Dispatching

web2py maps a URL of the form:

  1. http://127.0.0.1:8000/a/c/f.html

to the function f() in controller “c.py” in application “a”. If f is not present, web2py defaults to the index controller function. If c is not present, web2py defaults to the “default.py” controller, and if a is not present, web2py defaults to the init application. If there is no init application, web2py tries to run the welcome application. This is shown schematically in the image below:

image

By default, any new request also creates a new session. In addition, a session cookie is returned to the client browser to keep track of the session.

The extension .html is optional; .html is assumed as default. The extension determines the extension of the view that renders the output of the controller function f(). It allows the same content to be served in multiple formats (html, xml, json, rss, etc.).

Functions that take arguments or start with a double underscore are not publicly exposed and can only be called by other functions.

There is an exception made for URLs of the form:

  1. http://127.0.0.1:8000/a/static/filename

There is no controller called “static”. web2py interprets this as a request for the file called “filename” in the subfolder “static” of the application “a”.

When static files are downloaded, web2py does not create a session, nor does it issue a cookie or execute the models. web2py always streams static files in chunks of 1MB, and sends PARTIAL CONTENT when the client sends a RANGE request for a subset of the file.

web2py also supports the IF_MODIFIED_SINCE protocol, and does not send the file if it is already stored in the browser’s cache and if the file has not changed since that version.

When linking to an audio or video file in the static folder, if you want to force the browser to download the file instead of streaming the audio/video via a media player, add ?attachment to the URL. This tells web2py to set the Content-Disposition header of the HTTP response to “attachment”. For example:

  1. <a href="/app/static/my_audio_file.mp3?attachment">Download</a>

When the above link is clicked, the browser will prompt the user to download the MP3 file rather than immediately streaming the audio. (As discussed in response, you can also set HTTP response headers directly by assigning a dict of header names and their values to response.headers.)

web2py maps GET/POST requests of the form:

  1. http://127.0.0.1:8000/a/c/f.html/x/y/z?p=1&q=2

to function f in controller “c.py” in application a, and it stores the URL parameters in the request variable as follows:

  1. request.args = ['x', 'y', 'z']

and:

  1. request.vars = {'p': 1, 'q': 2}

and:

  1. request.application = 'a'
  2. request.controller = 'c'
  3. request.function = 'f'

In the above example, both request.args[i] and request.args(i) can be used to retrieve the i-th element of the request.args, but while the former raises an exception if the list does not have such an index, the latter returns None in this case.

  1. request.url

stores the full URL of the current request (not including GET variables).

  1. request.ajax

defaults False but it is True if web2py determines that the action was called by an Ajax request.

If the request is an Ajax request and it is initiated by a web2py component, the name of the component can be found in:

  1. request.cid

Components are discussed in more detail in Chapter 12.

If the HTTP request is a GET, then request.env.request_method is set to “GET”; if it is a POST, request.env.request_method is set to “POST”. URL query variables are stored in request.get_vars. request.post_vars contains all parameters passed into the body of a request (usually a POST, PUT or a DELETE one). The request.vars Storage dictionary contains both of them (get_vars and post_vars get merged)

web2py stores WSGI and web2py environment variables in request.env, for example:

  1. request.env.path_info = 'a/c/f'

and HTTP headers into environment variables, for example:

  1. request.env.http_host = '127.0.0.1:8000'

Notice that web2py validates all URLs to prevent directory traversal attacks.

URLs are only allowed to contain alphanumeric characters, underscores, and slashes; the args may contain non-consecutive dots. Spaces are replaced by underscores before validation. If the URL syntax is invalid, web2py returns an HTTP 400 error message[http-w] [http-o] .

If the URL corresponds to a request for a static file, web2py simply reads and returns (streams) the requested file.

If the URL does not request a static file, web2py processes the request in the following order:

  • Parses cookies.
  • Creates an environment in which to execute the function.
  • Initializes request, response, cache.
  • Opens the existing session or creates a new one.
  • Executes the models belonging to the requested application.
  • Executes the requested controller action function.
  • If the function returns a dictionary, executes the associated view.
  • On success, commits all open transactions.
  • Saves the session.
  • Returns an HTTP response.

Notice that the controller and the view are executed in different copies of the same environment; therefore, the view does not see the controller, but it sees the models and it sees the variables returned by the controller action function.

If an exception (other than HTTP) is raised, web2py does the following:

  • Stores the traceback in an error file and assigns a ticket number to it.
  • Rolls back all open database transactions.
  • Returns an error page reporting the ticket number.

If the exception is an HTTP exception, this is assumed to be the intended behavior (for example, an HTTP redirect), and all open database transactions are committed. The behavior after that is specified by the HTTP exception itself. The HTTP exception class is not a standard Python exception; it is defined by web2py.