mirror of https://github.com/encode/starlette.git
207 lines
6.5 KiB
Python
207 lines
6.5 KiB
Python
import asyncio
|
|
import os
|
|
import time
|
|
|
|
import pytest
|
|
|
|
from starlette.staticfiles import StaticFiles
|
|
from starlette.testclient import TestClient
|
|
|
|
|
|
def test_staticfiles(tmpdir):
|
|
path = os.path.join(tmpdir, "example.txt")
|
|
with open(path, "w") as file:
|
|
file.write("<file content>")
|
|
|
|
app = StaticFiles(directory=tmpdir)
|
|
client = TestClient(app)
|
|
response = client.get("/example.txt")
|
|
assert response.status_code == 200
|
|
assert response.text == "<file content>"
|
|
|
|
|
|
def test_staticfiles_with_package():
|
|
app = StaticFiles(packages=["tests"])
|
|
client = TestClient(app)
|
|
response = client.get("/example.txt")
|
|
assert response.status_code == 200
|
|
assert response.text == "123\n"
|
|
|
|
|
|
def test_staticfiles_post(tmpdir):
|
|
path = os.path.join(tmpdir, "example.txt")
|
|
with open(path, "w") as file:
|
|
file.write("<file content>")
|
|
|
|
app = StaticFiles(directory=tmpdir)
|
|
client = TestClient(app)
|
|
response = client.post("/example.txt")
|
|
assert response.status_code == 405
|
|
assert response.text == "Method Not Allowed"
|
|
|
|
|
|
def test_staticfiles_with_directory_returns_404(tmpdir):
|
|
path = os.path.join(tmpdir, "example.txt")
|
|
with open(path, "w") as file:
|
|
file.write("<file content>")
|
|
|
|
app = StaticFiles(directory=tmpdir)
|
|
client = TestClient(app)
|
|
response = client.get("/")
|
|
assert response.status_code == 404
|
|
assert response.text == "Not Found"
|
|
|
|
|
|
def test_staticfiles_with_missing_file_returns_404(tmpdir):
|
|
path = os.path.join(tmpdir, "example.txt")
|
|
with open(path, "w") as file:
|
|
file.write("<file content>")
|
|
|
|
app = StaticFiles(directory=tmpdir)
|
|
client = TestClient(app)
|
|
response = client.get("/404.txt")
|
|
assert response.status_code == 404
|
|
assert response.text == "Not Found"
|
|
|
|
|
|
def test_staticfiles_instantiated_with_missing_directory(tmpdir):
|
|
with pytest.raises(RuntimeError) as exc:
|
|
path = os.path.join(tmpdir, "no_such_directory")
|
|
StaticFiles(directory=path)
|
|
assert "does not exist" in str(exc)
|
|
|
|
|
|
def test_staticfiles_configured_with_missing_directory(tmpdir):
|
|
path = os.path.join(tmpdir, "no_such_directory")
|
|
app = StaticFiles(directory=path, check_dir=False)
|
|
client = TestClient(app)
|
|
with pytest.raises(RuntimeError) as exc:
|
|
client.get("/example.txt")
|
|
assert "does not exist" in str(exc)
|
|
|
|
|
|
def test_staticfiles_configured_with_file_instead_of_directory(tmpdir):
|
|
path = os.path.join(tmpdir, "example.txt")
|
|
with open(path, "w") as file:
|
|
file.write("<file content>")
|
|
|
|
app = StaticFiles(directory=path, check_dir=False)
|
|
client = TestClient(app)
|
|
with pytest.raises(RuntimeError) as exc:
|
|
client.get("/example.txt")
|
|
assert "is not a directory" in str(exc)
|
|
|
|
|
|
def test_staticfiles_config_check_occurs_only_once(tmpdir):
|
|
app = StaticFiles(directory=tmpdir)
|
|
client = TestClient(app)
|
|
assert not app.config_checked
|
|
client.get("/")
|
|
assert app.config_checked
|
|
client.get("/")
|
|
assert app.config_checked
|
|
|
|
|
|
def test_staticfiles_prevents_breaking_out_of_directory(tmpdir):
|
|
directory = os.path.join(tmpdir, "foo")
|
|
os.mkdir(directory)
|
|
|
|
path = os.path.join(tmpdir, "example.txt")
|
|
with open(path, "w") as file:
|
|
file.write("outside root dir")
|
|
|
|
app = StaticFiles(directory=directory)
|
|
# We can't test this with 'requests', so we test the app directly here.
|
|
path = app.get_path({"path": "/../example.txt"})
|
|
scope = {"method": "GET"}
|
|
loop = asyncio.get_event_loop()
|
|
response = loop.run_until_complete(app.get_response(path, scope))
|
|
assert response.status_code == 404
|
|
assert response.body == b"Not Found"
|
|
|
|
|
|
def test_staticfiles_never_read_file_for_head_method(tmpdir):
|
|
path = os.path.join(tmpdir, "example.txt")
|
|
with open(path, "w") as file:
|
|
file.write("<file content>")
|
|
|
|
app = StaticFiles(directory=tmpdir)
|
|
client = TestClient(app)
|
|
response = client.head("/example.txt")
|
|
assert response.status_code == 200
|
|
assert response.content == b""
|
|
assert response.headers["content-length"] == "14"
|
|
|
|
|
|
def test_staticfiles_304_with_etag_match(tmpdir):
|
|
path = os.path.join(tmpdir, "example.txt")
|
|
with open(path, "w") as file:
|
|
file.write("<file content>")
|
|
|
|
app = StaticFiles(directory=tmpdir)
|
|
client = TestClient(app)
|
|
first_resp = client.get("/example.txt")
|
|
assert first_resp.status_code == 200
|
|
last_etag = first_resp.headers["etag"]
|
|
second_resp = client.get("/example.txt", headers={"if-none-match": last_etag})
|
|
assert second_resp.status_code == 304
|
|
assert second_resp.content == b""
|
|
|
|
|
|
def test_staticfiles_304_with_last_modified_compare_last_req(tmpdir):
|
|
path = os.path.join(tmpdir, "example.txt")
|
|
file_last_modified_time = time.mktime(
|
|
time.strptime("2013-10-10 23:40:00", "%Y-%m-%d %H:%M:%S")
|
|
)
|
|
with open(path, "w") as file:
|
|
file.write("<file content>")
|
|
os.utime(path, (file_last_modified_time, file_last_modified_time))
|
|
|
|
app = StaticFiles(directory=tmpdir)
|
|
client = TestClient(app)
|
|
# last modified less than last request, 304
|
|
response = client.get(
|
|
"/example.txt", headers={"If-Modified-Since": "Thu, 11 Oct 2013 15:30:19 GMT"}
|
|
)
|
|
assert response.status_code == 304
|
|
assert response.content == b""
|
|
# last modified greater than last request, 200 with content
|
|
response = client.get(
|
|
"/example.txt", headers={"If-Modified-Since": "Thu, 20 Feb 2012 15:30:19 GMT"}
|
|
)
|
|
assert response.status_code == 200
|
|
assert response.content == b"<file content>"
|
|
|
|
|
|
def test_staticfiles_html(tmpdir):
|
|
path = os.path.join(tmpdir, "404.html")
|
|
with open(path, "w") as file:
|
|
file.write("<h1>Custom not found page</h1>")
|
|
path = os.path.join(tmpdir, "dir")
|
|
os.mkdir(path)
|
|
path = os.path.join(path, "index.html")
|
|
with open(path, "w") as file:
|
|
file.write("<h1>Hello</h1>")
|
|
|
|
app = StaticFiles(directory=tmpdir, html=True)
|
|
client = TestClient(app)
|
|
|
|
response = client.get("/dir/")
|
|
assert response.url == "http://testserver/dir/"
|
|
assert response.status_code == 200
|
|
assert response.text == "<h1>Hello</h1>"
|
|
|
|
response = client.get("/dir")
|
|
assert response.url == "http://testserver/dir/"
|
|
assert response.status_code == 200
|
|
assert response.text == "<h1>Hello</h1>"
|
|
|
|
response = client.get("/dir/index.html")
|
|
assert response.url == "http://testserver/dir/index.html"
|
|
assert response.status_code == 200
|
|
assert response.text == "<h1>Hello</h1>"
|
|
|
|
response = client.get("/missing")
|
|
assert response.status_code == 404
|
|
assert response.text == "<h1>Custom not found page</h1>"
|