Back to index

moin  1.9.0~rc2
Functions | Variables
MoinMoin.support.werkzeug.http Namespace Reference

Functions

def quote_header_value
def unquote_header_value
def dump_options_header
def dump_header
def parse_list_header
def parse_dict_header
def parse_options_header
def parse_accept_header
def parse_cache_control_header
def parse_set_header
def parse_authorization_header
def parse_www_authenticate_header
def quote_etag
def unquote_etag
def parse_etags
def generate_etag
def parse_date
def default_stream_factory
def _make_stream_factory
def _fix_ie_filename
def _line_parse
def parse_multipart
def parse_multipart_headers
def is_resource_modified
def remove_entity_headers
def remove_hop_by_hop_headers
def is_entity_header
def is_hop_by_hop_header
def is_valid_multipart_boundary

Variables

tuple _accept_re = re.compile(r'([^\s;,]+)(?:[^,]*?;\s*q=(\d*(?:\.\d+)?))?')
tuple _token_chars
tuple _etag_re = re.compile(r'([Ww]/)?(?:"(.*?)"|(.*?))(?:\s*,\s*|$)')
tuple _multipart_boundary_re = re.compile('^[ -~]{0,200}[!-~]$')
tuple _entity_headers
tuple _hop_by_pop_headers
tuple _supported_multipart_encodings = frozenset(['base64', 'quoted-printable'])

Function Documentation

Internet Explorer 6 transmits the full file name if a file is
uploaded.  This function strips the full path if it thinks the
filename is Windows-like absolute.

Definition at line 466 of file http.py.

00466 
00467 def _fix_ie_filename(filename):
00468     """Internet Explorer 6 transmits the full file name if a file is
00469     uploaded.  This function strips the full path if it thinks the
00470     filename is Windows-like absolute.
00471     """
00472     if filename[1:3] == ':\\' or filename[:2] == '\\\\':
00473         return filename.split('\\')[-1]
00474     return filename
00475 

Here is the caller graph for this function:

Removes line ending characters and returns a tuple (`stripped_line`,
`is_terminated`).

Definition at line 476 of file http.py.

00476 
00477 def _line_parse(line):
00478     """Removes line ending characters and returns a tuple (`stripped_line`,
00479     `is_terminated`).
00480     """
00481     if line[-2:] == '\r\n':
00482         return line[:-2], True
00483     elif line[-1:] in '\r\n':
00484         return line[:-1], True
00485     return line, False
00486 

Here is the call graph for this function:

Here is the caller graph for this function:

this exists for backwards compatibility!, will go away in 0.6.

Definition at line 452 of file http.py.

00452 
00453 def _make_stream_factory(factory):
00454     """this exists for backwards compatibility!, will go away in 0.6."""
00455     args, _, _, defaults = inspect.getargspec(factory)
00456     required_args = len(args) - len(defaults or ())
00457     if inspect.ismethod(factory):
00458         required_args -= 1
00459     if required_args != 0:
00460         return factory
00461     from warnings import warn
00462     warn(DeprecationWarning('stream factory passed to `parse_form_data` '
00463                             'uses deprecated invokation API.'), stacklevel=4)
00464     return lambda *a: factory()
00465 

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.default_stream_factory (   total_content_length,
  filename,
  content_type,
  content_length = None 
)
The stream factory that is used per default.

Definition at line 445 of file http.py.

00445 
00446                            content_length=None):
00447     """The stream factory that is used per default."""
00448     if total_content_length > 1024 * 500:
00449         return TemporaryFile('wb+')
00450     return StringIO()
00451 

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.dump_header (   iterable,
  allow_token = True 
)
Dump an HTTP header again.  This is the reversal of
:func:`parse_list_header`, :func:`parse_set_header` and
:func:`parse_dict_header`.  This also quotes strings that include an
equals sign unless you pass it as dict of key, value pairs.

:param iterable: the iterable or dict of values to quote.
:param allow_token: if set to `False` tokens as values are disallowed.
                    See :func:`quote_header_value` for more details.

Definition at line 112 of file http.py.

00112 
00113 def dump_header(iterable, allow_token=True):
00114     """Dump an HTTP header again.  This is the reversal of
00115     :func:`parse_list_header`, :func:`parse_set_header` and
00116     :func:`parse_dict_header`.  This also quotes strings that include an
00117     equals sign unless you pass it as dict of key, value pairs.
00118 
00119     :param iterable: the iterable or dict of values to quote.
00120     :param allow_token: if set to `False` tokens as values are disallowed.
00121                         See :func:`quote_header_value` for more details.
00122     """
00123     if isinstance(iterable, dict):
00124         items = []
00125         for key, value in iterable.iteritems():
00126             if value is None:
00127                 items.append(key)
00128             else:
00129                 items.append('%s=%s' % (
00130                     key,
00131                     quote_header_value(value, allow_token=allow_token)
00132                 ))
00133     else:
00134         items = [quote_header_value(x, allow_token=allow_token)
00135                  for x in iterable]
00136     return ', '.join(items)
00137 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.dump_options_header (   header,
  options 
)
The reverse function to :func:`parse_options_header`.

:param header: the header to dump
:param options: a dict of options to append.

Definition at line 95 of file http.py.

00095 
00096 def dump_options_header(header, options):
00097     """The reverse function to :func:`parse_options_header`.
00098 
00099     :param header: the header to dump
00100     :param options: a dict of options to append.
00101     """
00102     segments = []
00103     if header is not None:
00104         segments.append(header)
00105     for key, value in options.iteritems():
00106         if value is None:
00107             segments.append(key)
00108         else:
00109             segments.append('%s=%s' % (key, quote_header_value(value)))
00110     return '; '.join(segments)
00111 

Here is the call graph for this function:

Here is the caller graph for this function:

Generate an etag for some data.

Definition at line 405 of file http.py.

00405 
00406 def generate_etag(data):
00407     """Generate an etag for some data."""
00408     return md5(data).hexdigest()
00409 

Here is the caller graph for this function:

Check if a header is an entity header.

.. versionadded:: 0.5

:param header: the header to test.
:return: `True` if it's an entity header, `False` otherwise.

Definition at line 716 of file http.py.

00716 
00717 def is_entity_header(header):
00718     """Check if a header is an entity header.
00719 
00720     .. versionadded:: 0.5
00721 
00722     :param header: the header to test.
00723     :return: `True` if it's an entity header, `False` otherwise.
00724     """
00725     return header.lower() in _entity_headers
00726 

Here is the caller graph for this function:

Check if a header is an HTTP/1.1 "Hop-by-Hop" header.

.. versionadded:: 0.5

:param header: the header to test.
:return: `True` if it's an entity header, `False` otherwise.

Definition at line 727 of file http.py.

00727 
00728 def is_hop_by_hop_header(header):
00729     """Check if a header is an HTTP/1.1 "Hop-by-Hop" header.
00730 
00731     .. versionadded:: 0.5
00732 
00733     :param header: the header to test.
00734     :return: `True` if it's an entity header, `False` otherwise.
00735     """
00736     return header.lower() in _hop_by_pop_headers
00737 

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.is_resource_modified (   environ,
  etag = None,
  data = None,
  last_modified = None 
)
Convenience method for conditional requests.

:param environ: the WSGI environment of the request to be checked.
:param etag: the etag for the response for comparision.
:param data: or alternatively the data of the response to automatically
             generate an etag using :func:`generate_etag`.
:param last_modified: an optional date of the last modification.
:return: `True` if the resource was modified, otherwise `False`.

Definition at line 654 of file http.py.

00654 
00655 def is_resource_modified(environ, etag=None, data=None, last_modified=None):
00656     """Convenience method for conditional requests.
00657 
00658     :param environ: the WSGI environment of the request to be checked.
00659     :param etag: the etag for the response for comparision.
00660     :param data: or alternatively the data of the response to automatically
00661                  generate an etag using :func:`generate_etag`.
00662     :param last_modified: an optional date of the last modification.
00663     :return: `True` if the resource was modified, otherwise `False`.
00664     """
00665     if etag is None and data is not None:
00666         etag = generate_etag(data)
00667     elif data is not None:
00668         raise TypeError('both data and etag given')
00669     if environ['REQUEST_METHOD'] not in ('GET', 'HEAD'):
00670         return False
00671 
00672     unmodified = False
00673     if isinstance(last_modified, basestring):
00674         last_modified = parse_date(last_modified)
00675     modified_since = parse_date(environ.get('HTTP_IF_MODIFIED_SINCE'))
00676 
00677     if modified_since and last_modified and last_modified <= modified_since:
00678         unmodified = True
00679     if etag:
00680         if_none_match = parse_etags(environ.get('HTTP_IF_NONE_MATCH'))
00681         if if_none_match:
00682             unmodified = if_none_match.contains_raw(etag)
00683 
00684     return not unmodified
00685 

Here is the call graph for this function:

Here is the caller graph for this function:

Checks if the string given is a valid multipart boundary.

Definition at line 738 of file http.py.

00738 
00739 def is_valid_multipart_boundary(boundary):
00740     """Checks if the string given is a valid multipart boundary."""
00741     return _multipart_boundary_re.match(boundary) is not None
00742 
00743 
# circular dependency fun

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.parse_accept_header (   value,
  cls = None 
)
Parses an HTTP Accept-* header.  This does not implement a complete
valid algorithm but one that supports at least value and quality
extraction.

Returns a new :class:`Accept` object (basically a list of ``(value, quality)``
tuples sorted by the quality with some additional accessor methods).

The second parameter can be a subclass of :class:`Accept` that is created
with the parsed values and returned.

:param value: the accept header string to be parsed.
:param cls: the wrapper class for the return value (can be
                     :class:`Accept` or a subclass thereof)
:return: an instance of `cls`.

Definition at line 217 of file http.py.

00217 
00218 def parse_accept_header(value, cls=None):
00219     """Parses an HTTP Accept-* header.  This does not implement a complete
00220     valid algorithm but one that supports at least value and quality
00221     extraction.
00222 
00223     Returns a new :class:`Accept` object (basically a list of ``(value, quality)``
00224     tuples sorted by the quality with some additional accessor methods).
00225 
00226     The second parameter can be a subclass of :class:`Accept` that is created
00227     with the parsed values and returned.
00228 
00229     :param value: the accept header string to be parsed.
00230     :param cls: the wrapper class for the return value (can be
00231                          :class:`Accept` or a subclass thereof)
00232     :return: an instance of `cls`.
00233     """
00234     if cls is None:
00235         cls = Accept
00236 
00237     if not value:
00238         return cls(None)
00239 
00240     result = []
00241     for match in _accept_re.finditer(value):
00242         quality = match.group(2)
00243         if not quality:
00244             quality = 1
00245         else:
00246             quality = max(min(float(quality), 1), 0)
00247         result.append((match.group(1), quality))
00248     return cls(result)
00249 

Here is the caller graph for this function:

Parse an HTTP basic/digest authorization header transmitted by the web
browser.  The return value is either `None` if the header was invalid or
not given, otherwise an :class:`Authorization` object.

:param value: the authorization header to parse.
:return: a :class:`Authorization` object or `None`.

Definition at line 288 of file http.py.

00288 
00289 def parse_authorization_header(value):
00290     """Parse an HTTP basic/digest authorization header transmitted by the web
00291     browser.  The return value is either `None` if the header was invalid or
00292     not given, otherwise an :class:`Authorization` object.
00293 
00294     :param value: the authorization header to parse.
00295     :return: a :class:`Authorization` object or `None`.
00296     """
00297     if not value:
00298         return
00299     try:
00300         auth_type, auth_info = value.split(None, 1)
00301         auth_type = auth_type.lower()
00302     except ValueError:
00303         return
00304     if auth_type == 'basic':
00305         try:
00306             username, password = auth_info.decode('base64').split(':', 1)
00307         except Exception, e:
00308             return
00309         return Authorization('basic', {'username': username,
00310                                        'password': password})
00311     elif auth_type == 'digest':
00312         auth_map = parse_dict_header(auth_info)
00313         for key in 'username', 'realm', 'nonce', 'uri', 'nc', 'cnonce', \
00314                    'response':
00315             if not key in auth_map:
00316                 return
00317         return Authorization('digest', auth_map)
00318 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.parse_cache_control_header (   value,
  on_update = None,
  cls = None 
)
Parse a cache control header.  The RFC differs between response and
request cache control, this method does not.  It's your responsibility
to not use the wrong control statements.

.. versionadded:: 0.5
   The `cls` was added.  If not specified an immutable
   :class:`RequestCacheControl` is returned.

:param value: a cache control header to be parsed.
:param on_update: an optional callable that is called every time a
                  value on the :class:`CacheControl` object is changed.
:param cls: the class for the returned object.  By default
                            :class:`RequestCacheControl` is used.
:return: a `cls` object.

Definition at line 250 of file http.py.

00250 
00251 def parse_cache_control_header(value, on_update=None, cls=None):
00252     """Parse a cache control header.  The RFC differs between response and
00253     request cache control, this method does not.  It's your responsibility
00254     to not use the wrong control statements.
00255 
00256     .. versionadded:: 0.5
00257        The `cls` was added.  If not specified an immutable
00258        :class:`RequestCacheControl` is returned.
00259 
00260     :param value: a cache control header to be parsed.
00261     :param on_update: an optional callable that is called every time a
00262                       value on the :class:`CacheControl` object is changed.
00263     :param cls: the class for the returned object.  By default
00264                                 :class:`RequestCacheControl` is used.
00265     :return: a `cls` object.
00266     """
00267     if cls is None:
00268         cls = RequestCacheControl
00269     if not value:
00270         return cls(None, on_update)
00271     return cls(parse_dict_header(value), on_update)
00272 

Here is the call graph for this function:

Here is the caller graph for this function:

Parse one of the following date formats into a datetime object:

.. sourcecode:: text

    Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
    Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
    Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format

If parsing fails the return value is `None`.

:param value: a string with a supported date format.
:return: a :class:`datetime.datetime` object.

Definition at line 410 of file http.py.

00410 
00411 def parse_date(value):
00412     """Parse one of the following date formats into a datetime object:
00413 
00414     .. sourcecode:: text
00415 
00416         Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
00417         Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
00418         Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
00419 
00420     If parsing fails the return value is `None`.
00421 
00422     :param value: a string with a supported date format.
00423     :return: a :class:`datetime.datetime` object.
00424     """
00425     if value:
00426         t = parsedate_tz(value.strip())
00427         if t is not None:
00428             # if no timezone is part of the string we assume UTC
00429             if t[-1] is None:
00430                 t = t[:-1] + (0,)
00431             try:
00432                 return datetime.utcfromtimestamp(mktime_tz(t))
00433             except (OverflowError, ValueError):
00434                 # XXX Exception handler added by MoinMoin development:
00435                 # catch exceptions raised by the stdlib functions if they receive far-off or invalid values.
00436                 # This can happen if a user agent transmits a broken if-modified-since header:
00437                 # 'HTTP_IF_MODIFIED_SINCE': 'Mon, 23 Jan 3115 29:41:44 GMT'
00438                 # 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5'
00439                 # TODO: remove this patch if we require a werkzeug version > 0.5.1
00440                 # that has an official fix for this problem.
00441                 # related werkzeug ticket: http://dev.pocoo.org/projects/werkzeug/ticket/432
00442                 return None  # just tell we can't parse this
00443 

Here is the call graph for this function:

Here is the caller graph for this function:

Parse lists of key, value pairs as described by RFC 2068 Section 2 and
convert them into a python dict.  If there is no value for a key it will
be `None`.

:param value: a string with a dict header.
:return: dict

Definition at line 157 of file http.py.

00157 
00158 def parse_dict_header(value):
00159     """Parse lists of key, value pairs as described by RFC 2068 Section 2 and
00160     convert them into a python dict.  If there is no value for a key it will
00161     be `None`.
00162 
00163     :param value: a string with a dict header.
00164     :return: dict
00165     """
00166     result = {}
00167     for item in _parse_list_header(value):
00168         if '=' not in item:
00169             result[item] = None
00170             continue
00171         name, value = item.split('=', 1)
00172         if value[:1] == value[-1:] == '"':
00173             value = unquote_header_value(value[1:-1])
00174         result[name] = value
00175     return result
00176 

Here is the call graph for this function:

Here is the caller graph for this function:

Parse an etag header.

:param value: the tag header to parse
:return: an :class:`ETags` object.

Definition at line 376 of file http.py.

00376 
00377 def parse_etags(value):
00378     """Parse an etag header.
00379 
00380     :param value: the tag header to parse
00381     :return: an :class:`ETags` object.
00382     """
00383     if not value:
00384         return ETags()
00385     strong = []
00386     weak = []
00387     end = len(value)
00388     pos = 0
00389     while pos < end:
00390         match = _etag_re.match(value, pos)
00391         if match is None:
00392             break
00393         is_weak, quoted, raw = match.groups()
00394         if raw == '*':
00395             return ETags(star_tag=True)
00396         elif quoted:
00397             raw = quoted
00398         if is_weak:
00399             weak.append(raw)
00400         else:
00401             strong.append(raw)
00402         pos = match.end()
00403     return ETags(strong, weak)
00404 

Here is the caller graph for this function:

Parse lists as described by RFC 2068 Section 2.

In particular, parse comma-separated lists where the elements of
the list may include quoted-strings.  A quoted-string could
contain a comma.  A non-quoted string could have quotes in the
middle.  Quotes are removed automatically after parsing.

:param value: a string with a list header.
:return: list

Definition at line 138 of file http.py.

00138 
00139 def parse_list_header(value):
00140     """Parse lists as described by RFC 2068 Section 2.
00141 
00142     In particular, parse comma-separated lists where the elements of
00143     the list may include quoted-strings.  A quoted-string could
00144     contain a comma.  A non-quoted string could have quotes in the
00145     middle.  Quotes are removed automatically after parsing.
00146 
00147     :param value: a string with a list header.
00148     :return: list
00149     """
00150     result = []
00151     for item in _parse_list_header(value):
00152         if item[:1] == item[-1:] == '"':
00153             item = unquote_header_value(item[1:-1])
00154         result.append(item)
00155     return result
00156 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.parse_multipart (   file,
  boundary,
  content_length,
  stream_factory = None,
  charset = 'utf-8',
  errors = 'ignore',
  buffer_size = 10 * 1024,
  max_form_memory_size = None 
)
Parse a multipart/form-data stream.  This is invoked by
:func:`utils.parse_form_data` if the content type matches.  Currently it
exists for internal usage only, but could be exposed as separate
function if it turns out to be useful and if we consider the API stable.

Definition at line 489 of file http.py.

00489 
00490                     max_form_memory_size=None):
00491     """Parse a multipart/form-data stream.  This is invoked by
00492     :func:`utils.parse_form_data` if the content type matches.  Currently it
00493     exists for internal usage only, but could be exposed as separate
00494     function if it turns out to be useful and if we consider the API stable.
00495     """
00496     # XXX: this function does not support multipart/mixed.  I don't know of
00497     #      any browser that supports this, but it should be implemented
00498     #      nonetheless.
00499 
00500     # make sure the buffer size is divisible by four so that we can base64
00501     # decode chunk by chunk
00502     assert buffer_size % 4 == 0, 'buffer size has to be divisible by 4'
00503     # also the buffer size has to be at least 1024 bytes long or long headers
00504     # will freak out the system
00505     assert buffer_size >= 1024, 'buffer size has to be at least 1KB'
00506 
00507     if stream_factory is None:
00508         stream_factory = default_stream_factory
00509     else:
00510         stream_factory = _make_stream_factory(stream_factory)
00511 
00512     if not boundary:
00513         raise ValueError('Missing boundary')
00514     if not is_valid_multipart_boundary(boundary):
00515         raise ValueError('Invalid boundary: %s' % boundary)
00516     if len(boundary) > buffer_size:
00517         raise ValueError('Boundary longer than buffer size')
00518 
00519     total_content_length = content_length
00520     next_part = '--' + boundary
00521     last_part = next_part + '--'
00522 
00523     form = []
00524     files = []
00525     in_memory = 0
00526 
00527     # convert the file into a limited stream with iteration capabilities
00528     file = LimitedStream(file, content_length)
00529     iterator = chain(make_line_iter(file, buffer_size=buffer_size),
00530                      repeat(''))
00531 
00532     def _find_terminator():
00533         """The terminator might have some additional newlines before it.
00534         There is at least one application that sends additional newlines
00535         before headers (the python setuptools package).
00536         """
00537         for line in iterator:
00538             if not line:
00539                 break
00540             line = line.strip()
00541             if line:
00542                 return line
00543         return ''
00544 
00545     try:
00546         terminator = _find_terminator()
00547         if terminator != next_part:
00548             raise ValueError('Expected boundary at start of multipart data')
00549 
00550         while terminator != last_part:
00551             headers = parse_multipart_headers(iterator)
00552             disposition = headers.get('content-disposition')
00553             if disposition is None:
00554                 raise ValueError('Missing Content-Disposition header')
00555             disposition, extra = parse_options_header(disposition)
00556             filename = extra.get('filename')
00557             name = extra.get('name')
00558             transfer_encoding = headers.get('content-transfer-encoding')
00559 
00560             content_type = headers.get('content-type')
00561             if content_type is None:
00562                 is_file = False
00563             else:
00564                 content_type = parse_options_header(content_type)[0]
00565                 is_file = True
00566 
00567             if is_file:
00568                 if filename is not None:
00569                     filename = _fix_ie_filename(_decode_unicode(filename,
00570                                                                 charset,
00571                                                                 errors))
00572                 try:
00573                     content_length = int(headers['content-length'])
00574                 except (KeyError, ValueError):
00575                     content_length = 0
00576                 stream = stream_factory(total_content_length, content_type,
00577                                         filename, content_length)
00578             else:
00579                 stream = StringIO()
00580 
00581             buf = ''
00582             for line in iterator:
00583                 if not line:
00584                     raise ValueError('unexpected end of stream')
00585                 if line[:2] == '--':
00586                     terminator = line.rstrip()
00587                     if terminator in (next_part, last_part):
00588                         break
00589                 if transfer_encoding in _supported_multipart_encodings:
00590                     try:
00591                         line = line.decode(transfer_encoding)
00592                     except:
00593                         raise ValueError('could not base 64 decode chunk')
00594                 # we have something in the buffer from the last iteration.
00595                 # write that value to the output stream now and clear the buffer.
00596                 if buf:
00597                     stream.write(buf)
00598                     buf = ''
00599 
00600                 # If the line ends with windows CRLF we write everything except
00601                 # the last two bytes.  In all other cases however we write everything
00602                 # except the last byte.  If it was a newline, that's fine, otherwise
00603                 # it does not matter because we write it the last iteration.  If the
00604                 # loop aborts early because the end of a part was reached, the last
00605                 # newline is not written which is exactly what we want.
00606                 newline_length = line[-2:] == '\r\n' and 2 or 1
00607                 stream.write(line[:-newline_length])
00608                 buf = line[-newline_length:]
00609                 if not is_file and max_form_memory_size is not None:
00610                     in_memory += len(line)
00611                     if in_memory > max_form_memory_size:
00612                         from werkzeug.exceptions import RequestEntityTooLarge
00613                         raise RequestEntityTooLarge()
00614             else:
00615                 raise ValueError('unexpected end of part')
00616 
00617             # rewind the stream
00618             stream.seek(0)
00619 
00620             if is_file:
00621                 files.append((name, FileStorage(stream, filename, name,
00622                                                 content_type,
00623                                                 content_length)))
00624             else:
00625                 form.append((name, _decode_unicode(stream.read(),
00626                                                    charset, errors)))
00627     finally:
00628         # make sure the whole input stream is read
00629         file.exhaust()
00630 
00631     return form, files
00632 

Here is the call graph for this function:

Here is the caller graph for this function:

Parses multipart headers from an iterable that yields lines (including
the trailing newline symbol.

Definition at line 633 of file http.py.

00633 
00634 def parse_multipart_headers(iterable):
00635     """Parses multipart headers from an iterable that yields lines (including
00636     the trailing newline symbol.
00637     """
00638     result = []
00639     for line in iterable:
00640         line, line_terminated = _line_parse(line)
00641         if not line_terminated:
00642             raise ValueError('unexpected end of line in multipart header')
00643         if not line:
00644             break
00645         elif line[0] in ' \t' and result:
00646             key, value = result[-1]
00647             result[-1] = (key, value + '\n ' + line[1:])
00648         else:
00649             parts = line.split(':', 1)
00650             if len(parts) == 2:
00651                 result.append((parts[0].strip(), parts[1].strip()))
00652     return Headers(result)
00653 

Here is the call graph for this function:

Here is the caller graph for this function:

Parse a ``Content-Type`` like header into a tuple with the content
type and the options:

>>> parse_options_header('Content-Type: text/html; mimetype=text/html')
('Content-Type: text/html', {'mimetype': 'text/html'})

This should not be used to parse ``Cache-Control`` like headers that use
a slightly different format.  For these headers use the
:func:`parse_dict_header` function.

.. versionadded:: 0.5

:param value: the header to parse.
:return: (str, options)

Definition at line 177 of file http.py.

00177 
00178 def parse_options_header(value):
00179     """Parse a ``Content-Type`` like header into a tuple with the content
00180     type and the options:
00181 
00182     >>> parse_options_header('Content-Type: text/html; mimetype=text/html')
00183     ('Content-Type: text/html', {'mimetype': 'text/html'})
00184 
00185     This should not be used to parse ``Cache-Control`` like headers that use
00186     a slightly different format.  For these headers use the
00187     :func:`parse_dict_header` function.
00188 
00189     .. versionadded:: 0.5
00190 
00191     :param value: the header to parse.
00192     :return: (str, options)
00193     """
00194     def _tokenize(string):
00195         while string[:1] == ';':
00196             string = string[1:]
00197             end = string.find(';')
00198             while end > 0 and string.count('"', 0, end) % 2:
00199                 end = string.find(';', end + 1)
00200             if end < 0:
00201                 end = len(string)
00202             value = string[:end]
00203             yield value.strip()
00204             string = string[end:]
00205 
00206     parts = _tokenize(';' + value)
00207     name = parts.next()
00208     extra = {}
00209     for part in parts:
00210         if '=' in part:
00211             key, value = part.split('=', 1)
00212             extra[key.strip().lower()] = unquote_header_value(value.strip())
00213         else:
00214             extra[part.strip()] = None
00215     return name, extra
00216 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.parse_set_header (   value,
  on_update = None 
)
Parse a set-like header and return a :class:`HeaderSet` object.  The
return value is an object that treats the items case-insensitively and
keeps the order of the items.

:param value: a set header to be parsed.
:param on_update: an optional callable that is called every time a
                  value on the :class:`HeaderSet` object is changed.
:return: a :class:`HeaderSet`

Definition at line 273 of file http.py.

00273 
00274 def parse_set_header(value, on_update=None):
00275     """Parse a set-like header and return a :class:`HeaderSet` object.  The
00276     return value is an object that treats the items case-insensitively and
00277     keeps the order of the items.
00278 
00279     :param value: a set header to be parsed.
00280     :param on_update: an optional callable that is called every time a
00281                       value on the :class:`HeaderSet` object is changed.
00282     :return: a :class:`HeaderSet`
00283     """
00284     if not value:
00285         return HeaderSet(None, on_update)
00286     return HeaderSet(parse_list_header(value), on_update)
00287 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.parse_www_authenticate_header (   value,
  on_update = None 
)
Parse an HTTP WWW-Authenticate header into a :class:`WWWAuthenticate`
object.

:param value: a WWW-Authenticate header to parse.
:param on_update: an optional callable that is called every time a
                  value on the :class:`WWWAuthenticate` object is changed.
:return: a :class:`WWWAuthenticate` object.

Definition at line 319 of file http.py.

00319 
00320 def parse_www_authenticate_header(value, on_update=None):
00321     """Parse an HTTP WWW-Authenticate header into a :class:`WWWAuthenticate`
00322     object.
00323 
00324     :param value: a WWW-Authenticate header to parse.
00325     :param on_update: an optional callable that is called every time a
00326                       value on the :class:`WWWAuthenticate` object is changed.
00327     :return: a :class:`WWWAuthenticate` object.
00328     """
00329     if not value:
00330         return WWWAuthenticate(on_update=on_update)
00331     try:
00332         auth_type, auth_info = value.split(None, 1)
00333         auth_type = auth_type.lower()
00334     except (ValueError, AttributeError):
00335         return WWWAuthenticate(value.lower(), on_update=on_update)
00336     return WWWAuthenticate(auth_type, parse_dict_header(auth_info),
00337                            on_update)
00338 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.quote_etag (   etag,
  weak = False 
)
Quote an etag.

:param etag: the etag to quote.
:param weak: set to `True` to tag it "weak".

Definition at line 339 of file http.py.

00339 
00340 def quote_etag(etag, weak=False):
00341     """Quote an etag.
00342 
00343     :param etag: the etag to quote.
00344     :param weak: set to `True` to tag it "weak".
00345     """
00346     if '"' in etag:
00347         raise ValueError('invalid etag')
00348     etag = '"%s"' % etag
00349     if weak:
00350         etag = 'w/' + etag
00351     return etag
00352 

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.quote_header_value (   value,
  extra_chars = '',
  allow_token = True 
)
Quote a header value if necessary.

.. versionadded:: 0.5

:param value: the value to quote.
:param extra_chars: a list of extra characters to skip quoting.
:param allow_token: if this is enabled token values are returned
                    unchanged.

Definition at line 59 of file http.py.

00059 
00060 def quote_header_value(value, extra_chars='', allow_token=True):
00061     """Quote a header value if necessary.
00062 
00063     .. versionadded:: 0.5
00064 
00065     :param value: the value to quote.
00066     :param extra_chars: a list of extra characters to skip quoting.
00067     :param allow_token: if this is enabled token values are returned
00068                         unchanged.
00069     """
00070     value = str(value)
00071     if allow_token:
00072         token_chars = _token_chars | set(extra_chars)
00073         if set(value).issubset(token_chars):
00074             return value
00075     return '"%s"' % value.replace('\\', '\\\\').replace('"', '\\"')
00076 

Here is the caller graph for this function:

def MoinMoin.support.werkzeug.http.remove_entity_headers (   headers,
  allowed = ('expires', 'content-location' 
)
Remove all entity headers from a list or :class:`Headers` object.  This
operation works in-place.  `Expires` and `Content-Location` headers are
by default not removed.  The reason for this is :rfc:`2616` section
10.3.5 which specifies some entity headers that should be sent.

.. versionchanged:: 0.5
   added `allowed` parameter.

:param headers: a list or :class:`Headers` object.
:param allowed: a list of headers that should still be allowed even though
                they are entity headers.

Definition at line 686 of file http.py.

00686 
00687 def remove_entity_headers(headers, allowed=('expires', 'content-location')):
00688     """Remove all entity headers from a list or :class:`Headers` object.  This
00689     operation works in-place.  `Expires` and `Content-Location` headers are
00690     by default not removed.  The reason for this is :rfc:`2616` section
00691     10.3.5 which specifies some entity headers that should be sent.
00692 
00693     .. versionchanged:: 0.5
00694        added `allowed` parameter.
00695 
00696     :param headers: a list or :class:`Headers` object.
00697     :param allowed: a list of headers that should still be allowed even though
00698                     they are entity headers.
00699     """
00700     allowed = set(x.lower() for x in allowed)
00701     headers[:] = [(key, value) for key, value in headers if
00702                   not is_entity_header(key) or key.lower() in allowed]
00703 

Here is the call graph for this function:

Here is the caller graph for this function:

Remove all HTTP/1.1 "Hop-by-Hop" headers from a list or
:class:`Headers` object.  This operation works in-place.

.. versionadded:: 0.5

:param headers: a list or :class:`Headers` object.

Definition at line 704 of file http.py.

00704 
00705 def remove_hop_by_hop_headers(headers):
00706     """Remove all HTTP/1.1 "Hop-by-Hop" headers from a list or
00707     :class:`Headers` object.  This operation works in-place.
00708 
00709     .. versionadded:: 0.5
00710 
00711     :param headers: a list or :class:`Headers` object.
00712     """
00713     headers[:] = [(key, value) for key, value in headers if
00714                   not is_hop_by_hop_header(key)]
00715 

Here is the call graph for this function:

Unquote a single etag:

>>> unquote_etag('w/"bar"')
('bar', True)
>>> unquote_etag('"bar"')
('bar', False)

:param etag: the etag identifier to unquote.
:return: a ``(etag, weak)`` tuple.

Definition at line 353 of file http.py.

00353 
00354 def unquote_etag(etag):
00355     """Unquote a single etag:
00356 
00357     >>> unquote_etag('w/"bar"')
00358     ('bar', True)
00359     >>> unquote_etag('"bar"')
00360     ('bar', False)
00361 
00362     :param etag: the etag identifier to unquote.
00363     :return: a ``(etag, weak)`` tuple.
00364     """
00365     if not etag:
00366         return None, None
00367     etag = etag.strip()
00368     weak = False
00369     if etag[:2] in ('w/', 'W/'):
00370         weak = True
00371         etag = etag[2:]
00372     if etag[:1] == etag[-1:] == '"':
00373         etag = etag[1:-1]
00374     return etag, weak
00375 

Here is the caller graph for this function:

Definition at line 77 of file http.py.

00077 
00078 def unquote_header_value(value):
00079     r"""Unquotes a header value.  (Reversal of :func:`quote_header_value`).
00080     This does not use the real unquoting but what browsers are actually
00081     using for quoting.
00082 
00083     .. versionadded:: 0.5
00084 
00085     :param value: the header value to unquote.
00086     """
00087     if value and value[0] == value[-1] == '"':
00088         # this is not the real unquoting, but fixing this so that the
00089         # RFC is met will result in bugs with internet explorer and
00090         # probably some other browsers as well.  IE for example is
00091         # uploading files with "C:\foo\bar.txt" as filename
00092         value = value[1:-1].replace('\\\\', '\\').replace('\\"', '"')
00093     return value
00094 

Here is the caller graph for this function:


Variable Documentation

tuple MoinMoin.support.werkzeug.http._accept_re = re.compile(r'([^\s;,]+)(?:[^,]*?;\s*q=(\d*(?:\.\d+)?))?')

Definition at line 37 of file http.py.

Initial value:
00001 frozenset([
00002     'allow', 'content-encoding', 'content-language', 'content-length',
00003     'content-location', 'content-md5', 'content-range', 'content-type',
00004     'expires', 'last-modified'
00005 ])

Definition at line 43 of file http.py.

tuple MoinMoin.support.werkzeug.http._etag_re = re.compile(r'([Ww]/)?(?:"(.*?)"|(.*?))(?:\s*,\s*|$)')

Definition at line 40 of file http.py.

Initial value:
00001 frozenset([
00002     'connection', 'keep-alive', 'proxy-authenticate',
00003     'proxy-authorization', 'te', 'trailers', 'transfer-encoding',
00004     'upgrade'
00005 ])

Definition at line 48 of file http.py.

tuple MoinMoin.support.werkzeug.http._multipart_boundary_re = re.compile('^[ -~]{0,200}[!-~]$')

Definition at line 41 of file http.py.

tuple MoinMoin.support.werkzeug.http._supported_multipart_encodings = frozenset(['base64', 'quoted-printable'])

Definition at line 56 of file http.py.

Initial value:
00001 frozenset("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00002                          '^_`abcdefghijklmnopqrstuvwxyz|~')

Definition at line 38 of file http.py.