litespeedtech / litespeedtech/openlitespeed
HTTP/2 request body not forwarded to reverse proxy backend - Git push hangs while HTTP/1.1 works
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.5k
- Forks
- 233
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 5
Description
## Environment
- OpenLiteSpeed: 1.9.0
- OS: Debian 12
- Backend: Gitea
- Gitea backend address: `http://127.0.0.1:3000`
- OpenLiteSpeed configured as reverse proxy in front of Gitea
- Client: Git for Windows / PhpStorm
- HTTPS connection to OpenLiteSpeed
- HTTP/2 enabled
## Problem
A Git push to a Gitea instance behind an OpenLiteSpeed reverse proxy hangs when the Git client uses HTTP/2.
The same push to the same repository, using the same client, credentials, commit and server works immediately when forcing Git to use HTTP/1.1.
This appears to be related to the HTTP/2 request body not being forwarded correctly by OpenLiteSpeed to the reverse proxy backend.
## Reproduction
Normal Git push over HTTP/2:
```bash
git push
```
The push starts, but then hangs.
On the client it eventually fails with:
```text
RPC failed; HTTP 500
curl 22 The requested URL returned error: 500
send-pack: unexpected disconnect while reading sideband packet
the remote end hung up unexpectedly
```
The corresponding OpenLiteSpeed log shows:
```text
Connection idle time too long: 301 while in state: 6 watching for event: 394245, close!
Content len: -2, request line: 'POST /vroni/EMS.git/git-receive-pack HTTP/1.1'
HttpExtConnector state: 10, request body sent: 0, response body size: -2, response body sent:0, left in buffer: 0, attempts: 0.
Proxy connection state: 2, watching event: 25, Request header:456, body:-2, sent:0, Response header: 0, total: 0 bytes received in 0 seconds,Total processing time: 304.
```
The important part seems to be:
```text
request body sent: 0
body:-2
sent:0
```
The connection is identified as HTTP/2 by OpenLiteSpeed:
```text
[93.xxx.xxx.xxx:60291:H2-7#git.example.com]
```
Gitea receives the initial Git requests successfully:
```text
GET /vroni/EMS.git/info/refs?service=git-receive-pack
401 Unauthorized
GET /vroni/EMS.git/info/refs?service=git-receive-pack
200 OK
POST /vroni/EMS.git/git-receive-pack
```
The initial 401 is the normal Git HTTP authentication challenge. Authentication succeeds on the following request.
However, the POST request does not complete when the client connection uses HTTP/2.
## HTTP/1.1 comparison
I then repeated exactly the same push while forcing Git to use HTTP/1.1:
```bash
git -c http.version=HTTP/1.1 push --set-upstream origin main
```
This succeeds immediately:
```text
Enumerating objects: 32, done.
Counting objects: 100% (32/32), done.
Delta compression using up to 16 threads
Compressing objects: 100% (30/30), done.
Writing objects: 100% (30/30), 7.28 MiB | 1.81 MiB/s, done.
Total 30 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: . Processing 1 references
remote: Processed 1 references in total
a434b96..a5d930f main -> main
branch 'main' set up to track 'origin/main'.
```
So the behavior is reproducible:
| Client protocol | Result |
|---|---|
| HTTP/2 | Push hangs, request body appears not to be forwarded, eventually HTTP 500 |
| HTTP/1.1 | Push succeeds immediately, 7.28 MiB transferred |
No changes were made to Gitea, the repository, authentication, permissions, commit or reverse proxy configuration between these two tests.
Only the Git HTTP protocol version was changed.
## OpenLiteSpeed reverse proxy configuration
The Gitea external application is configured as:
```text
Type: Web Server
Address: http://127.0.0.1:3000
Max Connections: 100
Initial Request Timeout: 3600
Retry Timeout: 0
Response Buffering: No
```
The global OpenLiteSpeed connection timeout is:
```text
Connection Timeout: 300 seconds
```
I do not believe increasing this timeout would solve the underlying issue. The 300 second timeout only terminates the connection after it has already stalled.
The relevant observation is that OpenLiteSpeed reports:
```text
request body sent: 0
```
for the HTTP/2 Git `git-receive-pack` POST.
## Workaround
Forcing Git to use HTTP/1.1 avoids the problem:
```bash
git -c http.version=HTTP/1.1 push
```
A permanent client-side workaround is also possible by configuring HTTP/1.1 for the Gitea URL.
## Expected behavior
Git Smart HTTP POST requests (`git-receive-pack`) received over HTTP/2 should be forwarded correctly to the reverse proxy backend, just as they are when the client uses HTTP/1.1.
## Additional information
I searched existing OpenLiteSpeed GitHub issues and forum reports for HTTP/2, reverse proxy, request body, Git/Gitea and `git-receive-pack` problems before opening this issue.
I found older reports involving HTTP/2 uploads/proxy behavior, but I could not find an existing issue matching this reproducible Git Smart HTTP case where:
- HTTP/2 fails
- OpenLiteSpeed reports `request body sent: 0`
- the same request succeeds immediately with HTTP/1.1
I previously reported #480 regarding PHP response headers over HTTP/3/QUIC. This appears to be a separate issue: this report concerns an HTTP/2 request body through the OpenLiteSpeed reverse proxy.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with `git push` over HTTP/2 and compare it with `git -c http.version=HTTP/1.1 push`. Start by tracing the HTTP/2 reverse-proxy request-body path and the log entries showing `request body sent: 0`; done means the `git-receive-pack` POST body reaches the Gitea backend over HTTP/2 and the push completes without the timeout or HTTP 500.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100