Is there a way to drop an http connection in golang without sending anything to client?

huangapple go评论80阅读模式
英文:

Is there a way to drop an http connection in golang without sending anything to client?

问题

在某些情况下,我不想对客户端做出任何响应,就好像在某个端口上没有任何响应,就好像该端口未被使用。

示意图:

func handleClient(w http.ResponseWriter, r *http.Request) {

	if (****条件****) {
		// 不发送任何内容,断开连接
	} else {
		// 正常响应
	}
	
}

我将非常感谢任何帮助或线索来解决这个问题。

英文:

In certain circumstances I do not want to respond anything to client, as if there were nothing responding in a certain port, as if the port were not in use.

Schematically:

func handleClient(w http.ResponseWriter, r *http.Request) {

	if ( **** condition **** ) {
		// Drop connection without sending anything to client
	} else {
		// Normal response
	}
	
}

I will appreciate any help or clue to afford it.

答案1

得分: 2

你可以劫持连接以访问底层的TCP连接。这在Golang的标准HTTP服务器中是支持的。

以下是文档中的示例。在这个示例中,你可以直接调用conn.Close()并返回,而不是像示例中那样使用defer conn.Close(),这将关闭连接。

请记住,在这一点上,连接已经被接受。如果你想要连连接都不接受,你需要实现一个自定义的TCP监听器,有条件地将流量路由到你的HTTP服务器。你还需要考虑你的条件是什么。例如,你是否需要从HTTP请求中读取任何内容来确定条件的结果?

http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) {
    hj, ok := w.(http.Hijacker)
    if !ok {
        http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
        return
    }
    conn, bufrw, err := hj.Hijack()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    // Don't forget to close the connection:
    defer conn.Close()
    bufrw.WriteString("Now we're speaking raw TCP. Say hi: ")
    bufrw.Flush()
    s, err := bufrw.ReadString('\n')
    if err != nil {
        log.Printf("error reading string: %v", err)
        return
    }
    fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s)
    bufrw.Flush()
})

完整文档:
https://pkg.go.dev/net/http#Hijacker

英文:

You can hijack the connection to access the underlying tcp connection.
It's supported by the standard http server in golang.

Below is the example from the documentation.
Instead of doing defer conn.Close() like in this example, you could call conn.Close() directly and return, this will drop the connection.

Keep in mind that at this point the connection has already been accepted. If you want to not even accept the connection, you'll need to implement a custom tcp listener that routes the traffic to your http server conditionally.
You'll have to also consider what your condition will be.
Or example, do you need to read anything from the http request in order to determine the outcome of your condition ?

http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) {
		hj, ok := w.(http.Hijacker)
		if !ok {
			http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
			return
		}
		conn, bufrw, err := hj.Hijack()
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		// Don't forget to close the connection:
		defer conn.Close()
		bufrw.WriteString("Now we're speaking raw TCP. Say hi: ")
		bufrw.Flush()
		s, err := bufrw.ReadString('\n')
		if err != nil {
			log.Printf("error reading string: %v", err)
			return
		}
		fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s)
		bufrw.Flush()
	})

Full docs:
https://pkg.go.dev/net/http#Hijacker

huangapple
  • 本文由 发表于 2022年5月25日 04:05:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/72368886.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定