http - 通过原始TCP套接字接受和路由HTTP请求

标签 http go tcp server

我正在构建一个Web服务器,该服务器必须接受来自客户端的HTTP请求,但还必须接受来自对等方的原始TCP套接字上的请求。由于HTTP运行在TCP之上,因此我试图通过TCP服务器路由HTTP请求,而不是运行两个单独的服务。

有没有一种简单的方法可以使用net.Conn.Read()读取数据,确定它是HTTP GET/POST请求,然后将其传递给内置的HTTP处理程序或Gorilla mux?现在,我的代码看起来像这样,我自己在构建http路由逻辑:

func ListenConn() {
    listen, _ := net.Listen("tcp", ":8080")
    defer listen.Close()
    for {
        conn, err := listen.Accept()
        if err != nil {
            logger.Println("listener.go", "ListenConn", err.Error())
        }
        go HandleConn(conn)
    }
}

func HandleConn(conn net.Conn) {
    defer conn.Close()

    // determines if it is an http request

    scanner := bufio.NewScanner(conn)
    for scanner.Scan() {
        ln := scanner.Bytes()
        fmt.Println(ln)
        if strings.Fields(string(ln))[0] == "GET" {
            http.GetRegistrationCode(conn, strings.Fields(string(ln))[1])
            return
        }

        ... raw tcp handler code

    }
}

最佳答案

混合使用HTTP和原始TCP通信不是一个好主意。

考虑一下应用程序和客户端之间的所有防火墙和路由器。它们都旨在实现安全的HTTP传递。他们将如何处理您的TCP流量与有效HTTP进入同一端口的情况?

作为解决方案,您可以将流量拆分到同一应用程序中的两个不同端口。

通过端口分离,您可以独立地路由HTTP和TCP流量,并为每个 channel 配置适当的网络安全性。

监听2个不同端口的示例代码:

package main

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

type httpHandler struct {
}

func (m *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Println("HTTP request")
}

func main() {
    // http
    go func() {
        http.ListenAndServe(":8001", &httpHandler{})
    }()

    // tcp
    l, err := net.Listen("tcp", "localhost:8002")
    if err != nil {
        fmt.Println("Error listening:", err.Error())
        os.Exit(1)
    }
    defer l.Close()
    for {
        conn, err := l.Accept()
        if err != nil {
            fmt.Println("Error accepting: ", err.Error())
            os.Exit(1)
        }
        go handleRequest(conn)
    }
}

// Handles incoming requests.
func handleRequest(conn net.Conn) {
    // read/write from connection

    fmt.Println("TCP connection")
    conn.Close()
}

在浏览器中打开http://localhost:8001/并运行命令行echo -n "test" | nc localhost 8002以测试监听器

关于http - 通过原始TCP套接字接受和路由HTTP请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59582430/

相关文章:

Java HttpURLConnection : Content Length computation

perl - Regexp::Common::URI::http - 它能找到带有破折号的 URL,例如我的网站.domain.com

go - 从 Revel 中的 ViewArg 选择模板

tcp - 如何从 boost::asio::ip::tcp::socket::local_endpoint().address() 中提取地址字符串

c# - PHP 到 C# - 套接字 - 文件随机损坏

http - 在浏览器上保存数据

http - 在 root 和 rest on/api 上提供静态内容

go - 向数据库发送数据时出错

go - 带有强制内容 md5 的 AWS S3 预签名 URL

tcp - 如何将 TCP 流量从外部路由到 Kubernetes 集群内的服务?