Search code examples
gofasthttp

Fasthttp error when reading request headers: invalid header key " http/1.1\r\nuser-Agent"


I am just started learning Go, and this question made me stuck. Trying to test request handling on localhost in testing func using github.com/valyala/fasthttp. First running the server like in https://github.com/valyala/fasthttp/blob/master/server_example_test.go:

ln, err := net.Listen("tcp", ":8080")
if err != nil {
    log.Fatalf("error in net.Listen: %s", err)
}
requestHandler := func(ctx *fasthttp.RequestCtx) {
    fmt.Println(ctx, "Requested path is")
}
if err := fasthttp.Serve(ln, requestHandler); err != nil {
    log.Fatalf("error in Serve: %s", err)
}

then if I run the request func (FastRequest(url string)) from the same testing function it works fine...

Fasthttp request func:

func FastRequest(url string) error {
    Request := &fasthttp.Request{}
    Response := &fasthttp.Response{}
    FastHTTPClient := &fasthttp.Client{}    

    Request.SetRequestURI(url)

    for {

        err := FastHTTPClient.DoTimeout(Request, Response, time.Minute)
        switch err {
        case fasthttp.ErrTimeout, fasthttp.ErrDialTimeout:
            <-time.After(time.Minute * 2)
            continue
        case fasthttp.ErrNoFreeConns:
            <-time.After(time.Minute * 2)
            continue
        case nil:
            return nil
        default:
            if strings.Contains(err.Error(), "connection reset by peer") {
                <-time.After(time.Minute * 2)
                continue
            } else {
                return err
            }
        }
    }
}

But what I truly need to test is sending a request from my object, which implements the same FastRequest method in goroutine. And here I've got this error message:

 error when serving connection ":8080"<->":51325": error when reading request headers: invalid header key " http/1.1\r\nuser-Agent". Buffer size=206, contents: "GET here_is_request_url \n http/1.1\r\nuser-Agent: fasthttp\r\nHost: localhost:8080\r\n\r\n"

In FastRequest I haven't specified any user agent and the functions FastRequest() are the same. Only the place where the function is called is different. Whether it's called in goroutine or not does not matter.

So, fasthttp.RequestCtx cannot parse its own header? or what is going on?

========================================================================== Also, I should have added that in first case I've used fasthttp v1.6.0, when I changed it to 1.8.0 the error was:

error when serving connection ":8080"<->":57093": error when reading request headers: invalid header name. Buffer size=215, contents: "GET here_is_request_url\n HTTP/1.1\r\nUser-Agent: fasthttp\r\nHost: localhost:8080\r\n\r\n"

And finally, the issue was in "/n" added at the end of the url, that works for real servers, by my small localhost server couldn't handle it.


Solution

  • ... contents: "GET here_is_request_url \n http/1.1\r\n ...
                                         ^^^^^^^^^^^^^
                                             WRONG! 
    

    The URL you use in your code likely has a newline character (\n) still at the end since this is included in your request before the HTTP version and thus messes up the HTTP request. A real URL should have no white space which includes spaces and also newline characters.

    Additionally the HTTP version should be all-uppercase HTTP/1.1, i.e. your lower-case http/1.1 is wrong too. You don't show how you create the HTTP request but it is very likely messed up.