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

net/http: EOF error of http.Client.Do() #5312

Closed
gopherbot opened this issue Apr 18, 2013 · 13 comments
Closed

net/http: EOF error of http.Client.Do() #5312

gopherbot opened this issue Apr 18, 2013 · 13 comments
Milestone

Comments

@gopherbot
Copy link

by yunge.fu:

When I do two http requests:

resp, err := http.Get("http://localhost/signup";)
if err != nil {
    fmt.Println("get err:", err)
}
bs, _ := ioutil.ReadAll(resp.Body)
fmt.Println("bs:", string(bs[:20]))
resp.Body.Close()

//time.Sleep(1 * time.Millisecond)

resp2, err := http.PostForm("http://localhost/signup";,
url.Values{"FirstName": {"test first name"}})
if err != nil {
    fmt.Println("PostForm err:", err)
}
resp2.Body.Close()
io.Copy(os.Stdout, resp2.Body)

The second would always get EOF error, output error:
`PostForm err: Post http://localhost/signup: EOF`

But if I make the program sleep sometime between these requests, it would be ok:
time.Sleep(1 * time.Millisecond)

Which compiler are you using (5g, 6g, 8g, gccgo)?
6g

Which operating system are you using?
windows7, centos6.2

Which version are you using?  (run 'go version')
1.1beta2
Please note that 1.0.3 is ok!
@bradfitz
Copy link
Contributor

Comment 1:

Not enough information.
Please include a complete program, ideally client and server.
Also, check your error values.

Status changed to WaitingForReply.

@gopherbot
Copy link
Author

Comment 2 by yunge.fu:

Hi,
Test files uploaded, please try it, thanks.

Attachments:

  1. test.go (826 bytes)
  2. testser.go (1690 bytes)

@gopherbot
Copy link
Author

Comment 3 by yunge.fu:

When I use phantomjs(http://phantomjs.org/), also found same EOF issue.
1.Run phantomjs
phantomjs --webdriver=4444
2.Run go test
go run test.go
Get err: Post http://127.0.0.1:4444/wd/hub/session/d179ee50-ad89-11e2-9fa8-db836bf7
73d4/url: EOF
OS: Windows7 64bit , Centos6.2 32bit
And go1.0.3 is ok.

Attachments:

  1. test.go (624 bytes)

@bradfitz
Copy link
Contributor

Comment 4:

yunge.fu,
Could you download Wireshark (http://www.wireshark.org/download.html) and record the
traffic for "lo" (localhost) "port 4444" and do that again while recording?
Then save the pcap file and attach it here?

@gopherbot
Copy link
Author

Comment 5 by yunge.fu:

Hi,
I put all related files into a zip file, include pcapng files, please check it, thanks.

Attachments:

  1. go-issue-5312.zip (5524 bytes)

@bradfitz
Copy link
Contributor

Comment 6:

When filing bugs, never ignore error values.
What is the error value from ioutil.ReadAll?
Please update the test program and let me know if you get any results.  (or just nil
errors).
I will then try to reproduce.

@gopherbot
Copy link
Author

Comment 7 by yunge.fu:

pure go http ser test err:
req2 err: Get http://192.168.1.234:8000/index: EOF
phantomjs test:
Get err: Post http://192.168.1.234:4444/session/06eb0160-ae1f-11e2-b72e-75537d8a41e
c/url: EOF
And already updated these files.

Attachments:

  1. go-issue-5312.zip (5668 bytes)

@gopherbot
Copy link
Author

Comment 8 by hongruiqi:

Seems content-length is incorrect.

@minux
Copy link
Member

minux commented May 1, 2013

Comment 9:

after bisecting, the failure seems to occur after this commit:
changeset:   16008:231af8ac63aa
user:        Dmitriy Vyukov <dvyukov@google.com>
date:        Fri Mar 01 13:49:16 2013 +0200
summary:     runtime: improved scheduler

@minux
Copy link
Member

minux commented May 1, 2013

Comment 10:

ok, i understand what's happening here.
at the time of second http.Get(), the readLoop goroutine of the first
persistConn is runable but doesn't have a chance to run because of
the new scheduler favor the currently running goroutine (the main goroutine),
so the goroutine can't mark the connection as broken.
Then the 2nd http.Get will reuse that already-broken-but-not-marked-
as-so connection, and get an error immediately (EOF or sending on
broken connection).
This explains why these "solutions" superficially fixes the issue:
1. set GOMAXPROCS to 2 or higher
2. add a sleep between the two Get()'s
3. put a runtime.Gosched() between the two Get()'s
I don't yet know how to fix this problem, but I think this issue will
affect valid Go 1 programs.
cc: +brad and dvyukov, what's your opinion?

Labels changed: added go1.1.

@bradfitz
Copy link
Contributor

bradfitz commented May 1, 2013

Comment 11:

I think the program is just buggy.
The server sets an explicit Content-Length header of "161" rather than just letting the
net/http package deal with that detail, and then only sends 111 bytes:
    00000000  48 54 54 50 2f 31 2e 31  20 32 30 30 20 4f 4b 0d HTTP/1.1  200 OK.
    00000010  0a 43 6f 6e 74 65 6e 74  2d 45 6e 63 6f 64 69 6e .Content -Encodin
    00000020  67 3a 20 67 7a 69 70 0d  0a 43 6f 6e 74 65 6e 74 g: gzip. .Content
    00000030  2d 4c 65 6e 67 74 68 3a  20 31 36 31 0d 0a 43 6f -Length:  161..Co
    00000040  6e 74 65 6e 74 2d 54 79  70 65 3a 20 74 65 78 74 ntent-Ty pe: text
    00000050  2f 70 6c 61 69 6e 3b 20  63 68 61 72 73 65 74 3d /plain;  charset=
    00000060  75 74 66 2d 38 0d 0a 44  61 74 65 3a 20 57 65 64 utf-8..D ate: Wed
    00000070  2c 20 30 31 20 4d 61 79  20 32 30 31 33 20 31 37 , 01 May  2013 17
    00000080  3a 35 38 3a 34 39 20 47  4d 54 0d 0a 0d 0a 1f 8b :58:49 G MT......
    00000090  08 00 00 09 6e 88 00 ff  52 cb 29 b1 56 74 f1 77 ....n... R.).Vt.w
    000000A0  0e 89 0c 70 55 c8 28 c9  cd 51 4b 2f b1 e6 02 89 ...pU.(. .QK/....
    000000B0  82 38 0a 99 29 b6 6a ca  c6 26 d6 99 79 29 a9 15 .8..).j. .&..y)..
    000000C0  60 16 42 3e 35 31 05 ce  d1 47 e1 25 e5 a7 54 22 `.B>51.. .G.%..T"
    000000D0  d4 19 82 98 9e 25 40 dd  96 d6 c5 0a 25 a9 c5 25 .....%@. ....%..%
    000000E0  0a 05 89 e9 a9 10 6d 86  08 23 50 74 e9 c3 dc 02 ......m. .#Pt....
    000000F0  08 00 00 ff ff cb c2 51  47 a1 00 00 00          .......Q G....
Considering that, I don't really care that there's a tiny race on the client side when
the client sees something bogus from the same server.
This is related to issue #4677 and issue #3514 which cover this in part.  But this
server's still invalid. If I remove the strconv Content-Length line, it works.
Closing this issue.

Status changed to Invalid.

Attachments:

  1. pcap (1214 bytes)

@gopherbot
Copy link
Author

Comment 12 by yunge.fu:

Tried go1.1rc1, phantomjs test occasionally failed, same err:
Get http://127.0.0.1:4444/wd/hub/session/8e7d46e0-b2d1-11e2-84cf-0df5275b1326/url: EOF
Worse then before! 
go1.0.3 works fine, so this issue put the old code into a dangerous situation. If the
program call a paypal service, and occasional failed, then some people may just think
that's paypal's problem.

@gopherbot
Copy link
Author

Comment 13 by hongruiqi:

When I comment out "fmt.Println("bs:", string(bs[:20]))", the same error occured with go
1.0.3.

@rsc rsc added this to the Go1.1 milestone Apr 14, 2015
@rsc rsc removed the go1.1 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants