Use url_for to resolve path instead of hard coding it

Using url_for is useful if httpbin is served under a prefix path.  For
example, we can serve httpbin under http://example.org/httpbin.
Previously, we have to replace all hard coded paths, which produces
many diffs, and it makes hard to upgrade httpbin from source.  This
commit uses url_for to resolve correct path even if prefix path is
used.  For digest auth, we have to prepend request.script_root to
request.path to pass authentication.
This commit is contained in:
Tatsuhiro Tsujikawa
2015-07-11 01:28:38 +09:00
parent 811d0d5177
commit 88a7e1966d
4 changed files with 48 additions and 48 deletions
+8 -8
View File
@@ -249,10 +249,10 @@ def relative_redirect_n_times(n):
response.status_code = 302
if n == 1:
response.headers['Location'] = '/get'
response.headers['Location'] = url_for('view_get')
return response
response.headers['Location'] = '/relative-redirect/{0}'.format(n - 1)
response.headers['Location'] = url_for('relative_redirect_n_times', n=n - 1)
return response
@@ -357,7 +357,7 @@ def view_forms_post():
def set_cookie(name, value):
"""Sets a cookie and redirects to cookie list."""
r = app.make_response(redirect('/cookies'))
r = app.make_response(redirect(url_for('view_cookies')))
r.set_cookie(key=name, value=value, secure=secure_cookie())
return r
@@ -368,7 +368,7 @@ def set_cookies():
"""Sets cookie(s) as provided by the query string and redirects to cookie list."""
cookies = dict(request.args.items())
r = app.make_response(redirect('/cookies'))
r = app.make_response(redirect(url_for('view_cookies')))
for key, value in cookies.items():
r.set_cookie(key=key, value=value, secure=secure_cookie())
@@ -380,7 +380,7 @@ def delete_cookies():
"""Deletes cookie(s) as provided by the query string and redirects to cookie list."""
cookies = dict(request.args.items())
r = app.make_response(redirect('/cookies'))
r = app.make_response(redirect(url_for('view_cookies')))
for key, value in cookies.items():
r.delete_cookie(key=key)
@@ -631,14 +631,14 @@ def link_page(n, offset):
"""Generate a page containing n links to other pages which do the same."""
n = min(max(1, n), 200) # limit to between 1 and 200 links
link = "<a href='/links/{0}/{1}'>{2}</a> "
link = "<a href='{0}'>{1}</a> "
html = ['<html><head><title>Links</title></head><body>']
for i in xrange(n):
if i == offset:
html.append("{0} ".format(i))
else:
html.append(link.format(n, i, i))
html.append(link.format(url_for('link_page', n=n, offset=i), i))
html.append('</body></html>')
return ''.join(html)
@@ -647,7 +647,7 @@ def link_page(n, offset):
@app.route('/links/<int:n>')
def links(n):
"""Redirect to first links page."""
return redirect("/links/{0}/0".format(n))
return redirect(url_for('link_page', n=n, offset=0))
@app.route('/image')
+1 -1
View File
@@ -330,7 +330,7 @@ def check_digest_auth(user, passwd):
credentails = parse_authorization_header(request.headers.get('Authorization'))
if not credentails:
return
response_hash = response(credentails, passwd, dict(uri=request.path,
response_hash = response(credentails, passwd, dict(uri=request.script_root + request.path,
body=request.data,
method=request.method))
if credentails.get('response') == response_hash:
+1 -1
View File
@@ -4,7 +4,7 @@
</head>
<body>
<!-- Example form from HTML5 spec http://www.w3.org/TR/html5/forms.html#writing-a-form's-user-interface -->
<form method="post" action="/post">
<form method="post" action="{{ url_for('view_post') }}">
<p><label>Customer name: <input name="custname"></label></p>
<p><label>Telephone: <input type=tel name="custtel"></label></p>
<p><label>E-mail address: <input type=email name="custemail"></label></p>
+38 -38
View File
@@ -5,48 +5,48 @@
<h2 id="ENDPOINTS">ENDPOINTS</h2>
<ul>
<li><a href="/" data-bare-link="true"><code>/</code></a> This page.</li>
<li><a href="/ip" data-bare-link="true"><code>/ip</code></a> Returns Origin IP.</li>
<li><a href="/user-agent" data-bare-link="true"><code>/user-agent</code></a> Returns user-agent.</li>
<li><a href="/headers" data-bare-link="true"><code>/headers</code></a> Returns header dict.</li>
<li><a href="/get" data-bare-link="true"><code>/get</code></a> Returns GET data.</li>
<li><a href="{{ url_for('view_landing_page') }}" data-bare-link="true"><code>/</code></a> This page.</li>
<li><a href="{{ url_for('view_origin') }}" data-bare-link="true"><code>/ip</code></a> Returns Origin IP.</li>
<li><a href="{{ url_for('view_user_agent') }}" data-bare-link="true"><code>/user-agent</code></a> Returns user-agent.</li>
<li><a href="{{ url_for('view_headers') }}" data-bare-link="true"><code>/headers</code></a> Returns header dict.</li>
<li><a href="{{ url_for('view_get') }}" data-bare-link="true"><code>/get</code></a> Returns GET data.</li>
<li><code>/post</code> Returns POST data.</li>
<li><code>/patch</code> Returns PATCH data.</li>
<li><code>/put</code> Returns PUT data.</li>
<li><code>/delete</code> Returns DELETE data</li>
<li><a href="/encoding/utf8"><code>/encoding/utf8</code></a> Returns page containing UTF-8 data.</li>
<li><a href="/gzip" data-bare-link="true"><code>/gzip</code></a> Returns gzip-encoded data.</li>
<li><a href="/deflate" data-bare-link="true"><code>/deflate</code></a> Returns deflate-encoded data.</li>
<li><a href="/status/418"><code>/status/:code</code></a> Returns given HTTP Status code.</li>
<li><a href="/response-headers?Content-Type=text/plain;%20charset=UTF-8&amp;Server=httpbin"><code>/response-headers?key=val</code></a> Returns given response headers.</li>
<li><a href="/redirect/6"><code>/redirect/:n</code></a> 302 Redirects <em>n</em> times.</li>
<li><a href="/redirect-to?url=http://example.com/"><code>/redirect-to?url=foo</code></a> 302 Redirects to the <em>foo</em> URL.</li>
<li><a href="/relative-redirect/6"><code>/relative-redirect/:n</code></a> 302 Relative redirects <em>n</em> times.</li>
<li><a href="/absolute-redirect/6"><code>/absolute-redirect/:n</code></a> 302 Absolute redirects <em>n</em> times.</li>
<li><a href="/cookies" data-bare-link="true"><code>/cookies</code></a> Returns cookie data.</li>
<li><a href="/cookies/set?k1=v1&amp;k2=v2"><code>/cookies/set?name=value</code></a> Sets one or more simple cookies.</li>
<li><a href="/cookies/delete?k1&amp;k2"><code>/cookies/delete?name</code></a> Deletes one or more simple cookies.</li>
<li><a href="/basic-auth/user/passwd"><code>/basic-auth/:user/:passwd</code></a> Challenges HTTPBasic Auth.</li>
<li><a href="/hidden-basic-auth/user/passwd"><code>/hidden-basic-auth/:user/:passwd</code></a> 404'd BasicAuth.</li>
<li><a href="/digest-auth/auth/user/passwd"><code>/digest-auth/:qop/:user/:passwd</code></a> Challenges HTTP Digest Auth.</li>
<li><a href="/stream/20"><code>/stream/:n</code></a> Streams <em>n</em>100 lines.</li>
<li><a href="/delay/3"><code>/delay/:n</code></a> Delays responding for <em>n</em>10 seconds.</li>
<li><a href="/drip?numbytes=5&amp;duration=5&amp;code=200"><code>/drip?numbytes=n&amp;duration=s&amp;delay=s&amp;code=code</code></a> Drips data over a duration after an optional initial delay, then (optionally) returns with the given status code.</li>
<li><a href="/range/1024"><code>/range/1024?duration=s&amp;chunk_size=code</code></a> Streams <em>n</em> bytes, and allows specifying a <em>Range</em> header to select a subset of the data. Accepts a <em>chunk_size</em> and request <em>duration</em> parameter.</li>
<li><a href="/html" data-bare-link="true"><code>/html</code></a> Renders an HTML Page.</li>
<li><a href="/robots.txt" data-bare-link="true"><code>/robots.txt</code></a> Returns some robots.txt rules.</li>
<li><a href="/deny" data-bare-link="true"><code>/deny</code></a> Denied by robots.txt file.</li>
<li><a href="/cache" data-bare-link="true"><code>/cache</code></a> Returns 200 unless an If-Modified-Since or If-None-Match header is provided, when it returns a 304.</li>
<li><a href="/cache/60"><code>/cache/:n</code></a> Sets a Cache-Control header for <em>n</em> seconds.</li>
<li><a href="/bytes/1024"><code>/bytes/:n</code></a> Generates <em>n</em> random bytes of binary data, accepts optional <em>seed</em> integer parameter.</li>
<li><a href="/stream-bytes/1024"><code>/stream-bytes/:n</code></a> Streams <em>n</em> random bytes of binary data, accepts optional <em>seed</em> and <em>chunk_size</em> integer parameters.</li>
<li><a href="/links/10"><code>/links/:n</code></a> Returns page containing <em>n</em> HTML links.</li>
<li><a href="/image"><code>/image</code></a> Returns page containing an image.</li>
<li><a href="/image/png"><code>/image/png</code></a> Returns page containing a PNG image.</li>
<li><a href="/image/jpeg"><code>/image/jpeg</code></a> Returns page containing a JPEG image.</li>
<li><a href="/image/webp"><code>/image/webp</code></a> Returns page containing a WEBP image.</li>
<li><a href="/forms/post" data-bare-link="true"><code>/forms/post</code></a> HTML form that submits to <em>/post</em></li>
<li><a href="/xml" data-bare-link="true"><code>/xml</code></a> Returns some XML</li>
<li><a href="{{ url_for('encoding') }}"><code>/encoding/utf8</code></a> Returns page containing UTF-8 data.</li>
<li><a href="{{ url_for('view_gzip_encoded_content') }}" data-bare-link="true"><code>/gzip</code></a> Returns gzip-encoded data.</li>
<li><a href="{{ url_for('view_deflate_encoded_content') }}" data-bare-link="true"><code>/deflate</code></a> Returns deflate-encoded data.</li>
<li><a href="{{ url_for('view_status_code', codes='418') }}"><code>/status/:code</code></a> Returns given HTTP Status code.</li>
<li><a href="{{ url_for('response_headers', **{'Content-Type': 'text/plain; charset=UTF-8', 'Server': 'httpbin'}) }}"><code>/response-headers?key=val</code></a> Returns given response headers.</li>
<li><a href="{{ url_for('redirect_n_times', n=6) }}"><code>/redirect/:n</code></a> 302 Redirects <em>n</em> times.</li>
<li><a href="{{ url_for('redirect_to', url='http://example.com/') }}"><code>/redirect-to?url=foo</code></a> 302 Redirects to the <em>foo</em> URL.</li>
<li><a href="{{ url_for('relative_redirect_n_times', n=6) }}"><code>/relative-redirect/:n</code></a> 302 Relative redirects <em>n</em> times.</li>
<li><a href="{{ url_for('absolute_redirect_n_times', n=6) }}"><code>/absolute-redirect/:n</code></a> 302 Absolute redirects <em>n</em> times.</li>
<li><a href="{{ url_for('view_cookies') }}" data-bare-link="true"><code>/cookies</code></a> Returns cookie data.</li>
<li><a href="{{ url_for('set_cookies', k1='v1', k2='v2') }}"><code>/cookies/set?name=value</code></a> Sets one or more simple cookies.</li>
<li><a href="{{ url_for('delete_cookies', k1='', k2='') }}"><code>/cookies/delete?name</code></a> Deletes one or more simple cookies.</li>
<li><a href="{{ url_for('basic_auth', user='user', passwd='passwd') }}"><code>/basic-auth/:user/:passwd</code></a> Challenges HTTPBasic Auth.</li>
<li><a href="{{ url_for('hidden_basic_auth', user='user', passwd='passwd') }}"><code>/hidden-basic-auth/:user/:passwd</code></a> 404'd BasicAuth.</li>
<li><a href="{{ url_for('digest_auth', qop='auth', user='user', passwd='passwd') }}"><code>/digest-auth/:qop/:user/:passwd</code></a> Challenges HTTP Digest Auth.</li>
<li><a href="{{ url_for('stream_n_messages', n=20) }}"><code>/stream/:n</code></a> Streams <em>n</em>100 lines.</li>
<li><a href="{{ url_for('delay_response', delay=3) }}"><code>/delay/:n</code></a> Delays responding for <em>n</em>10 seconds.</li>
<li><a href="{{ url_for('drip', numbytes=5, duration=5, code=200) }}"><code>/drip?numbytes=n&amp;duration=s&amp;delay=s&amp;code=code</code></a> Drips data over a duration after an optional initial delay, then (optionally) returns with the given status code.</li>
<li><a href="{{ url_for('range_request', numbytes=1024) }}"><code>/range/1024?duration=s&amp;chunk_size=code</code></a> Streams <em>n</em> bytes, and allows specifying a <em>Range</em> header to select a subset of the data. Accepts a <em>chunk_size</em> and request <em>duration</em> parameter.</li>
<li><a href="{{ url_for('view_html_page') }}" data-bare-link="true"><code>/html</code></a> Renders an HTML Page.</li>
<li><a href="{{ url_for('view_robots_page') }}" data-bare-link="true"><code>/robots.txt</code></a> Returns some robots.txt rules.</li>
<li><a href="{{ url_for('view_deny_page') }}" data-bare-link="true"><code>/deny</code></a> Denied by robots.txt file.</li>
<li><a href="{{ url_for('cache') }}" data-bare-link="true"><code>/cache</code></a> Returns 200 unless an If-Modified-Since or If-None-Match header is provided, when it returns a 304.</li>
<li><a href="{{ url_for('cache_control', value=60) }}"><code>/cache/:n</code></a> Sets a Cache-Control header for <em>n</em> seconds.</li>
<li><a href="{{ url_for('random_bytes', n=1024) }}"><code>/bytes/:n</code></a> Generates <em>n</em> random bytes of binary data, accepts optional <em>seed</em> integer parameter.</li>
<li><a href="{{ url_for('stream_random_bytes', n=1024) }}"><code>/stream-bytes/:n</code></a> Streams <em>n</em> random bytes of binary data, accepts optional <em>seed</em> and <em>chunk_size</em> integer parameters.</li>
<li><a href="{{ url_for('links', n=10) }}"><code>/links/:n</code></a> Returns page containing <em>n</em> HTML links.</li>
<li><a href="{{ url_for('image') }}"><code>/image</code></a> Returns page containing an image.</li>
<li><a href="{{ url_for('image_png') }}"><code>/image/png</code></a> Returns page containing a PNG image.</li>
<li><a href="{{ url_for('image_jpeg') }}"><code>/image/jpeg</code></a> Returns page containing a JPEG image.</li>
<li><a href="{{ url_for('image_webp') }}"><code>/image/webp</code></a> Returns page containing a WEBP image.</li>
<li><a href="{{ url_for('view_forms_post') }}" data-bare-link="true"><code>/forms/post</code></a> HTML form that submits to <em>/post</em></li>
<li><a href="{{ url_for('xml') }}" data-bare-link="true"><code>/xml</code></a> Returns some XML</li>
</ul>