0

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.

Lara Zaiets
  • 5
  • 1
  • 4
  • 1
    Did you try this with the standard library http implementation? "user-Agent" is not valid header key, it should be "User-Agent" according to the http spec. – Burak Serdar Jan 13 '20 at 20:18
  • 3
    If you are just learning Go, please do not use fasthttp. It is not intended for casual usage. It is intended only for installations that need massively huge performance. – Jonathan Hall Jan 13 '20 at 20:24
  • @BurakSerdar I haven't specified it manualy in the request. Before the request itself it is empty. It seems like it's added inside FastHTTPClient.DoTimeout(Request, Response, time.Minute). – Lara Zaiets Jan 13 '20 at 20:28
  • 2
    Yes, that's what it looks like, and if it is so, it would be a bug in fasthttp. And that wouldn't be the first bug in that package. That's why especially if you're new to go, I suggest you use the standard library http package. It is performant and stable. – Burak Serdar Jan 13 '20 at 20:31
  • 2
    fasthttp is _known_ to break several HTTP standards, and somewhat intentionally. It says so right on the front page of the project. It really should almost never ever be used. I'm friends with the maintainer of the project, and he says the same. – Jonathan Hall Jan 13 '20 at 20:56
  • 1
    @BurakSerdar: Field names in HTTP are not case sensitive. `user-Agent` is perfectly valid as is `user-agent` or `User-Agent` - and they all mean exactly the same. – Steffen Ullrich Jan 13 '20 at 21:28
  • You are correct my mistake. They are case insensitive. – Burak Serdar Jan 13 '20 at 21:41

1 Answers1

1
... 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.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • hell!! yes, the thing was in this new line character that I've added higher, so if I printed urls all the way to log it was identical, because I've printed with Println)) and only context showed this character. thank you!! – Lara Zaiets Jan 14 '20 at 10:38