猿问

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

我正在编写一个小型 HTTP 服务器,它从一些嵌入式设备接收 HTTP POST。不幸的是,这些设备发送不包含 PATH 组件的格式错误的 POST 请求:


POST  HTTP/1.1

Host: 192.168.13.130:8080

Content-Length: 572

Connection: 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 main


import (

  "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)

}


哈士奇WWW
浏览 275回答 2
2回答

Helenr

您看到的错误发生在请求解析逻辑中,该逻辑发生在ServeHTTP调用之前。HTTP 请求是由包中的ReadRequest函数从套接字读取的net/http。它将使用空 URL 部分标记请求的第一行,然后继续解析 URL:if&nbsp;req.URL,&nbsp;err&nbsp;=&nbsp;url.ParseRequestURI(rawurl);&nbsp;err&nbsp;!=&nbsp;nil&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;nil,&nbsp;err &nbsp;&nbsp;&nbsp;&nbsp;}不幸的是,此函数将返回一个空 URL 字符串的错误,这将反过来中止请求读取过程。因此,在不修改标准库代码的情况下,似乎没有一种简单的方法可以实现您的目标。

慕丝7291255

我不确定 Go 的 HTTP 解析器是否允许没有 URI 路径元素的请求。如果没有,那么你就不走运了。但是,如果确实如此;你可以像这样覆盖请求的路径:type FixPath struct {}func (f *FixPath) ServeHTTP(w http.ResponseWriter, r *http.Request) {&nbsp; &nbsp; r.RequestURI = "/dummy/path" // fix URI path&nbsp; &nbsp; http.DefaultServeMux.ServeHTTP(w, r) // forward the fixed request to http.DefaultServeMux}func main() {&nbsp; &nbsp; // register handlers with http.DefaultServeMux through http.Handle or http.HandleFunc, and then...&nbsp; &nbsp; http.ListenAndServe(":8080", &FixPath{})}
随时随地看视频慕课网APP

相关分类

Go
我要回答