response.age is parsed as a timedelta. Previously, it was
incorrectly treated as a datetime. The header value is an integer
number of seconds, not a date string. (#414)

Fix a bug in TypeConversionDict where errors are not propagated
when using the converter. (#1102)

Authorization.qop is a string instead of a set, to comply with
RFC 2617. (#984)

An exception is raised when an encoded cookie is larger than, by
default, 4093 bytes. Browsers may silently ignore cookies larger than
this. BaseResponse has a new attribute max_cookie_size and
dump_cookie has a new argument max_size to configure this.
(#780, #1109)

Fix a TypeError in werkzeug.contrib.lint.GuardedIterator.close.
(#1116)

BaseResponse.calculate_content_length now correctly works for
Unicode responses on Python 3. It first encodes using
iter_encoded. (#705)

BuildErrors are now more informative. They come with a complete sentence
as error message, and also provide suggestions (pull request #691).

Fix a bug in the user agent parser where Safari’s build number instead of
version would be extracted (pull request #703).

Fixed issue where RedisCache set_many was broken for twemproxy, which doesn’t
support the default MULTI command (pull request #702).

mimetype parameters on request and response classes are now always
converted to lowercase.

Changed cache so that cache never expires if timeout is 0. This also fixes
an issue with redis setex (issue #550)

Werkzeug now assumes UTF-8 as filesystem encoding on Unix if Python
detected it as ASCII.

New optional has method on caches.

Fixed various bugs in parse_options_header (pull request #643).

If the reloader is enabled the server will now open the socket in the parent
process if this is possible. This means that when the reloader kicks in
the connection from client will wait instead of tearing down. This does
not work on all Python versions.

Implemented PIN based authentication for the debugger. This can optionally
be disabled but is discouraged. This change was necessary as it has been
discovered that too many people run the debugger in production.

Restored behavior of the data descriptor of the request class to pre 0.9
behavior. This now also means that .data and .get_data() have
different behavior. New code should use .get_data() always.

In addition to that there is now a flag for the .get_data() method that
controls what should happen with form data parsing and the form parser will
honor cached data. This makes dealing with custom form data more consistent.

Changed host lookup logic for forwarded hosts to allow lists of
hosts in which case only the first one is picked up.

Added wsgi.get_query_string, wsgi.get_path_info and
wsgi.get_script_name and made the wsgi.pop_path_info and
wsgi.peek_path_info functions perform unicode decoding. This
was necessary to avoid having to expose the WSGI encoding dance
on Python 3.

Added content_encoding and content_md5 to the request object’s
common request descriptor mixin.

added options and trace to the test client.

Overhauled the utilization of the input stream to be easier to use
and better to extend. The detection of content payload on the input
side is now more compliant with HTTP by detecting off the content
type header instead of the request method. This also now means that
the stream property on the request class is always available instead
of just when the parsing fails.

Added a favicon to the debugger which fixes problem with
state changes being triggered through a request to
/favicon.ico in Google Chrome. This should fix some
problems with Flask and other frameworks that use
context local objects on a stack with context preservation
on errors.

Fixed an issue with scrolling up in the debugger.

Fixed an issue with debuggers running on a different URL
than the URL root.

Fixed a problem with proxies not forwarding some rarely
used special methods properly.

Added a workaround to prevent the XSS protection from Chrome
breaking the debugger.

Skip redis tests if redis is not running.

Fixed a typo in the multipart parser that caused content-type
to not be picked up properly.

Add support for python-libmemcached to the Werkzeug cache abstraction
layer.

Improved url_decode() and url_encode() performance.

Fixed an issue where the SharedDataMiddleware could cause an
internal server error on weird paths when loading via pkg_resources.

Fixed an URL generation bug that caused URLs to be invalid if a
generated component contains a colon.

werkzeug.import_string() now works with partially set up
packages properly.

Disabled automatic socket switching for IPv6 on the development
server due to problems it caused.

Werkzeug no longer overrides the Date header when creating a
conditional HTTP response.

The routing system provides a method to retrieve the matching
methods for a given path.

The routing system now accepts a parameter to change the encoding
error behaviour.

The local manager can now accept custom ident functions in the
constructor that are forwarded to the wrapped local objects.

url_unquote_plus now accepts unicode strings again.

Fixed an issue with the filesystem session support’s prune
function and concurrent usage.

Fixed a problem with external URL generation discarding the port.

Added support for pylibmc to the Werkzeug cache abstraction layer.

Fixed an issue with the new multipart parser that happened when
a linebreak happened to be on the chunk limit.

Cookies are now set properly if ports are in use. A runtime error
is raised if one tries to set a cookie for a domain without a dot.

Fixed an issue with Template.from_file not working for file
descriptors.

Reloader can now use inotify to track reloads. This requires the
pyinotify library to be installed.

Werkzeug debugger can now submit to custom lodgeit installations.

redirect function’s status code assertion now allows 201 to be used
as redirection code. While it’s not a real redirect, it shares
enough with redirects for the function to still be useful.

Fixed securecookie for pypy.

Fixed ValueErrors being raised on calls to best_match on
MIMEAccept objects when invalid user data was supplied.

Deprecated werkzeug.contrib.kickstart and werkzeug.contrib.testtools

URL routing now can be passed the URL arguments to keep them for
redirects. In the future matching on URL arguments might also be
possible.

Header encoding changed from utf-8 to latin1 to support a port to
Python 3. Bytestrings passed to the object stay untouched which
makes it possible to have utf-8 cookies. This is a part where
the Python 3 version will later change in that it will always
operate on latin1 values.

Fixed a bug in the form parser that caused the last character to
be dropped off if certain values in multipart data are used.

Multipart parser now looks at the part-individual content type
header to override the global charset.

Introduced mimetype and mimetype_params attribute for the file
storage object.

Changed FileStorage filename fallback logic to skip special filenames
that Python uses for marking special files like stdin.

Introduced more HTTP exception classes.

call_on_close now can be used as a decorator.

Support for redis as cache backend.

Added BaseRequest.scheme.

Support for the RFC 5789 PATCH method.

New custom routing parser and better ordering.

Removed support for is_behind_proxy. Use a WSGI middleware
instead that rewrites the REMOTE_ADDR according to your setup.
Also see the werkzeug.contrib.fixers.ProxyFix for
a drop-in replacement.

Added cookie forging support to the test client.

Added support for host based matching in the routing system.

Switched from the default ‘ignore’ to the better ‘replace’
unicode error handling mode.

The builtin server now adds a function named ‘werkzeug.server.shutdown’
into the WSGI env to initiate a shutdown. This currently only works
in Python 2.6 and later.

Headers are now assumed to be latin1 for better compatibility with
Python 3 once we have support.

heavily improved local objects. Should pick up standalone greenlet
builds now and support proxies to free callables as well. There is
also a stacked local now that makes it possible to invoke the same
application from within itself by pushing current request/response
on top of the stack.

routing build method will also build non-default method rules properly
if no method is provided.

added proper IPv6 support for the builtin server.

windows specific filesystem session store fixes.
(should now be more stable under high concurrency)

fixed a NameError in the session system.

fixed a bug with empty arguments in the werkzeug.script system.

fixed a bug where log lines will be duplicated if an application uses
logging.basicConfig() (#499)

added secure password hashing and checking functions.

HEAD is now implicitly added as method in the routing system if
GET is present. Not doing that was considered a bug because often
code assumed that this is the case and in web servers that do not
normalize HEAD to GET this could break HEAD requests.

Response objects are no longer modified in place when they are evaluated
as WSGI applications. For backwards compatibility the fix_headers
function is still called in case it was overridden.
You should however change your application to use get_wsgi_headers if
you need header modifications before responses are sent as the backwards
compatibility support will go away in future versions.

append_slash_redirect() no longer requires the QUERY_STRING to be
in the WSGI environment.

moved LimitedStream from the contrib package into the regular
werkzeug one and changed the default behavior to raise exceptions
rather than stopping without warning. The old class will stick in
the module until 0.6.

implemented experimental multipart parser that replaces the old CGI hack.

added dump_options_header() and parse_options_header()

added quote_header_value() and unquote_header_value()

url_encode() and url_decode() now accept a separator
argument to switch between & and ; as pair separator. The magic
switch is no longer in place.

all form data parsing functions as well as the BaseRequest
object have parameters (or attributes) to limit the number of
incoming bytes (either totally or per field).

added LanguageAccept

request objects are now enforced to be read only for all collections.

added many new collection classes, refactored collections in general.

test support was refactored, semi-undocumented werkzeug.test.File
was replaced by werkzeug.FileStorage.

EnvironBuilder was added and unifies the previous distinct
create_environ(), Client and
BaseRequest.from_values(). They all work the same now which
is less confusing.

officially documented imports from the internal modules as undefined
behavior. These modules were never exposed as public interfaces.

removed FileStorage.__len__ which previously made the object
falsy for browsers not sending the content length which all browsers
do.

SharedDataMiddleware uses wrap_file now and has a
configurable cache timeout.

werkzeug.contrib.cache.Memcached accepts now objects that
implement the memcache.Client interface as alternative to a list of
strings with server addresses.
There is also now a GAEMemcachedCache that connects to the Google
appengine cache.

explicitly convert secret keys to bytestrings now because Python
2.6 no longer does that.

url_encode and all interfaces that call it, support ordering of
options now which however is disabled by default.

the development server no longer resolves the addresses of clients.

Fixed a typo in werkzeug.test that broke File.

Map.bind_to_environ uses the Host header now if available.

Fixed BaseCache.get_dict (#345)

werkzeug.test.Client can now run the application buffered in which
case the application is properly closed automatically.

fixed a bug in Response.application that made it impossible to use it
as method decorator.

the session system should work on appengine now

the secure cookie works properly in load balanced environments with
different cpu architectures now.

CacheControl.no_cache and CacheControl.private behavior changed to
reflect the possibilities of the HTTP RFC. Setting these attributes to
None or True now sets the value to “the empty value”.
More details in the documentation.

fixed werkzeug.contrib.atom.AtomFeed.__call__. (#338)

BaseResponse.make_conditional now always returns self. Previously
it didn’t for post requests and such.

fixed a bug in boolean attribute handling of html and xhtml.

added graceful error handling to the debugger pastebin feature.

added a more list like interface to Headers (slicing and indexing
works now)

fixed a bug with the __setitem__ method of Headers that didn’t
properly remove all keys on replacing.

added remove_entity_headers which removes all entity headers from
a list of headers (or a Headers object)

the responses now automatically call remove_entity_headers if the
status code is 304.

fixed a bug with Href query parameter handling. Previously the last
item of a call to Href was not handled properly if it was a dict.

headers now support a pop operation to better work with environ
properties.

Soft-deprecated the BaseRequest.data and
BaseResponse.data attributes and introduced new methods
to interact with entity data. This will allows in the future to
make better APIs to deal with request and response entity
bodies. So far there is no deprecation warning but users are
strongly encouraged to update.

The Headers and EnvironHeaders datastructures
are now designed to operate on unicode data. This is a backwards
incompatible change and was necessary for the Python 3 support.

The Headers object no longer supports in-place operations
through the old linked method. This has been removed without
replacement due to changes on the encoding model.

0.6.2

renamed the attribute implicit_seqence_conversion attribute of
the request object to implicit_sequence_conversion. Because
this is a feature that is typically unused and was only in there
for the 0.6 series we consider this a bug that does not require
backwards compatibility support which would be impossible to
properly implement.

BaseResponse.header_list was deprecated. You should not
need this function, get_wsgi_headers and the to_list
method on the regular headers should serve as a replacement.

Deprecated BaseResponse.iter_encoded’s charset parameter.

LimitedStream non-silent usage was deprecated.

the __repr__ of HTTP exceptions changed. This might break
doctests.

0.5

Werkzeug switched away from wsgiref as library for the builtin
webserver.

The encoding parameter for Templates is now called
charset. The older one will work for another two versions
but warn with a DeprecationWarning.

The Client has cookie support now which is enabled
by default.

BaseResponse._get_file_stream() is now passed more parameters
to make the function more useful. In 0.6 the old way to invoke
the method will no longer work. To support both newer and older
Werkzeug versions you can add all arguments to the signature and
provide default values for each of them.

url_decode() no longer supports both & and ; as
separator. This has to be specified explicitly now.

The request object is now enforced to be read-only for all
attributes. If your code relies on modifications of some values
makes sure to create copies of them using the mutable counterparts!

Some data structures that were only used on request objects are
now immutable as well. (Authorization / Accept
and subclasses)

CacheControl was split up into RequestCacheControl
and ResponseCacheControl, the former being immutable.
The old class will go away in 0.6

undocumented werkzeug.test.File was replaced by
FileWrapper.

it’s not longer possible to pass dicts inside the data dict
in Client. Use tuples instead.

It’s save to modify the return value of MultiDict.getlist()
and methods that return lists in the MultiDict now. The
class creates copies instead of revealing the internal lists.
However MultiDict.setlistdefault still (and intentionally)
returns the internal list for modifications.

0.3

Werkzeug 0.3 will be the last release with Python 2.3 compatibility.

The environ_property is now read-only by default. This decision was
made because the request in general should be considered read-only.

0.2

The BaseReporterStream is now part of the contrib module, the
new module is werkzeug.contrib.reporterstream. Starting with
0.3, the old import will not work any longer.

RequestRedirect now uses a 301 status code. Previously a 302
status code was used incorrectly. If you want to continue using
this 302 code, use response=redirect(e.new_url,302).

lazy_property is now called cached_property. The alias for
the old name will disappear in Werkzeug 0.3.

match can now raise MethodNotAllowed if configured for
methods and there was no method for that request.

The response_body attribute on the response object is now called
data. With Werkzeug 0.3 the old name will not work any longer.

The file-like methods on the response object are deprecated. If
you want to use the response object as file like object use the
Response class or a subclass of BaseResponse and mix the new
ResponseStreamMixin class and use response.stream.