Response » History » Version 2
Elmer de Looff, 2012-04-20 17:41
TOC on the right
1 | 2 | Elmer de Looff | {{>toc}} |
---|---|---|---|
2 | 2 | Elmer de Looff | |
3 | 1 | Elmer de Looff | h1. Response |
4 | 1 | Elmer de Looff | |
5 | 1 | Elmer de Looff | 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. |
6 | 1 | Elmer de Looff | |
7 | 1 | Elmer de Looff | <pre><code class="python"> |
8 | 1 | Elmer de Looff | def SimplePage(self): |
9 | 1 | Elmer de Looff | return """<!DOCTYPE html> |
10 | 1 | Elmer de Looff | <html> |
11 | 1 | Elmer de Looff | <head><title>My website</title></head> |
12 | 1 | Elmer de Looff | <body><h1>Hello world</h1></body> |
13 | 1 | Elmer de Looff | </html>""" |
14 | 1 | Elmer de Looff | </code></pre> |
15 | 1 | Elmer de Looff | |
16 | 1 | Elmer de Looff | This returns a minimal document to the client. Also, the default content-type will be used, and provided in the outgoing headers: *text/html*. |
17 | 1 | Elmer de Looff | |
18 | 1 | Elmer de Looff | *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. |
19 | 1 | Elmer de Looff | |
20 | 1 | Elmer de Looff | 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. |
21 | 1 | Elmer de Looff | |
22 | 1 | Elmer de Looff | |
23 | 1 | Elmer de Looff | h2. Different HTTP status code |
24 | 1 | Elmer de Looff | |
25 | 1 | Elmer de Looff | 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: |
26 | 1 | Elmer de Looff | |
27 | 1 | Elmer de Looff | <pre><code class="python"> |
28 | 1 | Elmer de Looff | def FourOhFour(self): |
29 | 1 | Elmer de Looff | return uweb.Response('Unfortunately, we could not locate your document', httpcode=404) |
30 | 1 | Elmer de Looff | </code></pre> |
31 | 1 | Elmer de Looff | |
32 | 1 | Elmer de Looff | 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: |
33 | 1 | Elmer de Looff | |
34 | 1 | Elmer de Looff | <pre><code class="python"> |
35 | 1 | Elmer de Looff | def FourOhFour(self, path): |
36 | 1 | Elmer de Looff | return uweb.Response(self.parser('404.utp', path=path), httpcode=404) |
37 | 1 | Elmer de Looff | </code></pre> |
38 | 1 | Elmer de Looff | |
39 | 1 | Elmer de Looff | |
40 | 1 | Elmer de Looff | h2. Different content-type |
41 | 1 | Elmer de Looff | |
42 | 1 | Elmer de Looff | 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: |
43 | 1 | Elmer de Looff | |
44 | 1 | Elmer de Looff | <pre><code class="python"> |
45 | 1 | Elmer de Looff | def JsonResponse(self): |
46 | 1 | Elmer de Looff | return uweb.Response(json.dumps({'name': 'µWeb'}), |
47 | 1 | Elmer de Looff | content_type='application/json') |
48 | 1 | Elmer de Looff | </code></pre> |
49 | 1 | Elmer de Looff | |
50 | 1 | Elmer de Looff | |
51 | 1 | Elmer de Looff | h2. Adding custom headers |
52 | 1 | Elmer de Looff | |
53 | 1 | Elmer de Looff | 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. |
54 | 1 | Elmer de Looff | |
55 | 1 | Elmer de Looff | <pre><code class="python"> |
56 | 1 | Elmer de Looff | def JsonGlobalResponse(self): |
57 | 1 | Elmer de Looff | return uweb.Response(json.dumps({'name': 'µWeb'}), |
58 | 1 | Elmer de Looff | content_type='application/json', |
59 | 1 | Elmer de Looff | headers={'Access-Control-Allow-Origin': '*', |
60 | 1 | Elmer de Looff | 'Cache-Control': 'no-cache, must-revalidate'}) |
61 | 1 | Elmer de Looff | </code></pre> |
62 | 1 | Elmer de Looff | |
63 | 1 | Elmer de Looff | *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. |
64 | 1 | Elmer de Looff | |
65 | 1 | Elmer de Looff | |
66 | 1 | Elmer de Looff | h1. Redirect |
67 | 1 | Elmer de Looff | |
68 | 1 | Elmer de Looff | 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)*: |
69 | 1 | Elmer de Looff | |
70 | 1 | Elmer de Looff | <pre><code class="python"> |
71 | 1 | Elmer de Looff | return uweb.Redirect('http://underdark.nl') |
72 | 1 | Elmer de Looff | </code></pre> |
73 | 1 | Elmer de Looff | |
74 | 1 | Elmer de Looff | To create a permanent redirect, simply provide the associated "status code":http://en.wikipedia.org/wiki/List_of_HTTP_status_codes: |
75 | 1 | Elmer de Looff | |
76 | 1 | Elmer de Looff | <pre><code class="python"> |
77 | 1 | Elmer de Looff | return uweb.Redirect('http://bugs.underdark.nl/projects/uweb/wiki/Response', httpcode=301) |
78 | 1 | Elmer de Looff | </code></pre> |