diff --git a/docs/sanic/blueprints.md b/docs/sanic/blueprints.md index 5be33cb6..1a7c5293 100644 --- a/docs/sanic/blueprints.md +++ b/docs/sanic/blueprints.md @@ -93,7 +93,14 @@ def ignore_404s(request, exception): Static files can be served globally, under the blueprint prefix. ```python -bp.static('/folder/to/serve', '/web/path') + +# suppose bp.name == 'bp' + +bp.static('/web/path', '/folder/to/serve') +# also you can pass name parameter to it for url_for +bp.static('/web/path', '/folder/to/server', name='uploads') +app.url_for('static', name='bp.uploads', filename='file.txt') == '/bp/web/path/file.txt' + ``` ## Start and stop diff --git a/docs/sanic/getting_started.md b/docs/sanic/getting_started.md index 04d22248..3e89cc3e 100644 --- a/docs/sanic/getting_started.md +++ b/docs/sanic/getting_started.md @@ -9,15 +9,16 @@ syntax, so earlier versions of python won't work. ```python from sanic import Sanic - from sanic.response import text + from sanic.response import json - app = Sanic(__name__) + app = Sanic() @app.route("/") async def test(request): - return text('Hello world!') + return json({"hello": "world"}) - app.run(host="0.0.0.0", port=8000, debug=True) + if __name__ == "__main__": + app.run(host="0.0.0.0", port=8000) ``` 3. Run the server: `python3 main.py` diff --git a/docs/sanic/routing.md b/docs/sanic/routing.md index 49b7c0b8..98179e17 100644 --- a/docs/sanic/routing.md +++ b/docs/sanic/routing.md @@ -301,3 +301,34 @@ def handler(request): # app.url_for('handler') == '/get' # app.url_for('post_handler') == '/post' ``` + +## Build URL for static files + +You can use `url_for` for static file url building now. +If it's for file directly, `filename` can be ignored. + +```python + +app = Sanic('test_static') +app.static('/static', './static') +app.static('/uploads', './uploads', name='uploads') +app.static('/the_best.png', '/home/ubuntu/test.png', name='best_png') + +bp = Blueprint('bp', url_prefix='bp') +bp.static('/static', './static') +bp.static('/uploads', './uploads', name='uploads') +bp.static('/the_best.png', '/home/ubuntu/test.png', name='best_png') +app.blueprint(bp) + +# then build the url +app.url_for('static', filename='file.txt') == '/static/file.txt' +app.url_for('static', name='static', filename='file.txt') == '/static/file.txt' +app.url_for('static', name='uploads', filename='file.txt') == '/uploads/file.txt' +app.url_for('static', name='best_png') == '/the_best.png' + +# blueprint url building +app.url_for('static', name='bp.static', filename='file.txt') == '/bp/static/file.txt' +app.url_for('static', name='bp.uploads', filename='file.txt') == '/bp/uploads/file.txt' +app.url_for('static', name='bp.best_png') == '/bp/static/the_best.png' + +``` diff --git a/docs/sanic/static_files.md b/docs/sanic/static_files.md index f0ce9d78..3419cad1 100644 --- a/docs/sanic/static_files.md +++ b/docs/sanic/static_files.md @@ -6,16 +6,40 @@ filename. The file specified will then be accessible via the given endpoint. ```python from sanic import Sanic +from sanic.blueprints import Blueprint + app = Sanic(__name__) # Serves files from the static folder to the URL /static app.static('/static', './static') +# use url_for to build the url, name defaults to 'static' and can be ignored +app.url_for('static', filename='file.txt') == '/static/file.txt' +app.url_for('static', name='static', filename='file.txt') == '/static/file.txt' # Serves the file /home/ubuntu/test.png when the URL /the_best.png # is requested -app.static('/the_best.png', '/home/ubuntu/test.png') +app.static('/the_best.png', '/home/ubuntu/test.png', name='best_png') + +# you can use url_for to build the static file url +# you can ignore name and filename parameters if you don't define it +app.url_for('static', name='best_png') == '/the_best.png' +app.url_for('static', name='best_png', filename='any') == '/the_best.png' + +# you need define the name for other static files +app.static('/another.png', '/home/ubuntu/another.png', name='another') +app.url_for('static', name='another') == '/another.png' +app.url_for('static', name='another', filename='any') == '/another.png' + +# also, you can use static for blueprint +bp = Blueprint('bp', url_prefix='/bp') +bp.static('/static', './static') + +# servers the file directly +bp.static('/the_best.png', '/home/ubuntu/test.png', name='best_png') +app.blueprint(bp) + +app.url_for('static', name='bp.static', filename='file.txt') == '/bp/static/file.txt' +app.url_for('static', name='bp.best_png') == '/bp/test_best.png' app.run(host="0.0.0.0", port=8000) ``` - -Note: currently you cannot build a URL for a static file using `url_for`. diff --git a/examples/teapot.py b/examples/teapot.py new file mode 100644 index 00000000..897f7836 --- /dev/null +++ b/examples/teapot.py @@ -0,0 +1,13 @@ +from sanic import Sanic +from sanic import response as res + +app = Sanic(__name__) + + +@app.route("/") +async def test(req): + return res.text("I\'m a teapot", status=418) + + +if __name__ == '__main__': + app.run(host="0.0.0.0", port=8000) diff --git a/sanic/app.py b/sanic/app.py index f06e9cd4..311814fd 100644 --- a/sanic/app.py +++ b/sanic/app.py @@ -345,13 +345,13 @@ class Sanic: # Static Files def static(self, uri, file_or_directory, pattern=r'/?.+', use_modified_since=True, use_content_range=False, - stream_large_files=False): + stream_large_files=False, name='static'): """Register a root to serve files from. The input can either be a file or a directory. See """ static_register(self, uri, file_or_directory, pattern, use_modified_since, use_content_range, - stream_large_files) + stream_large_files, name) def blueprint(self, blueprint, **options): """Register a blueprint on the application. @@ -401,12 +401,32 @@ class Sanic: URLBuildError """ # find the route by the supplied view name - uri, route = self.router.find_route_by_view_name(view_name) + kw = {} + # special static files url_for + if view_name == 'static': + kw.update(name=kwargs.pop('name', 'static')) + elif view_name.endswith('.static'): # blueprint.static + kwargs.pop('name', None) + kw.update(name=view_name) - if not uri or not route: + uri, route = self.router.find_route_by_view_name(view_name, **kw) + if not (uri and route): raise URLBuildError('Endpoint with name `{}` was not found'.format( view_name)) + if view_name == 'static' or view_name.endswith('.static'): + filename = kwargs.pop('filename', None) + # it's static folder + if ' self.request_max_size: exception = PayloadTooLarge('Payload Too Large') self.write_error(exception) - + try: + value = value.decode() + except UnicodeDecodeError: + value = value.decode('latin_1') self.headers.append( - (self._header_fragment.decode().casefold(), - value.decode())) + (self._header_fragment.decode().casefold(), value)) self._header_fragment = b'' diff --git a/sanic/static.py b/sanic/static.py index 36cb47db..a9683b27 100644 --- a/sanic/static.py +++ b/sanic/static.py @@ -18,7 +18,7 @@ from sanic.response import file, file_stream, HTTPResponse def register(app, uri, file_or_directory, pattern, use_modified_since, use_content_range, - stream_large_files): + stream_large_files, name='static'): # TODO: Though sanic is not a file server, I feel like we should at least # make a good effort here. Modified-since is nice, but we could # also look into etags, expires, and caching @@ -39,6 +39,7 @@ def register(app, uri, file_or_directory, pattern, than the file() handler to send the file If this is an integer, this represents the threshold size to switch to file_stream() + :param name: user defined name used for url_for """ # If we're not trying to match a file directly, # serve from the folder @@ -117,4 +118,8 @@ def register(app, uri, file_or_directory, pattern, path=file_or_directory, relative_url=file_uri) - app.route(uri, methods=['GET', 'HEAD'])(_handler) + # special prefix for static files + if not name.startswith('_static_'): + name = '_static_{}'.format(name) + + app.route(uri, methods=['GET', 'HEAD'], name=name)(_handler) diff --git a/tests/static/bp/decode me.txt b/tests/static/bp/decode me.txt new file mode 100644 index 00000000..b1c36682 --- /dev/null +++ b/tests/static/bp/decode me.txt @@ -0,0 +1 @@ +I am just a regular static file that needs to have its uri decoded diff --git a/tests/static/bp/python.png b/tests/static/bp/python.png new file mode 100644 index 00000000..52fda109 Binary files /dev/null and b/tests/static/bp/python.png differ diff --git a/tests/static/bp/test.file b/tests/static/bp/test.file new file mode 100644 index 00000000..0725a6ef --- /dev/null +++ b/tests/static/bp/test.file @@ -0,0 +1 @@ +I am just a regular static file diff --git a/tests/test_url_building.py b/tests/test_url_building.py index f234efda..fe31f658 100644 --- a/tests/test_url_building.py +++ b/tests/test_url_building.py @@ -17,6 +17,9 @@ URL_FOR_VALUE2 = '/myurl?arg1=v1&arg1=v2#anchor' URL_FOR_ARGS3 = dict(arg1='v1', _anchor='anchor', _scheme='http', _server='localhost:{}'.format(test_port), _external=True) URL_FOR_VALUE3 = 'http://localhost:{}/myurl?arg1=v1#anchor'.format(test_port) +URL_FOR_ARGS4 = dict(arg1='v1', _anchor='anchor', _external=True, + _server='http://localhost:{}'.format(test_port),) +URL_FOR_VALUE4 = 'http://localhost:{}/myurl?arg1=v1#anchor'.format(test_port) def _generate_handlers_from_names(app, l): @@ -49,7 +52,8 @@ def test_simple_url_for_getting(simple_app): @pytest.mark.parametrize('args,url', [(URL_FOR_ARGS1, URL_FOR_VALUE1), (URL_FOR_ARGS2, URL_FOR_VALUE2), - (URL_FOR_ARGS3, URL_FOR_VALUE3)]) + (URL_FOR_ARGS3, URL_FOR_VALUE3), + (URL_FOR_ARGS4, URL_FOR_VALUE4)]) def test_simple_url_for_getting_with_more_params(args, url): app = Sanic('more_url_build') diff --git a/tests/test_url_for_static.py b/tests/test_url_for_static.py new file mode 100644 index 00000000..d1d8fc9b --- /dev/null +++ b/tests/test_url_for_static.py @@ -0,0 +1,446 @@ +import inspect +import os + +import pytest + +from sanic import Sanic +from sanic.blueprints import Blueprint + + +@pytest.fixture(scope='module') +def static_file_directory(): + """The static directory to serve""" + current_file = inspect.getfile(inspect.currentframe()) + current_directory = os.path.dirname(os.path.abspath(current_file)) + static_directory = os.path.join(current_directory, 'static') + return static_directory + + +def get_file_path(static_file_directory, file_name): + return os.path.join(static_file_directory, file_name) + + +def get_file_content(static_file_directory, file_name): + """The content of the static file to check""" + with open(get_file_path(static_file_directory, file_name), 'rb') as file: + return file.read() + + +@pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt', 'python.png']) +def test_static_file(static_file_directory, file_name): + app = Sanic('test_static') + app.static( + '/testing.file', get_file_path(static_file_directory, file_name)) + app.static( + '/testing2.file', get_file_path(static_file_directory, file_name), + name='testing_file') + + uri = app.url_for('static') + uri2 = app.url_for('static', filename='any') + uri3 = app.url_for('static', name='static', filename='any') + + assert uri == '/testing.file' + assert uri == uri2 + assert uri2 == uri3 + + request, response = app.test_client.get(uri) + assert response.status == 200 + assert response.body == get_file_content(static_file_directory, file_name) + + bp = Blueprint('test_bp_static', url_prefix='/bp') + + bp.static('/testing.file', get_file_path(static_file_directory, file_name)) + bp.static('/testing2.file', + get_file_path(static_file_directory, file_name), + name='testing_file') + + app.blueprint(bp) + + uri = app.url_for('static', name='test_bp_static.static') + uri2 = app.url_for('static', name='test_bp_static.static', filename='any') + uri3 = app.url_for('test_bp_static.static') + uri4 = app.url_for('test_bp_static.static', name='any') + uri5 = app.url_for('test_bp_static.static', filename='any') + uri6 = app.url_for('test_bp_static.static', name='any', filename='any') + + assert uri == '/bp/testing.file' + assert uri == uri2 + assert uri2 == uri3 + assert uri3 == uri4 + assert uri4 == uri5 + assert uri5 == uri6 + + request, response = app.test_client.get(uri) + assert response.status == 200 + assert response.body == get_file_content(static_file_directory, file_name) + + # test for other parameters + uri = app.url_for('static', _external=True, _server='http://localhost') + assert uri == 'http://localhost/testing.file' + + uri = app.url_for('static', name='test_bp_static.static', + _external=True, _server='http://localhost') + assert uri == 'http://localhost/bp/testing.file' + + # test for defined name + uri = app.url_for('static', name='testing_file') + assert uri == '/testing2.file' + + request, response = app.test_client.get(uri) + assert response.status == 200 + assert response.body == get_file_content(static_file_directory, file_name) + + uri = app.url_for('static', name='test_bp_static.testing_file') + assert uri == '/bp/testing2.file' + assert uri == app.url_for('static', name='test_bp_static.testing_file', + filename='any') + + request, response = app.test_client.get(uri) + assert response.status == 200 + assert response.body == get_file_content(static_file_directory, file_name) + + +@pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) +@pytest.mark.parametrize('base_uri', ['/static', '', '/dir']) +def test_static_directory(file_name, base_uri, static_file_directory): + + app = Sanic('test_static') + app.static(base_uri, static_file_directory) + base_uri2 = base_uri + '/2' + app.static(base_uri2, static_file_directory, name='uploads') + + uri = app.url_for('static', name='static', filename=file_name) + assert uri == '{}/{}'.format(base_uri, file_name) + + request, response = app.test_client.get(uri) + assert response.status == 200 + assert response.body == get_file_content(static_file_directory, file_name) + + uri2 = app.url_for('static', name='static', filename='/' + file_name) + uri3 = app.url_for('static', filename=file_name) + uri4 = app.url_for('static', filename='/' + file_name) + uri5 = app.url_for('static', name='uploads', filename=file_name) + uri6 = app.url_for('static', name='uploads', filename='/' + file_name) + + assert uri == uri2 + assert uri2 == uri3 + assert uri3 == uri4 + + assert uri5 == '{}/{}'.format(base_uri2, file_name) + assert uri5 == uri6 + + bp = Blueprint('test_bp_static', url_prefix='/bp') + + bp.static(base_uri, static_file_directory) + bp.static(base_uri2, static_file_directory, name='uploads') + app.blueprint(bp) + + uri = app.url_for('static', name='test_bp_static.static', + filename=file_name) + uri2 = app.url_for('static', name='test_bp_static.static', + filename='/' + file_name) + + uri4 = app.url_for('static', name='test_bp_static.uploads', + filename=file_name) + uri5 = app.url_for('static', name='test_bp_static.uploads', + filename='/' + file_name) + + assert uri == '/bp{}/{}'.format(base_uri, file_name) + assert uri == uri2 + + assert uri4 == '/bp{}/{}'.format(base_uri2, file_name) + assert uri4 == uri5 + + request, response = app.test_client.get(uri) + assert response.status == 200 + assert response.body == get_file_content(static_file_directory, file_name) + + + +@pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) +def test_static_head_request(file_name, static_file_directory): + app = Sanic('test_static') + app.static( + '/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + + bp = Blueprint('test_bp_static', url_prefix='/bp') + bp.static('/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + app.blueprint(bp) + + uri = app.url_for('static') + assert uri == '/testing.file' + assert uri == app.url_for('static', name='static') + assert uri == app.url_for('static', name='static', filename='any') + + request, response = app.test_client.head(uri) + assert response.status == 200 + assert 'Accept-Ranges' in response.headers + assert 'Content-Length' in response.headers + assert int(response.headers[ + 'Content-Length']) == len( + get_file_content(static_file_directory, file_name)) + + # blueprint + uri = app.url_for('static', name='test_bp_static.static') + assert uri == '/bp/testing.file' + assert uri == app.url_for('static', name='test_bp_static.static', + filename='any') + + request, response = app.test_client.head(uri) + assert response.status == 200 + assert 'Accept-Ranges' in response.headers + assert 'Content-Length' in response.headers + assert int(response.headers[ + 'Content-Length']) == len( + get_file_content(static_file_directory, file_name)) + + +@pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) +def test_static_content_range_correct(file_name, static_file_directory): + app = Sanic('test_static') + app.static( + '/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + + bp = Blueprint('test_bp_static', url_prefix='/bp') + bp.static('/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + app.blueprint(bp) + + headers = { + 'Range': 'bytes=12-19' + } + uri = app.url_for('static') + assert uri == '/testing.file' + assert uri == app.url_for('static', name='static') + assert uri == app.url_for('static', name='static', filename='any') + + request, response = app.test_client.get(uri, headers=headers) + assert response.status == 200 + assert 'Content-Length' in response.headers + assert 'Content-Range' in response.headers + static_content = bytes(get_file_content( + static_file_directory, file_name))[12:19] + assert int(response.headers[ + 'Content-Length']) == len(static_content) + assert response.body == static_content + + # blueprint + uri = app.url_for('static', name='test_bp_static.static') + assert uri == '/bp/testing.file' + assert uri == app.url_for('static', name='test_bp_static.static', + filename='any') + assert uri == app.url_for('test_bp_static.static') + assert uri == app.url_for('test_bp_static.static', name='any') + assert uri == app.url_for('test_bp_static.static', filename='any') + assert uri == app.url_for('test_bp_static.static', name='any', + filename='any') + + request, response = app.test_client.get(uri, headers=headers) + assert response.status == 200 + assert 'Content-Length' in response.headers + assert 'Content-Range' in response.headers + static_content = bytes(get_file_content( + static_file_directory, file_name))[12:19] + assert int(response.headers[ + 'Content-Length']) == len(static_content) + assert response.body == static_content + + +@pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) +def test_static_content_range_front(file_name, static_file_directory): + app = Sanic('test_static') + app.static( + '/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + + bp = Blueprint('test_bp_static', url_prefix='/bp') + bp.static('/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + app.blueprint(bp) + + headers = { + 'Range': 'bytes=12-' + } + uri = app.url_for('static') + assert uri == '/testing.file' + assert uri == app.url_for('static', name='static') + assert uri == app.url_for('static', name='static', filename='any') + + request, response = app.test_client.get(uri, headers=headers) + assert response.status == 200 + assert 'Content-Length' in response.headers + assert 'Content-Range' in response.headers + static_content = bytes(get_file_content( + static_file_directory, file_name))[12:] + assert int(response.headers[ + 'Content-Length']) == len(static_content) + assert response.body == static_content + + # blueprint + uri = app.url_for('static', name='test_bp_static.static') + assert uri == '/bp/testing.file' + assert uri == app.url_for('static', name='test_bp_static.static', + filename='any') + assert uri == app.url_for('test_bp_static.static') + assert uri == app.url_for('test_bp_static.static', name='any') + assert uri == app.url_for('test_bp_static.static', filename='any') + assert uri == app.url_for('test_bp_static.static', name='any', + filename='any') + + request, response = app.test_client.get(uri, headers=headers) + assert response.status == 200 + assert 'Content-Length' in response.headers + assert 'Content-Range' in response.headers + static_content = bytes(get_file_content( + static_file_directory, file_name))[12:] + assert int(response.headers[ + 'Content-Length']) == len(static_content) + assert response.body == static_content + + +@pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) +def test_static_content_range_back(file_name, static_file_directory): + app = Sanic('test_static') + app.static( + '/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + + bp = Blueprint('test_bp_static', url_prefix='/bp') + bp.static('/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + app.blueprint(bp) + + headers = { + 'Range': 'bytes=-12' + } + uri = app.url_for('static') + assert uri == '/testing.file' + assert uri == app.url_for('static', name='static') + assert uri == app.url_for('static', name='static', filename='any') + + request, response = app.test_client.get(uri, headers=headers) + assert response.status == 200 + assert 'Content-Length' in response.headers + assert 'Content-Range' in response.headers + static_content = bytes(get_file_content( + static_file_directory, file_name))[-12:] + assert int(response.headers[ + 'Content-Length']) == len(static_content) + assert response.body == static_content + + # blueprint + uri = app.url_for('static', name='test_bp_static.static') + assert uri == '/bp/testing.file' + assert uri == app.url_for('static', name='test_bp_static.static', + filename='any') + assert uri == app.url_for('test_bp_static.static') + assert uri == app.url_for('test_bp_static.static', name='any') + assert uri == app.url_for('test_bp_static.static', filename='any') + assert uri == app.url_for('test_bp_static.static', name='any', + filename='any') + + request, response = app.test_client.get(uri, headers=headers) + assert response.status == 200 + assert 'Content-Length' in response.headers + assert 'Content-Range' in response.headers + static_content = bytes(get_file_content( + static_file_directory, file_name))[-12:] + assert int(response.headers[ + 'Content-Length']) == len(static_content) + assert response.body == static_content + + +@pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) +def test_static_content_range_empty(file_name, static_file_directory): + app = Sanic('test_static') + app.static( + '/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + + bp = Blueprint('test_bp_static', url_prefix='/bp') + bp.static('/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + app.blueprint(bp) + + uri = app.url_for('static') + assert uri == '/testing.file' + assert uri == app.url_for('static', name='static') + assert uri == app.url_for('static', name='static', filename='any') + + request, response = app.test_client.get(uri) + assert response.status == 200 + assert 'Content-Length' in response.headers + assert 'Content-Range' not in response.headers + assert int(response.headers[ + 'Content-Length']) == len(get_file_content(static_file_directory, file_name)) + assert response.body == bytes( + get_file_content(static_file_directory, file_name)) + + # blueprint + uri = app.url_for('static', name='test_bp_static.static') + assert uri == '/bp/testing.file' + assert uri == app.url_for('static', name='test_bp_static.static', + filename='any') + assert uri == app.url_for('test_bp_static.static') + assert uri == app.url_for('test_bp_static.static', name='any') + assert uri == app.url_for('test_bp_static.static', filename='any') + assert uri == app.url_for('test_bp_static.static', name='any', + filename='any') + + request, response = app.test_client.get(uri) + assert response.status == 200 + assert 'Content-Length' in response.headers + assert 'Content-Range' not in response.headers + assert int(response.headers[ + 'Content-Length']) == len(get_file_content(static_file_directory, file_name)) + assert response.body == bytes( + get_file_content(static_file_directory, file_name)) + + +@pytest.mark.parametrize('file_name', ['test.file', 'decode me.txt']) +def test_static_content_range_error(file_name, static_file_directory): + app = Sanic('test_static') + app.static( + '/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + + bp = Blueprint('test_bp_static', url_prefix='/bp') + bp.static('/testing.file', get_file_path(static_file_directory, file_name), + use_content_range=True) + app.blueprint(bp) + + headers = { + 'Range': 'bytes=1-0' + } + uri = app.url_for('static') + assert uri == '/testing.file' + assert uri == app.url_for('static', name='static') + assert uri == app.url_for('static', name='static', filename='any') + + request, response = app.test_client.get(uri, headers=headers) + assert response.status == 416 + assert 'Content-Length' in response.headers + assert 'Content-Range' in response.headers + assert response.headers['Content-Range'] == "bytes */%s" % ( + len(get_file_content(static_file_directory, file_name)),) + + # blueprint + uri = app.url_for('static', name='test_bp_static.static') + assert uri == '/bp/testing.file' + assert uri == app.url_for('static', name='test_bp_static.static', + filename='any') + assert uri == app.url_for('test_bp_static.static') + assert uri == app.url_for('test_bp_static.static', name='any') + assert uri == app.url_for('test_bp_static.static', filename='any') + assert uri == app.url_for('test_bp_static.static', name='any', + filename='any') + + request, response = app.test_client.get(uri, headers=headers) + assert response.status == 416 + assert 'Content-Length' in response.headers + assert 'Content-Range' in response.headers + assert response.headers['Content-Range'] == "bytes */%s" % ( + len(get_file_content(static_file_directory, file_name)),)