Response » History » Version 2
Version 1 (Elmer de Looff, 2012-04-20 17:36) → Version 2/3 (Elmer de Looff, 2012-04-20 17:41)
{{>toc}}
h1. Response
HTTP requests can be answered in one of two ways in uWeb. The first, and simplest method is to simply issue a @return@ statement in the *[[PageMaker]]* and provide a string (or any object that can be reduced to a string). This will create a response to the client with a *HTTP status code 200 OK*, and the body of the reply will be the returned string.
<pre><code class="python">
def SimplePage(self):
return """<!DOCTYPE html>
<html>
<head><title>My website</title></head>
<body><h1>Hello world</h1></body>
</html>"""
</code></pre>
This returns a minimal document to the client. Also, the default content-type will be used, and provided in the outgoing headers: *text/html*.
*N.B.*: Like all code examples on this page, this example assumes that the defined function is part of a PageMaker class, and that the uweb package itself has been imported under its default name.
If you need to change any of these, for instance setting a cookie, another content-type, or different HTTP status codes, you will need to use the @Repsonse@ class. The following sections will explain how to use the Response class in various situations.
h2. Different HTTP status code
Returning a "Not Found" page, or even a "Internal Server Error" page is never fun, but they are two of many situations where you will want to serve content with a different HTTP status code. This is easily done using the @Response@ class:
<pre><code class="python">
def FourOhFour(self):
return uweb.Response('Unfortunately, we could not locate your document', httpcode=404)
</code></pre>
A more verbose example, that also shows you how you would use the *[[TemplateParser]]*, could look like like follows. In this example, we grab the receive the requested path as argument from the *[[Request Router]]*, and we pass this into a template:
<pre><code class="python">
def FourOhFour(self, path):
return uweb.Response(self.parser('404.utp', path=path), httpcode=404)
</code></pre>
h2. Different content-type
There are also many situations where our response is not HTML. For instance, if you're developing rich applications with a lot of Javascript interaction, you will likely be answering requests using JSON. The final steps of your response would look like this:
<pre><code class="python">
def JsonResponse(self):
return uweb.Response(json.dumps({'name': 'µWeb'}),
content_type='application/json')
</code></pre>
h2. Adding custom headers
Adding to our previous example, if we want our JSON response to be usable cross-domain, we need to provide the correct allow-origin controls. These require a header mention, and can be added directly into the @Response@ object. Headers can be added by providing a dictionary with the header names and corresponding values.
<pre><code class="python">
def JsonGlobalResponse(self):
return uweb.Response(json.dumps({'name': 'µWeb'}),
content_type='application/json',
headers={'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache, must-revalidate'})
</code></pre>
*N.B.:* Cookies should be set using the *[[Request]]* object's @AddCookie@ method, and not using the headers of the @Response@ object. Redirects can generally more easily be created using the @Redirect@ class explained below.
h1. Redirect
For redirects, there is a convenience class present in uWeb. This is a subclass of @Response@ that only requires a new location, and optionally a HTTP status code. If the status code is not provided, it will default to *307 (Temporary Redirect)*:
<pre><code class="python">
return uweb.Redirect('http://underdark.nl')
</code></pre>
To create a permanent redirect, simply provide the associated "status code":http://en.wikipedia.org/wiki/List_of_HTTP_status_codes:
<pre><code class="python">
return uweb.Redirect('http://bugs.underdark.nl/projects/uweb/wiki/Response', httpcode=301)
</code></pre>
h1. Response
HTTP requests can be answered in one of two ways in uWeb. The first, and simplest method is to simply issue a @return@ statement in the *[[PageMaker]]* and provide a string (or any object that can be reduced to a string). This will create a response to the client with a *HTTP status code 200 OK*, and the body of the reply will be the returned string.
<pre><code class="python">
def SimplePage(self):
return """<!DOCTYPE html>
<html>
<head><title>My website</title></head>
<body><h1>Hello world</h1></body>
</html>"""
</code></pre>
This returns a minimal document to the client. Also, the default content-type will be used, and provided in the outgoing headers: *text/html*.
*N.B.*: Like all code examples on this page, this example assumes that the defined function is part of a PageMaker class, and that the uweb package itself has been imported under its default name.
If you need to change any of these, for instance setting a cookie, another content-type, or different HTTP status codes, you will need to use the @Repsonse@ class. The following sections will explain how to use the Response class in various situations.
h2. Different HTTP status code
Returning a "Not Found" page, or even a "Internal Server Error" page is never fun, but they are two of many situations where you will want to serve content with a different HTTP status code. This is easily done using the @Response@ class:
<pre><code class="python">
def FourOhFour(self):
return uweb.Response('Unfortunately, we could not locate your document', httpcode=404)
</code></pre>
A more verbose example, that also shows you how you would use the *[[TemplateParser]]*, could look like like follows. In this example, we grab the receive the requested path as argument from the *[[Request Router]]*, and we pass this into a template:
<pre><code class="python">
def FourOhFour(self, path):
return uweb.Response(self.parser('404.utp', path=path), httpcode=404)
</code></pre>
h2. Different content-type
There are also many situations where our response is not HTML. For instance, if you're developing rich applications with a lot of Javascript interaction, you will likely be answering requests using JSON. The final steps of your response would look like this:
<pre><code class="python">
def JsonResponse(self):
return uweb.Response(json.dumps({'name': 'µWeb'}),
content_type='application/json')
</code></pre>
h2. Adding custom headers
Adding to our previous example, if we want our JSON response to be usable cross-domain, we need to provide the correct allow-origin controls. These require a header mention, and can be added directly into the @Response@ object. Headers can be added by providing a dictionary with the header names and corresponding values.
<pre><code class="python">
def JsonGlobalResponse(self):
return uweb.Response(json.dumps({'name': 'µWeb'}),
content_type='application/json',
headers={'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-cache, must-revalidate'})
</code></pre>
*N.B.:* Cookies should be set using the *[[Request]]* object's @AddCookie@ method, and not using the headers of the @Response@ object. Redirects can generally more easily be created using the @Redirect@ class explained below.
h1. Redirect
For redirects, there is a convenience class present in uWeb. This is a subclass of @Response@ that only requires a new location, and optionally a HTTP status code. If the status code is not provided, it will default to *307 (Temporary Redirect)*:
<pre><code class="python">
return uweb.Redirect('http://underdark.nl')
</code></pre>
To create a permanent redirect, simply provide the associated "status code":http://en.wikipedia.org/wiki/List_of_HTTP_status_codes:
<pre><code class="python">
return uweb.Redirect('http://bugs.underdark.nl/projects/uweb/wiki/Response', httpcode=301)
</code></pre>