Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsolicited response received on idle HTTP channel starting with "\r\n"; err=<nil> #2782

Closed
kxepal opened this issue Mar 1, 2018 · 9 comments · Fixed by #3041
Closed

Unsolicited response received on idle HTTP channel starting with "\r\n"; err=<nil> #2782

kxepal opened this issue Mar 1, 2018 · 9 comments · Fixed by #3041

Comments

@kxepal
Copy link
Member

kxepal commented Mar 1, 2018

Long story short

By default, aiohttp closes keep-alive connections after 75 seconds of inactivity. Just before closing it, server sends \r\n data to client in order to notify it about closing. However, not all the clients are happy with that. One of those is standard golang net/http which logs errors in this case not about closed connection, but about bad data received in place when there should be any of such.

Referenced commit: bf49f8e

Question is that behaviour correct or common, or based on some RFC?
What recommendations could we give to clients which complains about to relax their communication with aiohttp servers?

Expected behaviour

2018/03/01 13:52:12 Hello, Anonymous

Actual behaviour

2018/03/01 13:52:12 Hello, Anonymous
2018/03/01 13:53:27 Unsolicited response received on idle HTTP channel starting with "\r\n"; err=<nil>

Steps to reproduce

  1. Run any aiohttp example. Let's take examples/web_srv.py
  2. Save the following as main.go, for example:
package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    Url, err := url.Parse("http://localhost:8080/hello")
    if err != nil {
        log.Panic(err)
        return
    }

    client := http.Client{
        Timeout: time.Duration(time.Millisecond * 10000),
    }

    resp, err := client.Get(Url.String())
    if err != nil {
        log.Panic(err)
        return
    }

    body, err := ioutil.ReadAll(resp.Body)
    resp.Body.Close()

    log.Print(string(body))
    time.Sleep(100 * time.Second)
}
  1. Run it as go run main.go
  2. Wait for awhile and see the error from subject.

Your environment

  1. Python 3.6 / aiohttp 3.0.5
  2. go 1.9.1
@kxepal
Copy link
Member Author

kxepal commented Mar 1, 2018

/cc @fafhrd91

@kxepal
Copy link
Member Author

kxepal commented Mar 1, 2018

Currently, I suggested to limit idleTimeout to golang client by 60 seconds, so it will close idle connection long before aiohttp does it itself with additional response data. But not sure if that's ok in general to tweak clients to let them work with aiohttp nicely.

@kxepal kxepal added the server label Mar 1, 2018
@hubo1016
Copy link
Contributor

hubo1016 commented Mar 1, 2018

Shouldn't the server just close the connection? Another choice is shutdown the send side first, read and discard any received data for a short while, then close the connection, so the client won't receive broken pipe errors (but usually It is not worth doing this)

@kxepal
Copy link
Member Author

kxepal commented Mar 1, 2018

Shouldn't the server just close the connection?

That's how it was and the reason of current behaviour is about to fix that state

I didn't found any references in actual RFCs about such behaviour as like as I didn't noticed any recommended behaviour to avoid such issues. However, I didn't dig too much so could miss something.

@fafhrd91
Copy link
Member

fafhrd91 commented Mar 1, 2018

#1883 describes the problem. Maybe this should be configurable. I don’t have opinion

@hubo1016
Copy link
Contributor

hubo1016 commented Mar 1, 2018

@fafhrd91 is it an asyncio bug? Looks weird.

@asvetlov asvetlov added this to the 3.1 milestone Mar 1, 2018
@fafhrd91
Copy link
Member

fafhrd91 commented Mar 1, 2018

It is reproducible

@asvetlov asvetlov modified the milestones: 3.1, 3.2 Mar 22, 2018
@asvetlov asvetlov modified the milestones: 3.2, 3.3 May 7, 2018
@Tinche
Copy link

Tinche commented May 29, 2018

Our backend is also Go calling out to asyncio/aiohttp, and I've been seeing this.

@lock
Copy link

lock bot commented Oct 28, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a [new issue] for related bugs.
If you feel like there's important points made in this discussion, please include those exceprts into that [new issue].
[new issue]: https://github.com/aio-libs/aiohttp/issues/new

@lock lock bot added the outdated label Oct 28, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants