为了账号安全,请及时绑定邮箱和手机立即绑定

Go http 无法处理没有 PATH 的 HTTP 请求

Go http 无法处理没有 PATH 的 HTTP 请求

Go
哈士奇WWW 2021-07-09 09:40:17
我正在编写一个小型 HTTP 服务器,它从一些嵌入式设备接收 HTTP POST。不幸的是,这些设备发送不包含 PATH 组件的格式错误的 POST 请求:POST  HTTP/1.1Host: 192.168.13.130:8080Content-Length: 572Connection: Keep-Alive<?xml version="1.0"?>....REST OF XML BODY因此,Go http 永远不会将请求传递给我的任何处理程序,并且总是以 400 Bad Request 进行响应。由于这些是嵌入式设备,并且改变它们发送请求的方式不是一种选择,但我也许可以拦截 HTTP 请求,如果不存在 PATH,则在它传递给 SeverMux 之前向其添加一个(例如 /)。我通过创建自己的 CameraMux 尝试了这一点,但即使在从我的自定义 ServeMux 调用 ServeHTTP() 方法之前,Go 也总是以 400 Bad Request 响应(参见下面的代码)。有没有办法在 Go http 响应 Bad Request 之前的某个时间修改 Request 对象,或者有办法让 Go 接受请求,即使它没有 PATH?package mainimport (  "net/http"                              "log"  "os")type CameraMux struct {                   mux *http.ServeMux                    } func (handler *CameraMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {  // Try to fix URL.Path here but the server never reaches this method.      log.Printf("URL %v\n", r.URL.Path)  handler.mux.ServeHTTP(w, r)}func process(path string) error {  log.Printf("Processing %v\n", path)  // Do processing based on path and body    return nil}func main() {  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {    path := r.URL.Path[1:]    log.Printf("Processing path %v\n", path)     err := process(path)    if err != nil {      w.WriteHeader(http.StatusBadRequest)     } else {      w.WriteHeader(http.StatusOK)    }  })  err := http.ListenAndServe(":8080", &CameraMux{http.DefaultServeMux})  if err != nil {    log.Println(err)    os.Exit(1)  }  os.Exit(0)}
查看完整描述

2 回答

?
Helenr

TA贡献1780条经验 获得超3个赞

您看到的错误发生在请求解析逻辑中,该逻辑发生在ServeHTTP调用之前。

HTTP 请求是由包中的ReadRequest函数从套接字读取的net/http。它将使用空 URL 部分标记请求的第一行,然后继续解析 URL

if req.URL, err = url.ParseRequestURI(rawurl); err != nil {
    return nil, err
    }

不幸的是,此函数将返回一个空 URL 字符串的错误,这将反过来中止请求读取过程。

因此,在不修改标准库代码的情况下,似乎没有一种简单的方法可以实现您的目标。


查看完整回答
反对 回复 2021-07-12
?
慕丝7291255

TA贡献1859条经验 获得超6个赞

我不确定 Go 的 HTTP 解析器是否允许没有 URI 路径元素的请求。如果没有,那么你就不走运了。但是,如果确实如此;你可以像这样覆盖请求的路径:


type FixPath struct {}


func (f *FixPath) ServeHTTP(w http.ResponseWriter, r *http.Request) {

    r.RequestURI = "/dummy/path" // fix URI path

    http.DefaultServeMux.ServeHTTP(w, r) // forward the fixed request to http.DefaultServeMux

}


func main() {


    // register handlers with http.DefaultServeMux through http.Handle or http.HandleFunc, and then...


    http.ListenAndServe(":8080", &FixPath{})

}


查看完整回答
反对 回复 2021-07-12
  • 2 回答
  • 0 关注
  • 274 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信