Fix disconnect detection being incorrect in some cases (issue 21)
Fix exception when calling .accept.best_match(..) on a header containing
‘*’ (instead of ‘/‘)
Split Accept class into appropriate subclasses (AcceptCharset,
AcceptLanguage)
Improve language matching code so that 'en'inAcceptLanguage('en-gb')
(the app can now offer a generic ‘en’ and it will match any of the
accepted dialects) and 'en_GB'inAcceptLanguage('en-gb') (normalization
of the dash/underscode in language names).
Deprecate req.etag.weak_match(..)
Deprecate Response.request and Response.environ attrs.
Add detection for browser / user-agent disconnects. If the client disconnected
before sending the entire request body (POST / PUT), req.POST, req.body
and other related properties and methods will raise an exception.
Previously this caused the application get a truncated request with no indication that it
is incomplete.
Make Response.body_file settable. This is now valid:
Response(body_file=open('foo.bin'),content_type=...)
Revert the restriction on req.body not being settable for GET and some
other requests. Such requests actually can have a body according to HTTP BIS
(see also commit message)
Add support for file upload testing via Request.blank(POST=..). Patch contributed by
Tim Perevezentsev. See also:
ticket,
changeset.
Deprecate req.str_GET, str_POST, str_params and str_cookies (warning).
Deprecate req.decode_param_names (warning).
Change req.decode_param_names default to True. This means that .POST, .GET,
.params and .cookies keys are now unicode. This is necessary for WebOb to behave
as close as possible on Python 2 and Python 3.
Use environ['wsgi.input'].read() instead of .read(-1) because the former
is explicitly mentioned in PEP-3333 and CherryPy server does not support the latter.
Add new environ['webob.is_body_readable'] flag which specifies if the
input stream is readable even if the CONTENT_LENGTH is not set.
WebOb now only ever reads the input stream if the content-length is known
or this flag is set.
The two changes above fix a hangup with CherryPy and wsgiref servers
(issue 6)
req.body_file is now safer to read directly. For GET and other similar requests
it returns an empty StringIO or BytesIO object even if the server passed in
something else.
Setting req.body_file to a string now produces a PendingDeprecationWarning.
It will produce DeprecationWarning in 1.1 and raise an error in 1.2. Either
set req.body_file to a file-like object or set req.body to a string value.
Fix .pop() and .setdefault(..) methods of req/resp.cache_control
The field names escaping bug semi-fixed in 1.0.3 and originally blamed on cgi module
was in fact a webob.request._encode_multipart bug (also in Google Chrome) and was
lurking in webob code for quite some time – 1.0.2 just made it trigger more often.
Now it is fixed properly.
Make sure that req.url and related properties do not unnecessarily escape some chars
(:@&+$) in the URI path (issue 5)
Revert some changes from 1.0.3 that have broken backwards compatibility for some apps.
Getting req.body_file does not make input stream seekable, but there’s a new property
req.body_file_seekable that does.
Request.get_response and Request.call_application seek the input body to start
before calling the app (if possible).
Accessing req.body ‘rewinds’ the input stream back to pos 0 as well.
When accessing req.POST we now avoid making the body seekable as the input stream data
are preserved in FakeCGIBody anyway.
Add new method Request.from_string.
Make sure Request.as_string() uses CRLF to separate headers.
Improve parity between Request.as_string() and .from_file/.from_string
methods, so that the latter can parse output of the former and create a similar
request object which wasn’t always the case previously.
Correct a caching issue introduced in WebOb 1.0.2 that was causing unnecessary reparsing
of POST requests.
Fix a bug regarding field names escaping for forms submitted as multipart/form-data.
For more infromation see the bug report and discussion and 1.0.4 notes for further fix.
WebOb 1.0.1 changed the behavior of MultiDict.update to be more in line with
other dict-like objects. We now also issue a warning when we detect that the
client code seems to expect the old, extending semantics.
Make Response.set_cookie(key,None) set the ‘delete-cookie’ (same as .delete_cookie(key))
Make req.upath_info and req.uscript_name settable
Add :meth:Request.as_string() method
Add a req.is_body_seekable property
Support for the deflate method with resp.decode_content()
To better conform to WSGI spec we no longer attempt to use seek on wsgi.input file
instead we assume it is not seekable unless env['webob.is_body_seekable'] is set.
When making the body seekable we set that flag.
A call to req.make_body_seekable() now guarantees that the body is seekable, is at 0 position
and that a correct req.content_length is present.
req.body_file is always seekable. To access env['wsgi.input'] without any processing,
use req.body_file_raw. (Partially reverted in 1.0.4)
Drop util.safezip module and make util a module instead of a subpackage.
Merge statusreasons into it.
Instead of using stdlib Cookie with monkeypatching, add a derived
but thoroughly rewritten, cleaner, safer and faster webob.cookies module.
Fix: Response.merge_cookies now copies the headers before modification instead of
doing it in-place.
Fix: setting request header attribute to None deletes that header.
(Bug only affected the 1.0 release).
Use io.BytesIO for the request body file on Python 2.7 and newer.
If a UnicodeMultiDict was used as the multi argument of another
UnicodeMultiDict, and a cgi.FieldStorage with a filename
with high-order characters was present in the underlying
UnicodeMultiDict, a UnicodeEncodeError would be raised when any
helper method caused the _decode_value method to be called,
because the method would try to decode an already decoded string.
Fix tests to pass under Python 2.4.
Add descriptive docstrings to each exception in webob.exc.
Change the behaviour of MultiDict.update to overwrite existing header
values instead of adding new headers. The extending semantics are now available
via the extend method.
Fix a bug in webob.exc.WSGIHTTPException.__init__. If a list of
headers was passed as a sequence which contained duplicate keys (for
example, multiple Set-Cookie headers), all but one of those headers
would be lost, because the list was effectively flattened into a dictionary
as the result of calling self.headers.update. Fixed via calling
self.headers.extend instead.
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).
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).
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 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).
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-200115:34:10GMT (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)
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.
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.
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).
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.