Project

General

Profile

Request » History » Version 5

Version 4 (Elmer de Looff, 2012-04-27 12:00) → Version 5/23 (Elmer de Looff, 2012-04-27 12:18)

h1. Request

{{>toc}}

The @Request@ object is an abstraction of the incoming HTTP request. This allows one simple interface that is independent of the underlying server that µWeb runs on (either [[Standalone]] using BaseHTTPServer, or [[Apache]] mode on @mod_python@).

From PageMaker methods, the request object is accessible as the @self.req@ member. The request object contains all the information about the incoming request: query arguments, post data, cookies and environment data. It is also the object where you define cookies that need to be provided to the client.

h1. Query arguments

All query arguments provided by the client are present on the request object. They are also accessible directly on the [[PageMaker]] object. The following code demonstrates both ways to access a query argument:

<pre><code class="html">
...
<form>
<label for="name">Name: </label><input id="name" name="name" />
<input type="submit" value="Tell us your name" />
</form>
...
</code></pre>

<pre><code
class="python">
def NameFromQuery(self): QueryTeller(self):
# Retrieves the 'name' argument from the request object:
name = self.req.vars['get'].getfirst('name')

# Retrieves the 'name' argument directly from the PageMaker instance (linked to the request):
name = self.get.getfirst('name')
return name
</code></pre>

Using the @getfirst@ method, you get a single string returned from the query argument mapping, or a @None@ if no such value exists. Much like a dictionary's @get@ method, you can provide a second argument to the method, and have that returned instead as the default.

Now, HTTP allows the client to provide the same query argument multiple times. Using @getfirst@ you would only get the very first defined argument. So a request that looks like @http://example.org/group?name=Bob&name=Mark&name=Jenny@ would only return 'Bob' in the previous example. To get all their names printed, you can use the following:

<pre><code class="html">
...
<form action="/group">
<h2>Names in this group</h2>
<!-- These would likely be generated with Javascript, but written here for demonstrative purposes -->
<label for="name_1">Name: </label><input id="name_1" name="name" />
<label for="name_2">Name: </label><input id="name_2" name="name" />
<label for="name_3">Name: </label><input id="name_3" name="name" />
<input type="submit" value="Send these names" />
</form>
...
</code></pre>

<pre><code
class="python">
def MemberNames(self): QueryTeller(self):
names = self.get.getlist('name')
return ', '.join(names)
</code></pre>

This returns a neat comma-separated string with all the provided names. The @getlist@ method does not take a default, but will instead return an empty list when there are no values for the requested argument name.

h1. h2. Post data vars

Submitted form data is available on POST arguments can be found under: self.post and should be accessed by issueing a 'getfirst()', or 'getlist()' call for the request object as well. The interface is similar desired key.
self.post.getfirst() allows for a second argument
to that of set a default if the query arguments, and desired key isn't set by the @FieldStorage@ class already present in the @cgi@ module. If we take our initial example form handler, but now receive the data through HTTP POST, the code would look like this: browser

<pre><code <pre>
<code
class="html">
... argA = self.post.getfirst('argA')
<form method="post">
<label for="name">Name: </label><input id="name" name="name" />
<input type="submit" value="Tell us your name" />
</form>
...
</code></pre>
argB = self.post.getfirst('argB', 'empty')

<pre><code class="python">
def NameFromPost(self):
if 'argA' in self.post:
# Retrieves #pass, argA has been send by the 'name' value from the request object:
name = self.req.vars['post'].getfirst('name')

# Retrieves the 'name' value directly from the PageMaker instance (linked to the request):
name = self.post.getfirst('name')
return name
browser

</code>

</code></pre> </pre>

Like with the query arguments, @getfirst@ accepts a second argument that provides a default other than @None@. h2. Get vars

Multiple values are again possible in the FieldStorage, but these GET arguments can be found under: self.get, they work exactly like they do in the query arguments, so please have a look at those. same as POST vars.

h2. Uploading files

h2. Structured data using POST

h1.
Cookies

self.cookies contains the cookies send by the browser, as the interface to create them from the server.

h3. Retrieving a cookie
You can fetch the content of cookie by accessig the self.cookie dict with the name of the desired cookie as its key.
The returned cookie object has a value member containing the actual value of the requested cookie.
<pre>
<code class="python">
self.cookies['sample'].value
</code>
</pre>

h1. Environment h2. ENV

The env variable is a dictionary containing the following items;
* CONTENT_TYPE
* CONTENT_LENGTH
* HTTP_COOKIE
* HTTP_HOST
* HTTP_REFERER
* HTTP_USER_AGENT
* PATH_INFO
* QUERY_STRING
* REMOTE_ADDR
* REQUEST_METHOD
* UWEB_MODE 'STANDALONE' / 'MOD_PYTHON'

h2. h3. Extended environment

env
If more detail is required about the environment, you can issue a call to the self.req.ExtendedEnvironment() method, which will inject more details into the env var. This is a much slower operation than the normal env call, so that's why its tucked away in a separate method.

* AUTH_TYPE
* CONNECTION_ID
* DOCUMENT_ROOT
* RAW_REQUEST
* REMOTE_HOST
* REMOTE_USER
* SERVER_NAME
* SERVER_PORT
* SERVER_LOCAL_NAME
* SERVER_LOCAL_IP
* SERVER_PROTOCOL

And in case of a @mod_python@ setup you will also get:
* MODPYTHON_HANDLER
* MODPYTHON_INTERPRETER
* MODPYTHON_PHASE

h1. Setting cookies