dongwuge6201 2013-10-25 17:18
浏览 1465

进行请求时的http.Request RequestURI字段

I dumped request from server to []byte and used ReadRequest to make a request with Client.Do method. I got an error:

http: Request.RequestURI can't be set in client requests.

Can you explain me why exactly I got this error?

  • 写回答

1条回答 默认 最新

  • du4010 2013-10-26 13:20
    关注

    The error is clear: You are not allowed to have RequestURI set when doing a client request.

    In the documentation for http.Request.RequestURI, it says (my emphasis):

    RequestURI is the unmodified Request-URI of the
    Request-Line (RFC 2616, Section 5.1) as sent by the client
    to a server. Usually the URL field should be used instead.
    It is an error to set this field in an HTTP client request.

    The reason why it is set is because that is what ReadRequest does when parsing the request stream.

    So, you need to set the URL and clear the RequestURI if you want to send it. After making an attempt, I noticed that the URL object in the request returned from ReadRequest will not have all the information set, such as scheme and host. Due to this, you will need to set it yourself, or just parse a new URL using Parse in the net/url package:

    Here is some working code for you:

    package main
    
    import (
        "fmt"
        "strings"
        "bufio"
        "net/http"
        "net/url"
    )
    
    var rawRequest = `GET /pkg/net/http/ HTTP/1.1
    Host: golang.org
    Connection: close
    User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; de-de) AppleWebKit/523.10.3 (KHTML, like Gecko) Version/3.0.4 Safari/523.10
    Accept-Encoding: gzip
    Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7
    Cache-Control: no-cache
    Accept-Language: de,en;q=0.7,en-us;q=0.3
    
    `
    
    func main() {
        b := bufio.NewReader(strings.NewReader(rawRequest))
    
        req, err := http.ReadRequest(b)
        if err != nil {
            panic(err)
        }
    
        // We can't have this set. And it only contains "/pkg/net/http/" anyway
        req.RequestURI = ""
    
        // Since the req.URL will not have all the information set,
        // such as protocol scheme and host, we create a new URL
        u, err := url.Parse("http://golang.org/pkg/net/http/")
        if err != nil {
            panic(err)
        }   
        req.URL = u
    
        client := &http.Client{}
        resp, err := client.Do(req)
        if err != nil {
            panic(err)
        }
    
        fmt.Printf("%#v
    ", resp)
    }
    

    Playground

    Ps. play.golang.org will panic, since we don't have the permission to do http requests.

    评论

报告相同问题?

悬赏问题

  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端