17.2. CherryPy and the HTTP Request/Response Cycle
As you will see in Chapter 18, "TurboGears Deployment," you can run TurboGears applications directly on CherryPy, or behind ModPython, ModProxy, or behind any server that supports the Web Server Gateway Interface (WSGI) specification. But no matter how you configure the front end, CherryPy is still responsible for handling the incoming requests and creating the final responses to go out to the user.
The exact methods that CherryPy uses are probably not important, but it is often important that you know how to access the various request properties, and how to set response parameters. Luckily, the cherrypy.request and cherrypy.response objects provide easy access to each of these items.
For example, when extending the 20 Min Wiki (available on turbogearsbook.com), you might want to implement a common wiki feature that logs the IP address of every user who edits a page. This is extraordinarily easy: Just add a line such as user_IP = cherrypy.request.remote_addr(). You can then save user_IP into whatever log format you want.
Some people have complained about CherryPy because it doesn't differentiate between post and get requests. But this complaint is misdirected; you can create a simple controller object that determines the request method with a single call to cherrypy.request.method and use it to redirect you to objects that handle the specific request type that came in. And most of the time, the same object can handle both post and get requests, so less-common cases are easy, and the common case is absolutely trivial. In Table 17.1, you can see the attributes of the request object and what they return.
Table 17-1. cherrypy.request Object Attributes
Contains the IP address of the client who made the request, or empty string (if remote address is unavailable).
Contains the client port number, or -1 if the client port is not available.
Contains the client host name if available
Contains a dictionary with the HTTP headers
The first line of the request, which will be something like PUT /path/to/page HTTP/1.0.
Contains a simple_cookie object from the standard library's cookie module.
The unprocessed request body (for post and put requests)
Contains the rfile attribute and is only available for post or put methods only when the processRequestBody value is set to False. If processRequestBody is true, the request body will be consumed and the results placed in request.body or turned into the parameters passed into the controller method.
the body of the request
Contains the contents of a put or post request that is not encoded as application/x-www-form-urlencoded
This attribute doesn't contain data from the requestinstead it controls whether the request body is processed by CherryPy or left in the rfile attribute for your controllers to process on their own.
Contains the HTTP request method (GET, POST, and so on).
Contains the version of the HTTP used for the request in the format HTTP/1.1.
Contains a numeric representation of the HTTP version used in the request.
Contains the environment dictionary for use with Web Server Gateway Interface (WSGI) call (only available when you use a WSGI server).
The query string of the request (everything after the ?).
This contains the path portion of the URL from the request
Contains all values from the query string and the values from the post body (if any).
Contains the base URL of the request.
Contains the full URL from the browser, base + path + querystring.
Contains the object path of the exposed method that will be called for this request.
Contains the original path to the exposed method for this requestonly useful if you have filters that might change the object path.
Contains the original parameters in case they were modified by a filter on the way in.
"http" or "https" so you can tell whether the request came over a secure channel.
We've already mentioned that having the remote_addr and method information can be tremendously useful. We also saw simple_cookie used in Fast Track (Chapter 8). Many of the other attributes will only be used in unusual cases, but they are always there if you need them.
But, you can also store information specific to a particular request in the cherrypy.request object, and it will be automatically available anywhere you need it while processing that request. Table 17-2 lists each of the attributes of the cherry.response object. You can set these attributes to modify the response that will be sent to the user.
Table 17-2. cherrypy.response Object Attributes
Just like request.headers, but contains the headers that will be included in the response.
Contains a simple cookie object that behaves like a Python dictionary.
string or itterable
Contains the response string of the cherrypy method, or a generator that will produce the final HTTP output.
int or string
The HTTP response string, or an int that corresponds to the nummeric value of the response code.
The HTTP version that should be used in the response.