Ñò ô†³Kc4@sdZddkZddkZddkZddklZlZlZddklZ ddk l Z dddd d gZ d e fd „ƒYZed ƒZed ƒZedƒZedƒZedƒZedƒZx>eƒiƒD]-\ZZeeeƒoe ieƒnqéWhZd efd„ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZ e!d„Z"e#e#e#e#d„Z$e!d„Z%defd„ƒYZ&defd„ƒYZ'e'd d!d"ƒd#efd$„ƒYZ(e(d%d&d'ƒd(efd)„ƒYZ)e)d*d&d+ƒd,efd-„ƒYZ*e*d.d&d/ƒd0e&fd1„ƒYZ+e+d2d3d4ƒd5efd6„ƒYZ,e,d7d3d8ƒd9efd:„ƒYZ-e-d;d3d<ƒd=efd>„ƒYZ.e.d?d@dAƒdBefdC„ƒYZ/e/dDd&dEƒdFefdG„ƒYZ0e0dHd3dIƒx.dJd3dKdLdMfdNd3dKdLdOfdPd3dKdLdQfdRd@dKdSdEfdTd&dUdLdVfdWd3dUdLdXfdYd!dKdLdZfd[d&dUdLd\fd]d&dKdLd^fd_d&dKdSd`fdad&dKdSdbfdcd!dUdddefdfd@dKdSdgfdhd3dKdLdifdjd&dUdddkfdld3dUdSdmfdnd3dKdSdofdpd3dKdLdqfdrd3dKdLdsfdtd3dKdSdufdvd3dKdddwfdxd&dUdddyfdzd@dUdSd{fd|d3dKdSd}fd~d!dUdLdfd€d@dKdLdfd‚d3dKdSdƒfd„d3dUdSd…fd†d@dKdSd‡fdˆd@dUdSd‰fdŠd@dUd‹dXfdŒd3dKdLdfdŽd!dKdLdfdd!dKdLd‘fd’d!dKdLd“fd”d3dUdSd•fd–d@dKdLd—fd˜d!dKdLd™fdšd!dKd‹d›fdœd@dUd‹dff(D]V\Z1Z2Z3Z4Z5hedL6e d‹6e&dd6edS6e4Z6e5e6e1e2e5e3ƒ_[6qWxIei7ƒD];Z8e8i1i9dždŸƒi:ƒZ;e8e<ƒe;ƒo e?eeƒoe=ieƒnqËWdS( sÁ HTTP Message Header Fields (see RFC 4229) This contains general support for HTTP/1.1 message headers [1]_ in a manner that supports WSGI ``environ`` [2]_ and ``response_headers`` [3]_. Specifically, this module defines a ``HTTPHeader`` class whose instances correspond to field-name items. The actual field-content for the message-header is stored in the appropriate WSGI collection (either the ``environ`` for requests, or ``response_headers`` for responses). Each ``HTTPHeader`` instance is a callable (defining ``__call__``) that takes one of the following: - an ``environ`` dictionary, returning the corresponding header value by according to the WSGI's ``HTTP_`` prefix mechanism, e.g., ``USER_AGENT(environ)`` returns ``environ.get('HTTP_USER_AGENT')`` - a ``response_headers`` list, giving a comma-delimited string for each corresponding ``header_value`` tuple entries (see below). - a sequence of string ``*args`` that are comma-delimited into a single string value: ``CONTENT_TYPE("text/html","text/plain")`` returns ``"text/html, text/plain"`` - a set of ``**kwargs`` keyword arguments that are used to create a header value, in a manner dependent upon the particular header in question (to make value construction easier and error-free): ``CONTENT_DISPOSITION(max_age=CONTENT_DISPOSITION.ONEWEEK)`` returns ``"public, max-age=60480"`` Each ``HTTPHeader`` instance also provides several methods to act on a WSGI collection, for removing and setting header values. ``delete(collection)`` This method removes all entries of the corresponding header from the given collection (``environ`` or ``response_headers``), e.g., ``USER_AGENT.remove(environ)`` deletes the 'HTTP_USER_AGENT' entry from the ``environ``. ``update(collection, *args, **kwargs)`` This method does an in-place replacement of the given header entry, for example: ``CONTENT_LENGTH(response_headers,len(body))`` The first argument is a valid ``environ`` dictionary or ``response_headers`` list; remaining arguments are passed on to ``__call__(*args, **kwargs)`` for value construction. ``apply(collection, **kwargs)`` This method is similar to update, only that it may affect other headers. For example, according to recommendations in RFC 2616, certain Cache-Control configurations should also set the ``Expires`` header for HTTP/1.0 clients. By default, ``apply()`` is simply ``update()`` but limited to keyword arguments. This particular approach to managing headers within a WSGI collection has several advantages: 1. Typos in the header name are easily detected since they become a ``NameError`` when executed. The approach of using header strings directly can be problematic; for example, the following should return ``None`` : ``environ.get("HTTP_ACCEPT_LANGUAGES")`` 2. For specific headers with validation, using ``__call__`` will result in an automatic header value check. For example, the _ContentDisposition header will reject a value having ``maxage`` or ``max_age`` (the appropriate parameter is ``max-age`` ). 3. When appending/replacing headers, the field-name has the suggested RFC capitalization (e.g. ``Content-Type`` or ``ETag``) for user-agents that incorrectly use case-sensitive matches. 4. Some headers (such as ``Content-Type``) are 0, that is, only one entry of this type may occur in a given set of ``response_headers``. This module knows about those cases and enforces this cardinality constraint. 5. The exact details of WSGI header management are abstracted so the programmer need not worry about operational differences between ``environ`` dictionary or ``response_headers`` list. 6. Sorting of ``HTTPHeaders`` is done following the RFC suggestion that general-headers come first, followed by request and response headers, and finishing with entity-headers. 7. Special care is given to exceptional cases such as Set-Cookie which violates the RFC's recommendation about combining header content into a single entry using comma separation. A particular difficulty with HTTP message headers is a categorization of sorts as described in section 4.2: Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)]. It MUST be possible to combine the multiple header fields into one "field-name: field-value" pair, without changing the semantics of the message, by appending each subsequent field-value to the first, each separated by a comma. This creates three fundamentally different kinds of headers: - Those that do not have a #(values) production, and hence are singular and may only occur once in a set of response fields; this case is handled by the ``_SingleValueHeader`` subclass. - Those which have the #(values) production and follow the combining rule outlined above; our ``_MultiValueHeader`` case. - Those which are multi-valued, but cannot be combined (such as the ``Set-Cookie`` header due to its ``Expires`` parameter); or where combining them into a single header entry would cause common user-agents to fail (``WWW-Authenticate``, ``Warning``) since they fail to handle dates even when properly quoted. This case is handled by ``_MultiEntryHeader``. Since this project does not have time to provide rigorous support and validation for all headers, it does a basic construction of headers listed in RFC 2616 (plus a few others) so that they can be obtained by simply doing ``from paste.httpheaders import *``; the name of the header instance is the "common name" less any dashes to give CamelCase style names. .. [1] http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 .. [2] http://www.python.org/peps/pep-0333.html#environ-variables .. [3] http://www.python.org/peps/pep-0333.html#the-start-response-callable iÿÿÿÿN(t formatdatet parsedate_tzt mktime_tz(ttime(tHTTPBadRequestt get_headert list_headerstnormalize_headerst HTTPHeadertEnvironVariablecBs)eZdZd„Zd„Zd„ZRS(sµ a CGI ``environ`` variable as described by WSGI This is a helper object so that standard WSGI ``environ`` variables can be extracted w/o syntax error possibility. cCs|i|dƒS(Nt(tget(tselftenviron((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyt__call__šscCsd|S(Ns((R ((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyt__repr__œscCs|||(R2t __class__RR/(R tref((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyRlsc Osö|p|i|Stt|dƒjotg}|iiƒ}xWg}|dD]*\}}|iƒ|jo ||qSqS~D]}|i|ƒq„W|Stt|dƒjo*|di|iƒ}|pdS|fSx|D]}qèW|S(sq find/construct field-value(s) for the given header Resolution is done according to the following arguments: - If only keyword arguments are given, then this is equivalent to ``compose(**kwargs)``. - If the first (and only) argument is a dict, it is assumed to be a WSGI ``environ`` and the result of the corresponding ``HTTP_`` entry is returned. - If the first (and only) argument is a list, it is assumed to be a WSGI ``response_headers`` and the field-value(s) for this header are collected and returned. - In all other cases, the arguments are collected, checked that they are string values, possibly verified by the header's logic, and returned. At this time it is an error to provide keyword arguments if args is present (this might change). It is an error to provide both a WSGI object and also string arguments. If no arguments are provided, then ``compose()`` is called to provide a default value for the header; if there is not default it is an error. i(( RtlistttypeR/R4tappendtdictR R'( R RRtresultR/t_[1]theaderRtitem((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pytvaluesps&%cOs2|i||Ž}|pdSt|dƒiƒS(sÕ converts ``values()`` into a string value This method converts the results of ``values()`` into a string value for common usage. By default, it is asserted that only one value exists; if you need to access all values then either call ``values()`` directly, or inherit ``_MultiValueHeader`` which overrides this method to return a comma separated list of values as described by section 4.2 of RFC 2616. R i(RHtstrtstrip(R RRRH((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyRŸs cCs‘t|ƒtjo#|i|jo||i=n|Sd}xN|t|ƒjo:||diƒ|ijo||=q?n|d7}q?WdS(sS removes all occurances of the header from the collection provided iiN(RARCR'tlenR4R+(R R!ti((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pytdelete±scOsö|i||Ž}|p|i|ƒdSt|ƒtjo|||iÊsN(RRSRZRJR4tfloatRBRk(R RRRFRERXtlangstqstlangtpiecestparamsR®tparamtlvaluetrvaluet_[2]((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyR ±s, 5!   (RRRR (((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyR­¬ssAccept-LanguagesRFC 2616, 14.4t _AcceptRangescBseZdZddd„ZRS(s. Accept-Ranges, RFC 2616 section 14.5 cCs|odSdS(Ntbytestnone(sbytes(snone((R R¼R»((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyRÒsN(RRRRSR(((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyRºÎss Accept-RangesR%sRFC 2616, 14.5t _ContentRangecBs eZdZdddd„ZRS(s. Content-Range, RFC 2616 section 14.6 cCsd|||f}|fS(Nsbytes %d-%d/%d((R t first_bytet last_bytet total_lengthR^((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyRÜsN(RRRRSR(((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyR½Øss Content-RangesRFC 2616, 14.6t_AuthorizationcBs,eZdZdddddddd„ZRS(s2 Authorization, RFC 2617 (RFC 2616, 14.8) cs|p| o4d|iƒ|iƒf}d|idƒiƒSˆpd‰|idƒ\} } | iddƒ\} } tiƒ} | i| ˆ||ƒ|iddƒ\} }titi|ƒƒ} d tf‡‡fd †ƒY}d | i |ƒ| ƒ}|fS( Ns%s:%ssBasic %stbase64Rœsrealm="t"it t FakeRequestcs5eZ‡fd†Zd„Z‡fd†ZeZRS(csˆS(N((R (tpath(s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyt get_full_url÷scSstS(N(R,(R ((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pythas_dataùscs ˆpdS(NtGET((R (tmethod(s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyt get_methodûs(RRRÇRÈRËt get_selector((RÆRÊ(s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyRÅös s Digest %s( RJtencodeRZturllib2tAbstractDigestAuthHandlert add_passwordtparse_keqv_listtparse_http_listR-tget_authorization(R tdigesttbasictusernametpasswordt challengeRÆRÊtuserpassR*trealmtauthttokentchalRÅR^((RÊRÆs5/usr/lib/python2.6/site-packages/paste/httpheaders.pyRçs  N(RRRRSR(((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pyRÁãs t AuthorizationsRFC 2617tAccepts1.1s multi-valuesRFC 2616, 14.1sAccept-CharsetsRFC 2616, 14.2sAccept-EncodingsRFC 2616, 14.3tAgetsingulartAllows1.0sRFC 2616, 14.7tCookiesRFC 2109/Netscapet ConnectionsRFC 2616, 14.10sContent-EncodingsRFC 2616, 14.11sContent-LanguagesRFC 2616, 14.12sContent-LocationsRFC 2616, 14.14s Content-MD5sRFC 2616, 14.15tDates date-headersRFC 2616, 14.18tETagsRFC 2616, 14.19tExpectsRFC 2616, 14.20tExpiressRFC 2616, 14.21tFromsRFC 2616, 14.22tHostsRFC 2616, 14.23sIf-MatchsRFC 2616, 14.24s If-None-MatchsRFC 2616, 14.26sIf-RangesRFC 2616, 14.27sIf-Unmodified-SincesRFC 2616, 14.28s Last-ModifiedsRFC 2616, 14.29tLocationsRFC 2616, 14.30s Max-ForwardssRFC 2616, 14.31tPragmasRFC 2616, 14.32sProxy-AuthenticatesRFC 2616, 14.33sProxy-AuthorizationsRFC 2616, 14.34tReferersRFC 2616, 14.36s Retry-AftersRFC 2616, 14.37tServersRFC 2616, 14.38s Set-Cookies multi-entrytTEsRFC 2616, 14.39tTrailersRFC 2616, 14.40sTransfer-EncodingsRFC 2616, 14.41tUpgradesRFC 2616, 14.42s User-AgentsRFC 2616, 14.43tVarysRFC 2616, 14.44tViasRFC 2616, 14.45tWarningsRFC 2616, 14.46sWWW-AuthenticatesRFC 2616, 14.47R)R*(@RRŸRÎtretrfc822RRRRRtthttpexceptionsRt__all__RIR RRRRRRtglobalsRzt_namet_objR;RBR3R-RRTRUR[RORRSRRRsRwR‰R—R™R¡R£R­RºR½RÁR/R0R1tstyletcommenttklassRHRbR8R7theadnametlocalst __pudge_all__RAt issubclass(((s5/usr/lib/python2.6/site-packages/paste/httpheaders.pytˆsÖ            ÿ;   &{ B0