changeset 9:5000914da3ff default tip

simplify handling of stream copying
author Paul Fisher <paul@pfish.zone>
date Mon, 16 Feb 2026 00:12:57 -0500
parents fe3c9fae4d4d
children
files src/hggit_serve.py
diffstat 1 files changed, 7 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/hggit_serve.py	Sun Feb 15 22:26:15 2026 -0500
+++ b/src/hggit_serve.py	Mon Feb 16 00:12:57 2026 -0500
@@ -145,13 +145,6 @@
         perm,
     )
     cgi_env = _build_git_environ(req_ctx, request)
-    content_length_hdr = request.headers.get(b'content-length', b'0')
-    try:
-        content_length = int(content_length_hdr)
-    except ValueError as ve:
-        raise hgerr.InputError(
-            f'Invalid content-length {content_length_hdr!r}'.encode()
-        ) from ve
     http_backend = repo.ui.configlist(
         b'hggit-serve', b'http-backend', default=(b'git', b'http-backend')
     )
@@ -168,10 +161,11 @@
     assert call.stdin
     # Git will not start writing output until stdin is fully closed.
     with call.stdin:
-        if content_length:
-            shutil.copyfileobj(
-                request.bodyfh, call.stdin, length=content_length
-            )
+        # This is how we know if there's anything to read from bodyfh.
+        # If we try to read from bodyfh on a request with no content,
+        # it hangs forever.
+        if b'CONTENT_LENGTH' in request.rawenv:
+            shutil.copyfileobj(request.bodyfh, call.stdin)
 
     status, headers, rest = _parse_cgi_response(call.stdout)
     response.status = status
@@ -180,7 +174,8 @@
 
     def write_the_rest() -> t.Iterator[bytes]:
         with call, rest:
-            while more := rest.read(1024 * 1024):
+            # if it's good enough for shutil it's good enough for me
+            while more := rest.read(shutil.COPY_BUFSIZE):
                 yield more
         if perm == _PUSH:
             _importing_enter(repo)