News

0.9.8

  • Fix issue with WSGIHTTPException inadvertently generating unicode body and failing to encode it
  • WWW-Authenticate response header is accessible as response.www_authenticate
  • response.www_authenticate and request.authorization hold None or tuple (auth_method, params) where params is a dictionary (or a string when auth_method is not one of known auth schemes and for Authenticate: Basic ...)
  • Don’t share response headers when getting a response like resp = req.get_response(some_app); this can avoid some funny errors with modifying headers and reusing Response objects.
  • Add overwrite argument to Response.set_cookie() that make the new value overwrite the previously set. False by default.
  • Add strict argument to Response.unset_cookie() that controls if an exception should be raised in case there are no cookies to unset. True by default.
  • Fix req.GET.copy()
  • Make sure that 304 Not Modified responses generated by Response.conditional_response_app() exclude Content-{Length/Type} headers
  • Fix Response.copy() not being an independent copy
  • When the requested range is not satisfiable, return a 416 error (was returning entire body)
  • Truncate response for range requests that go beyond the end of body (was treating as invalid).

0.9.7.1

  • Fix an import problem with Pylons

0.9.7

  • Moved repository from svn location to http://bitbucket.org/ianb/webob/
  • Arguments to Accept.best_match() must be specific types, not wildcards. The server should know a list of specic types it can offer and use best_match to select a specific one.
  • With req.accept.best_match([types]) prefer the first type in the list (previously it preferred later types).
  • Also, make sure that if the user-agent accepts multiple types and there are multiple matches to the types that the application offers, req.accept.best_match([..]) returns the most specific match. So if the server can satisfy either image/* or text/plain types, the latter will be picked independent from the order the accepted or offered types are listed (given they have the same quality rating).
  • Fix Range, Content-Range and AppIter support all of which were broken in many ways, incorrectly parsing ranges, reporting incorrect content-ranges, failing to generate the correct body to satisfy the range from app_iter etc.
  • Fix assumption that presense of a seek method means that the stream is seekable.
  • Add ubody alias for Response.unicode_body
  • Add Unicode versions of Request.script_name and path_info: uscript_name and upath_info.
  • Split __init__.py into four modules: request, response, descriptors and datetime_utils.
  • Fix Response.body access resetting Content-Length to zero for HEAD responses.
  • Support passing Unicode bodies to WSGIHTTPException constructors.
  • Make bool(req.accept) return False for requests with missing Accept header.
  • Add HTTP version to Request.__str__() output.
  • Resolve deprecation warnings for parse_qsl on Python 2.6 and newer.
  • Fix Response.md5_etag() setting Content-MD5 in incorrect format.
  • Add Request.authorization property for Authorization header.
  • Make sure ETag value is always quoted (required by RFC)
  • Moved most Request behavior into a new class named BaseRequest. The Request class is now a superclass for BaseRequest and a simple mixin which manages environ['webob.adhoc_attrs'] when __setitem__, __delitem__ and __getitem__ are called. This allows framework developers who do not want the environ['webob.adhoc_attrs'] mutation behavior from __setattr__. (chrism)
  • Added response attribute response.content_disposition for its associated header.
  • Changed how charset is determined on webob.Request objects. Now the charset parameter is read on the Content-Type header, if it is present. Otherwise a default_charset parameter is read, or the charset argument to the Request constructor. This is more similar to how webob.Response handles the charset.
  • Made the case of the Content-Type header consistent (note: this might break some doctests).
  • Make req.GET settable, such that req.environ['QUERY_STRING'] is updated.
  • Fix problem with req.POST causing a re-parse of the body when you instantiate multiple Request objects over the same environ (e.g., when using middleware that looks at req.POST).
  • Recreate the request body properly when a POST includes file uploads.
  • When req.POST is updated, the generated body will include the new values.
  • Added a POST parameter to webob.Request.blank(); when given this will create a request body for the POST parameters (list of two-tuples or dictionary-like object). Note: this does not handle unicode or file uploads.
  • Added method webob.Response.merge_cookies(), which takes the Set-Cookie headers from a Response, and merges them with another response or WSGI application. (This is useful for flash messages.)
  • Fix a problem with creating exceptions like webob.exc.HTTPNotFound(body='<notfound/>', content_type='application/xml') (i.e., non-HTML exceptions).
  • When a Location header is not absolute in a Response, it will be made absolute when the Response is called as a WSGI application. This makes the response less bound to a specific request.
  • Added webob.dec, a decorator for making WSGI applications from functions with the signature resp = app(req).

0.9.6.1

  • Fixed Response.__init__(), which for some content types would raise an exception.
  • The req.body property will not recreate a StringIO object unnecessarily when rereading the body.

0.9.6

  • Removed environ_getter from webob.Request. This largely-unused option allowed a Request object to be instantiated with a dynamic underlying environ. Since it wasn’t used much, and might have been ill-advised from the beginning, and affected performance, it has been removed (from Chris McDonough).
  • Speed ups for webob.Response.__init__() and webob.Request.__init__()
  • Fix defaulting of CONTENT_TYPE instead of CONTENT_LENGTH to 0 in Request.str_POST.
  • Added webob.Response.copy()

0.9.5

  • Fix Request.blank('/').copy() raising an exception.
  • Fix a potential memory leak with HEAD requests and 304 responses.
  • Make webob.html_escape() respect the .__html__() magic method, which allows you to use HTML in :class`webob.exc.HTTPException` instances.
  • Handle unicode values for resp.location.
  • Allow arbitrary keyword arguments to exc.HTTP* (the same keywords you can send to webob.Response).
  • Allow setting webob.Response.cache_expires() (usually it is called as a method). This is primarily to allow Response(cache_expires=True).

0.9.4

  • Quiet Python 2.6 deprecation warnings.
  • Added an attribute unicode_errors to webob.Response – if set to something like unicode_errors='replace' it will decode resp.body appropriately. The default is strict (which was the former un-overridable behavior).

0.9.3

  • Make sure that if changing the body the Content-MD5 header is removed. (Otherwise a lot of middleware would accidentally corrupt responses).
  • Fixed Response.encode_content('identity') case (was a no-op even for encoded bodies).
  • Fixed Request.remove_conditional_headers() that was removing If-Match header instead of If-None-Match.
  • Fixed resp.set_cookie(max_age=timedelta(...))
  • request.POST now supports PUT requests with the appropriate Content-Type.

0.9.2

  • Add more arguments to Request.remove_conditional_headers() for more fine-grained control: remove_encoding, remove_range, remove_match, remove_modified. All of them are True by default.
  • Add an set_content_md5 argument to Response.md5_etag() that calculates and sets Content-MD5 reponse header from current body.
  • Change formatting of cookie expires, to use the more traditional format Wed, 5-May-2001 15:34:10 GMT (dashes instead of spaces). Browsers should deal with either format, but some other code expects dashes.
  • Added in sorted function for backward compatibility with Python 2.3.
  • Allow keyword arguments to webob.Request, which assign attributes (possibly overwriting values in the environment).
  • Added methods webob.Request.make_body_seekable() and webob.Request.copy_body(), which make it easier to share a request body among different consuming applications, doing something like req.make_body_seekable(); req.body_file.seek(0)

0.9.1

  • request.params.copy() now returns a writable MultiDict (before it returned an unwritable object).
  • There were several things broken with UnicodeMultiDict when decode_param_names is turned on (when the dictionary keys are unicode).
  • You can pass keyword arguments to Request.blank() that will be used to construct Request (e.g., Request.blank('/', decode_param_names=True)).
  • If you set headers like response.etag to a unicode value, they will be encoded as ISO-8859-1 (however, they will remain encoded, and response.etag will not be a unicode value).
  • When parsing, interpret times with no timezone as UTC (previously they would be interpreted as local time).
  • Set the Expires property on cookies when using response.set_cookie(). This is inherited from max_age.
  • Support Unicode cookie values

0.9

  • Added req.urlarg, which represents positional arguments in environ['wsgiorg.routing_args'].
  • For Python 2.4, added attribute get/set proxies on exception objects from, for example, webob.exc.HTTPNotFound().exception, so that they act more like normal response objects (despite not being new-style classes or webob.Response objects). In Python 2.5 the exceptions are webob.Response objects.

Backward Incompatible Changes

  • The Response constructor has changed: it is now Response([body], [status], ...) (before it was Response([status], [body], ...)). Body may be str or unicode.
  • The Response class defaults to text/html for the Content-Type, and utf8 for the charset (charset is only set on text/* and application/*+xml responses).

Bugfixes and Small Changes

  • Use BaseCookie instead of SimpleCookie for parsing cookies.
  • Added resp.write(text) method, which is equivalent to resp.body += text or resp.unicode_body += text, depending on the type of text.
  • The decode_param_names argument (used like Request(decode_param_names=True)) was being ignored.
  • Unicode decoding of file uploads and file upload filenames were causing errors when decoding non-file-upload fields (both fixes from Ryan Barrett).

0.8.5

  • Added response methods resp.encode_content() and resp.decode_content() to gzip or ungzip content.
  • Response(status=404) now works (before you would have to use status="404 Not Found").
  • Bugfix (typo) with reusing POST body.
  • Added 226 IM Used response status.
  • Backport of string.Template included for Python 2.3 compatibility.

0.8.4

  • __setattr__ would keep Request subclasses from having properly settable environ proxies (like req.path_info).

0.8.3

  • request.POST was giving FieldStorage objects for every attribute, not just file uploads. This is fixed now.
  • Added request attributes req.server_name and req.server_port for the environ keys SERVER_NAME and SERVER_PORT.
  • Avoid exceptions in req.content_length, even if environ['CONTENT_LENGTH'] is somehow invalid.

0.8.2

  • Python 2.3 compatibility: backport of reversed(seq)
  • Made separate .exception attribute on webob.exc objects, since new-style classes can’t be raised as exceptions.
  • Deprecate req.postvars and req.queryvars, instead using the sole names req.GET and req.POST (also req.str_GET and req.str_POST). The old names give a warning; will give an error in next release, and be completely gone in the following release.
  • req.user_agent is now just a simple string (parsing the User-Agent header was just too volatile, and required too much knowledge about current browsers). Similarly, req.referer_search_query() is gone.
  • Added parameters version and comment to Response.set_cookie(), per William Dode’s suggestion.
  • Was accidentally consuming file uploads, instead of putting the FieldStorage object directly in the parameters.

0.8.1

  • Added res.set_cookie(..., httponly=True) to set the HttpOnly attribute on the cookie, which keeps Javascript from reading the cookie.
  • Added some WebDAV-related responses to webob.exc
  • Set default Last-Modified when using response.cache_expire() (fixes issue with Opera)
  • Generally fix .cache_control

0.8

First release. Nothing is new, or everything is new, depending on how you think about it.

Table Of Contents

Previous topic

Another Do-It-Yourself Framework

Next topic

License

This Page