Skip to content

Handle cases where content length of an http response is zero #7013

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

Closed
wants to merge 2 commits into from

Conversation

lrm29
Copy link
Contributor

@lrm29 lrm29 commented Jan 13, 2025

There's a behaviour change between 1.8.0 and 1.9.0. I have a Git server that's used for testing, and for private repositories it initially returns a 401 with an empty body:

TRACE: Sending GET request to http://hostname:1234/user/repo/info/refs?service=git-upload-pack
TRACE: Connecting to remote hostname port 1234
TRACE: Sending request:
GET /user/repo/info/refs?service=git-upload-pack HTTP/1.1
User-Agent: git/2.0 (libgit2 1.9.0)
Host: localhost:1000
Accept: /

TRACE: Received:
HTTP/1.1 401 Unauthorized
Content-Type: text/plain
Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
Set-Cookie: i_like_gogs=xxxx; Path=/; HttpOnly
Set-Cookie: _csrf=xxxx; Path=/; Expires=Tue, 14 Jan 2025
Www-Authenticate: Basic realm="."
Date: Mon, 13 Jan 2025
Content-Length: 0

At this point we're then waiting indefinitely to read from a stream:

#0  0x00007fd6aa729899 in __libc_recv (fd=3, buf=0x56452326e390, len=16384, flags=0) at ../sysdeps/unix/sysv/linux/recv.c:28
#1  0x0000564521408c76 in socket_read (stream=0x56452324d170, data=0x56452326e390, len=16384) at src/libgit2/streams/socket.c:280
#2  0x000056452141a871 in git_stream_read (st=0x56452324d170, data=0x56452326e390, len=16384) at src/libgit2/stream.h:50
#3  0x000056452141cf34 in client_read (client=0x56452325cfb0) at src/libgit2/transports/httpclient.c:1150
#4  0x000056452141cfc8 in client_read_and_parse (client=0x56452325cfb0) at src/libgit2/transports/httpclient.c:1175
#5  0x000056452141dd37 in git_http_client_skip_body (client=0x56452325cfb0) at src/libgit2/transports/httpclient.c:1545
#6  0x00005645214193d3 in handle_response (complete=0x7ffda378351f, stream=0x564523258260, response=0x7ffda3783520, allow_replay=true) at src/libgit2/transports/http.c:269
#7  0x00005645214199dd in http_stream_read (s=0x564523258260, buffer=0x56452325e380 "", buffer_size=65536, out_len=0x7ffda3783680) at src/libgit2/transports/http.c:429
#8  0x000056452141fb59 in git_smart__recv (t=0x56452325e150) at src/libgit2/transports/smart.c:29
#9  0x00005645214233cf in git_smart__store_refs (t=0x56452325e150, flushes=2) at src/libgit2/transports/smart_protocol.c:58
#10 0x0000564521420115 in git_smart__connect (transport=0x56452325e150, url=0x56452324d470 "http://localhost/user/repo", direction=0, connect_opts=0x7ffda37837d0) at src/libgit2/transports/smart.c:171
#11 0x00005645213eae2d in git_remote_connect_ext (remote=0x564523186dd0, direction=GIT_DIRECTION_FETCH, given_opts=0x7ffda37838e0) at src/libgit2/remote.c:963
#12 0x00005645213573aa in clone_into (repo=0x5645231f0250, _remote=0x564523188750, opts=0x7ffda3783a20) at src/libgit2/clone.c:444

I will investigate further, the attached change works around this issue for me but I'd like to understand what changed (I know the http parser changed?).

@lrm29 lrm29 marked this pull request as draft January 13, 2025 18:27
@lrm29
Copy link
Contributor Author

lrm29 commented Jan 14, 2025

Ok, so the difference in behaviour is because the on_message_complete callback is not run.

We've paused the parser in on_headers_complete, then we call git_http_parser_resume but don't finish parser execution (even though in this case, we just need to read 0 bytes!). I had to remove the call to llhttp_finish as that returned HPE_INVALID_EOF_STATE.

If it helps I could share a docker container with the Git server that displays this behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant