simonw: Feel free to squash-merge this so it doesn't go in as three separate commits.
diff --git a/starlette/response.py b/starlette/response.py
index db5bac8..f189ef3 100644
--- a/starlette/response.py
+++ b/starlette/response.py
@@ -177,5 +177,9 @@ class FileResponse(Response):
                 chunk = await file.read(self.chunk_size)
                 more_body = len(chunk) == self.chunk_size
                 await send(
-                    {"type": "http.response.body", "body": chunk, "more_body": False}
+                    {
+                        "type": "http.response.body",
+                        "body": chunk,
+                        "more_body": more_body,
+                    }
                 )

Error serving static files larger than 4096 bytes
Static files larger than 4096 bytes do not appear to be served correctly.

Here's a test I just wrote that illustrates the problem: https://github.com/simonw/starlette/commit/e2d6665fa5c32e77a3fe22836b14620a7f5999bb

Running that test gives me the following output:

```
(venv) starlette $ PYTHONPATH=. pytest -k test_large_staticfile 
===================================================== test session starts ======================================================
platform darwin -- Python 3.6.5, pytest-3.6.1, py-1.5.3, pluggy-0.6.0
rootdir: /Users/simonw/Dropbox/Development/starlette, inifile:
collected 43 items / 42 deselected                                                                                             

tests/test_staticfiles.py F                                                                                              [100%]

=========================================================== FAILURES ===========================================================
____________________________________________________ test_large_staticfile _____________________________________________________

tmpdir = local('/private/var/folders/jj/fngnv0810tn2lt_kd3911pdc0000gp/T/pytest-of-simonw/pytest-8/test_large_staticfile0')

    def test_large_staticfile(tmpdir):
        path = os.path.join(tmpdir, "example.txt")
        content = "this is a lot of content" * 200
        print("content len = ", len(content))
        with open(path, "w") as file:
            file.write(content)
    
        app = StaticFile(path=path)
        client = TestClient(app)
        response = client.get("/")
        assert response.status_code == 200
>       assert len(content) == len(response.text)
E       AssertionError: assert 4800 == 4096
E        +  where 4800 = len('this is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot of cont...is is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot of content')
E        +  and   4096 = len(' contentthis is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot...ontentthis is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot of')
E        +    where ' contentthis is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot...ontentthis is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot of contentthis is a lot of' = <Response [200]>.text

tests/test_staticfiles.py:30: AssertionError
```
diff --git a/tests/test_response.py b/tests/test_response.py
index 670aa6c..bbfde25 100644
--- a/tests/test_response.py
+++ b/tests/test_response.py
@@ -70,8 +70,9 @@ def test_response_headers():
 
 def test_file_response(tmpdir):
     path = os.path.join(tmpdir, "xyz")
+    content = b"<file content>" * 1000
     with open(path, "wb") as file:
-        file.write(b"<file content>")
+        file.write(content)
 
     def app(scope):
         return FileResponse(path=path, filename="example.png")
@@ -80,7 +81,7 @@ def test_file_response(tmpdir):
     response = client.get("/")
     expected_disposition = 'attachment; filename="example.png"'
     assert response.status_code == 200
-    assert response.content == b"<file content>"
+    assert response.content == content
     assert response.headers["content-type"] == "image/png"
     assert response.headers["content-disposition"] == expected_disposition
     assert "content-length" in response.headers
diff --git a/tests/test_staticfiles.py b/tests/test_staticfiles.py
index ac5a6ae..d615ba6 100644
--- a/tests/test_staticfiles.py
+++ b/tests/test_staticfiles.py
@@ -16,6 +16,21 @@ def test_staticfile(tmpdir):
     assert response.text == "<file content>"
 
 
+def test_large_staticfile(tmpdir):
+    path = os.path.join(tmpdir, "example.txt")
+    content = "this is a lot of content" * 200
+    print("content len = ", len(content))
+    with open(path, "w") as file:
+        file.write(content)
+
+    app = StaticFile(path=path)
+    client = TestClient(app)
+    response = client.get("/")
+    assert response.status_code == 200
+    assert len(content) == len(response.text)
+    assert content == response.text
+
+
 def test_staticfile_post(tmpdir):
     path = os.path.join(tmpdir, "example.txt")
     with open(path, "w") as file:

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-cov black twine
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
aiofiles==24.1.0
backports.tarfile==1.2.0
black==25.1.0
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
click==8.1.8
codecov==2.1.13
coverage==7.8.0
cryptography==44.0.2
docutils==0.21.2
exceptiongroup==1.2.2
id==1.5.0
idna==3.10
importlib_metadata==8.6.1
iniconfig==2.1.0
jaraco.classes==3.4.0
jaraco.context==6.0.1
jaraco.functools==4.1.0
jeepney==0.9.0
keyring==25.6.0
markdown-it-py==3.0.0
mdurl==0.1.2
more-itertools==10.6.0
mypy-extensions==1.0.0
nh3==0.2.21
packaging==24.2
pathspec==0.12.1
platformdirs==4.3.7
pluggy==1.5.0
pycparser==2.22
Pygments==2.19.1
pytest==8.3.5
pytest-cov==6.0.0
readme_renderer==44.0
requests==2.32.3
requests-toolbelt==1.0.0
rfc3986==2.0.0
rich==14.0.0
SecretStorage==3.3.3
-e git+https://github.com/encode/starlette.git@590db3d6ea6c7f3b03013209822cda2c54dc38ae#egg=starlette
tomli==2.2.1
twine==6.1.0
typing_extensions==4.13.0
urllib3==2.3.0
zipp==3.21.0

name: starlette
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - aiofiles==24.1.0
      - backports-tarfile==1.2.0
      - black==25.1.0
      - certifi==2025.1.31
      - cffi==1.17.1
      - charset-normalizer==3.4.1
      - click==8.1.8
      - codecov==2.1.13
      - coverage==7.8.0
      - cryptography==44.0.2
      - docutils==0.21.2
      - exceptiongroup==1.2.2
      - id==1.5.0
      - idna==3.10
      - importlib-metadata==8.6.1
      - iniconfig==2.1.0
      - jaraco-classes==3.4.0
      - jaraco-context==6.0.1
      - jaraco-functools==4.1.0
      - jeepney==0.9.0
      - keyring==25.6.0
      - markdown-it-py==3.0.0
      - mdurl==0.1.2
      - more-itertools==10.6.0
      - mypy-extensions==1.0.0
      - nh3==0.2.21
      - packaging==24.2
      - pathspec==0.12.1
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pycparser==2.22
      - pygments==2.19.1
      - pytest==8.3.5
      - pytest-cov==6.0.0
      - readme-renderer==44.0
      - requests==2.32.3
      - requests-toolbelt==1.0.0
      - rfc3986==2.0.0
      - rich==14.0.0
      - secretstorage==3.3.3
      - tomli==2.2.1
      - twine==6.1.0
      - typing-extensions==4.13.0
      - urllib3==2.3.0
      - zipp==3.21.0
prefix: /opt/conda/envs/starlette

tests/test_response.py::test_file_response tests/test_staticfiles.py::test_large_staticfile
tests/test_response.py::test_text_response tests/test_response.py::test_bytes_response tests/test_response.py::test_streaming_response tests/test_response.py::test_response_headers tests/test_staticfiles.py::test_staticfile tests/test_staticfiles.py::test_staticfile_post tests/test_staticfiles.py::test_staticfile_with_directory_raises_error tests/test_staticfiles.py::test_staticfile_with_missing_file_raises_error tests/test_staticfiles.py::test_staticfiles tests/test_staticfiles.py::test_staticfiles_post tests/test_staticfiles.py::test_staticfiles_with_directory_returns_404 tests/test_staticfiles.py::test_staticfiles_with_missing_file_returns_404 tests/test_staticfiles.py::test_staticfiles_configured_with_missing_directory tests/test_staticfiles.py::test_staticfiles_configured_with_file_instead_of_directory tests/test_staticfiles.py::test_staticfiles_config_check_occurs_only_once tests/test_staticfiles.py::test_staticfiles_prevents_breaking_out_of_directory
starlette/response.py
starlette/response.py