Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Unreleased

- The development server does not set ``Transfer-Encoding: chunked``
for 1xx, 204, 304, and HEAD responses. :issue:`2375`
- Response HTML for exceptions and redirects starts with
``<!doctype html>`` and ``<html lang=en>``. :issue:`2390`


Version 2.1.1
Expand Down
2 changes: 1 addition & 1 deletion docs/test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ requests.
>>> resp.headers
Headers([('Content-Type', 'text/html; charset=utf-8'), ('Content-Length', '6658')])
>>> response.get_data(as_text=True)
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"...'
'<!doctype html>...'

The client's request methods return instances of :class:`TestResponse`.
This provides extra attributes and methods on top of
Expand Down
3 changes: 1 addition & 2 deletions examples/coolmagic/templates/layout.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!doctype html>
<html>
<head>
<title>{{ page_title }} &mdash; Cool Magic!</title>
Expand Down
3 changes: 1 addition & 2 deletions examples/couchy/templates/layout.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!doctype html>
<html>
<head>
<title>Shorty</title>
Expand Down
3 changes: 1 addition & 2 deletions examples/cupoftee/templates/layout.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!doctype html>
<html>
<head>
<title>Teeworlds Server Browser</title>
Expand Down
3 changes: 1 addition & 2 deletions examples/i18nurls/templates/layout.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!doctype html>
<html>
<head>
<title>{{ title }} | Example Application</title>
Expand Down
3 changes: 1 addition & 2 deletions examples/plnt/templates/layout.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!doctype html>
<title>Plnt Planet</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('shared', file='style.css') }}">

Expand Down
3 changes: 1 addition & 2 deletions examples/shorty/templates/layout.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!doctype html>
<html>
<head>
<title>Shorty</title>
Expand Down
4 changes: 2 additions & 2 deletions src/werkzeug/_internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,8 @@ def injecting_start_response(
injecting_start_response("200 OK", [("Content-Type", "text/html")])
return [
f"""\
<!DOCTYPE html>
<html>
<!doctype html>
<html lang=en>
<head>
<title>About Werkzeug</title>
<style type="text/css">
Expand Down
4 changes: 2 additions & 2 deletions src/werkzeug/debug/tbtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
from .console import Console

HEADER = """\
<!DOCTYPE html>
<html>
<!doctype html>
<html lang=en>
<head>
<title>%(title)s // Werkzeug Debugger</title>
<link rel="stylesheet" href="?__debugger__=yes&amp;cmd=resource&amp;f=style.css">
Expand Down
3 changes: 2 additions & 1 deletion src/werkzeug/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ def get_body(
) -> str:
"""Get the HTML body."""
return (
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
"<!doctype html>\n"
"<html lang=en>\n"
f"<title>{self.code} {escape(self.name)}</title>\n"
f"<h1>{escape(self.name)}</h1>\n"
f"{self.get_description(environ)}\n"
Expand Down
4 changes: 2 additions & 2 deletions src/werkzeug/testapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@


TEMPLATE = """\
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!doctype html>
<html lang=en>
<title>WSGI Information</title>
<style type="text/css">
@import url(https://fonts.googleapis.com/css?family=Ubuntu);
Expand Down
8 changes: 5 additions & 3 deletions src/werkzeug/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,15 @@ def redirect(
from .urls import iri_to_uri

location = iri_to_uri(location, safe_conversion=True)

response = Response( # type: ignore
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
"<!doctype html>\n"
"<html lang=en>\n"
"<title>Redirecting...</title>\n"
"<h1>Redirecting...</h1>\n"
"<p>You should be redirected automatically to target URL: "
"<p>You should be redirected automatically to the target URL: "
f'<a href="{html.escape(location)}">{display_location}</a>. If'
" not click the link.",
" not, click the link.\n",
code,
mimetype="text/html",
)
Expand Down
2 changes: 1 addition & 1 deletion tests/res/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
Expand Down
16 changes: 16 additions & 0 deletions tests/test_exceptions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import datetime
from html import escape

import pytest

Expand Down Expand Up @@ -146,3 +147,18 @@ class TestResponse(Response):

def test_description_none():
HTTPException().get_response()


@pytest.mark.parametrize(
"cls",
sorted(
(e for e in HTTPException.__subclasses__() if e.code),
key=lambda e: e.code, # type: ignore
),
)
def test_response_body(cls):
exc = cls()
response_body = exc.get_body()
assert response_body.startswith("<!doctype html>\n<html lang=en>\n")
assert f"{exc.code} {escape(exc.name)}" in response_body
assert exc.get_description() in response_body
29 changes: 27 additions & 2 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,43 @@

def test_redirect():
resp = utils.redirect("/füübär")
assert b"/f%C3%BC%C3%BCb%C3%A4r" in resp.get_data()
assert resp.headers["Location"] == "/f%C3%BC%C3%BCb%C3%A4r"
assert resp.status_code == 302
assert resp.get_data() == (
b"<!doctype html>\n"
b"<html lang=en>\n"
b"<title>Redirecting...</title>\n"
b"<h1>Redirecting...</h1>\n"
b"<p>You should be redirected automatically to the target URL: "
b'<a href="/f%C3%BC%C3%BCb%C3%A4r">/f\xc3\xbc\xc3\xbcb\xc3\xa4r</a>. '
b"If not, click the link.\n"
)

resp = utils.redirect("http://☃.net/", 307)
assert b"http://xn--n3h.net/" in resp.get_data()
assert resp.headers["Location"] == "http://xn--n3h.net/"
assert resp.status_code == 307
assert resp.get_data() == (
b"<!doctype html>\n"
b"<html lang=en>\n"
b"<title>Redirecting...</title>\n"
b"<h1>Redirecting...</h1>\n"
b"<p>You should be redirected automatically to the target URL: "
b'<a href="http://xn--n3h.net/">http://\xe2\x98\x83.net/</a>. '
b"If not, click the link.\n"
)

resp = utils.redirect("http://example.com/", 305)
assert resp.headers["Location"] == "http://example.com/"
assert resp.status_code == 305
assert resp.get_data() == (
b"<!doctype html>\n"
b"<html lang=en>\n"
b"<title>Redirecting...</title>\n"
b"<h1>Redirecting...</h1>\n"
b"<p>You should be redirected automatically to the target URL: "
b'<a href="http://example.com/">http://example.com/</a>. '
b"If not, click the link.\n"
)


def test_redirect_xss():
Expand Down