Ñò ÐõJc@sddZddkZddkZddklZlZlZlZddkZei dƒZ ei dƒZ de fd„ƒYZ dd„Zd efd „ƒYZd efd „ƒYZd efd„ƒYZdefd„ƒYZdefd„ƒYZd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zee_ddgZdS(s" Middleware to check for obedience to the WSGI specification. Some of the things this checks: * Signature of the application and start_response (including that keyword arguments are not used). * Environment checks: - Environment is a dictionary (and not a subclass). - That all the required keys are in the environment: REQUEST_METHOD, SERVER_NAME, SERVER_PORT, wsgi.version, wsgi.input, wsgi.errors, wsgi.multithread, wsgi.multiprocess, wsgi.run_once - That HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH are not in the environment (these headers should appear as CONTENT_LENGTH and CONTENT_TYPE). - Warns if QUERY_STRING is missing, as the cgi module acts unpredictably in that case. - That CGI-style variables (that don't contain a .) have (non-unicode) string values - That wsgi.version is a tuple - That wsgi.url_scheme is 'http' or 'https' (@@: is this too restrictive?) - Warns if the REQUEST_METHOD is not known (@@: probably too restrictive). - That SCRIPT_NAME and PATH_INFO are empty or start with / - That at least one of SCRIPT_NAME or PATH_INFO are set. - That CONTENT_LENGTH is a positive integer. - That SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should be '/'). - That wsgi.input has the methods read, readline, readlines, and __iter__ - That wsgi.errors has the methods flush, write, writelines * The status is a string, contains a space, starts with an integer, and that integer is in range (> 100). * That the headers is a list (not a subclass, not another kind of sequence). * That the items of the headers are tuples of strings. * That there is no 'status' header (that is used in CGI, but not in WSGI). * That the headers don't contain newlines or colons, end in _ or -, or contain characters codes below 037. * That Content-Type is given if there is content (CGI often has a default content type, but WSGI does not). * That no Content-Type is given when there is no content (@@: is this too restrictive?) * That the exc_info argument to start_response is a tuple or None. * That all calls to the writer are with strings, and no other methods on the writer are accessed. * That wsgi.input is used properly: - .read() is called with zero or one argument - That it returns a string - That readline, readlines, and __iter__ return strings - That .close() is not called - No other methods are provided * That wsgi.errors is used properly: - .write() and .writelines() is called with a string - That .close() is not called, and no other methods are provided. * The response iterator: - That it is not a string (it should be a list of a single string; a string will work, but perform horribly). - That .next() returns a string - That the iterator is not iterated over until start_response has been called (that can signal either a server or application error). - That .close() is called (doesn't raise exception, only prints to sys.stderr, because we only know it isn't called when the object is garbage collected). iÿÿÿÿN(tDictTypet StringTypet TupleTypetListTypes^[a-zA-Z][a-zA-Z0-9\-_]*$s [\000-\037]t WSGIWarningcBseZdZRS(s: Raised in response to WSGI-spec-related warnings (t__name__t __module__t__doc__(((s0/usr/lib/python2.6/site-packages/webtest/lint.pyRxscs‡fd†}|S(s® When applied between a WSGI server and a WSGI application, this middleware will check for WSGI compliancy on a number of levels. This middleware does not modify the request or response in any way, but will throw an AssertionError if anything seems off (except for a failure to close the application iterator, which will be printed to stderr -- there's no way to throw an exception at that point). csÏt|ƒdjp td‚| p td‚|\}‰t|ƒg‰‡‡fd†}t|dƒ|dThe application must return an iterator, if only an empty list( RR t check_environt InputWrappert ErrorWrapperR tFalsetcheck_iteratortIteratorWrapper(RRtenvironRtiterator(t application(RRs0/usr/lib/python2.6/site-packages/webtest/lint.pytlint_app‰s   ((R!t global_confR"((R!s0/usr/lib/python2.6/site-packages/webtest/lint.pyt middleware}s )RcBs>eZd„Zd„Zd„Zd„Zd„Zd„ZRS(cCs ||_dS(N(tinput(tselft wsgi_input((s0/usr/lib/python2.6/site-packages/webtest/lint.pyt__init__¶scGsPt|ƒdjpt‚|ii|Œ}t|ƒtdƒjpt‚|S(Nit(RR R%treadttype(R&Rtv((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR*¹s cGs6|ii|Œ}t|ƒtdƒjpt‚|S(NR)(R%treadlineR+R (R&RR,((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR-¿s cGst|ƒdjpt‚|ii|Œ}t|ƒtgƒjpt‚x.|D]&}t|ƒtdƒjpt‚qSW|S(NiR)(RR R%t readlinesR+(R&Rtlinestline((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR.Äs $ccs'x |iƒ}|pdS|VqdS(N(R-(R&R0((s0/usr/lib/python2.6/site-packages/webtest/lint.pyt__iter__Ìs  cCsdp td‚dS(Nis input.close() must not be called(R (R&((s0/usr/lib/python2.6/site-packages/webtest/lint.pytcloseÓs(RRR(R*R-R.R1R2(((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR´s      RcBs5eZd„Zd„Zd„Zd„Zd„ZRS(cCs ||_dS(N(terrors(R&t wsgi_errors((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR(ØscCs4t|ƒtdƒjpt‚|ii|ƒdS(NR)(R+R R3twrite(R&ts((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR5Ûs cCs|iiƒdS(N(R3tflush(R&((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR7ßscCs"x|D]}|i|ƒqWdS(N(R5(R&tseqR0((s0/usr/lib/python2.6/site-packages/webtest/lint.pyt writelinesâscCsdp td‚dS(Nis!errors.close() must not be called(R (R&((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR2æs(RRR(R5R7R9R2(((s0/usr/lib/python2.6/site-packages/webtest/lint.pyRÖs     RcBseZd„Zd„ZRS(cCs ||_dS(N(twriter(R&t wsgi_writer((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR(ëscCs1t|ƒtdƒjpt‚|i|ƒdS(NR)(R+R R:(R&R6((s0/usr/lib/python2.6/site-packages/webtest/lint.pyt__call__îs (RRR(R<(((s0/usr/lib/python2.6/site-packages/webtest/lint.pyRés tPartialIteratorWrappercBseZd„Zd„ZRS(cCs ||_dS(N(R (R&t wsgi_iterator((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR(ôscCs t|iƒS(N(RR (R&((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR1÷s(RRR(R1(((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR=òs RcBs5eZd„Zd„Zd„Zd„Zd„ZRS(cCs.||_t|ƒ|_t|_||_dS(N(toriginal_iteratortiterR Rtclosedtcheck_start_response(R&R>RB((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR(ýs  cCs|S(N((R&((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR1scCsY|i p td‚|iiƒ}|idj o!|ip td‚d|_n|S(NsIterator read after closedsjThe application returns and we started iterating over its body, but start_response has not yet been called(RAR R tnextRBR (R&R,((s0/usr/lib/python2.6/site-packages/webtest/lint.pyRCs  cCs1t|_t|idƒo|iiƒndS(NR2(tTrueRAthasattrR?R2(R&((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR2s cCs6|iptiidƒn|ip td‚dS(Ns/Iterator garbage collected without being closed(RAtsyststderrR5R (R&((s0/usr/lib/python2.6/site-packages/webtest/lint.pyt__del__s     (RRR(R1RCR2RH(((s0/usr/lib/python2.6/site-packages/webtest/lint.pyRûs    cCsÊt|ƒtjptdt|ƒ|f‚xDdddddddd d g D]!}||jptd |‚qOWx9d d gD]+}||jptd||df‚qWd|jotidtƒnxd|iƒD]V}d|joqÞnt||ƒtjp%td|t||ƒ||f‚qÞWt|dƒtjptd|d‚|dd+jptd|d‚t |dƒt |dƒ|dd,jotid |dtƒn|i d!ƒ p&|d!i d"ƒptd#|d!‚|i d$ƒ p&|d$i d"ƒptd%|d$‚|i d&ƒo-t |d&ƒd'jptd(|d&‚n|i d!ƒp|id$ƒp td)‚n|i d!ƒd"jp td*‚dS(-Ns:Environment is not of the right type: %r (environment: %r)tREQUEST_METHODt SERVER_NAMEt SERVER_PORTs wsgi.versions wsgi.inputs wsgi.errorsswsgi.multithreadswsgi.multiprocesss wsgi.run_onces$Environment missing required key: %rtHTTP_CONTENT_TYPEtHTTP_CONTENT_LENGTHs8Environment should not have the key: %s (use %s instead)it QUERY_STRINGs’QUERY_STRING is not in the WSGI environment; the cgi module will use sys.argv when this variable is missing, so application errors are more likelyt.s9Environmental variable %s is not a string: %r (value: %r)s#wsgi.version should be a tuple (%r)swsgi.url_schemethttpthttpsswsgi.url_scheme unknown: %rtGETtHEADtPOSTtOPTIONStPUTtDELETEtTRACEsUnknown REQUEST_METHOD: %rt SCRIPT_NAMEt/s$SCRIPT_NAME doesn't start with /: %rt PATH_INFOs"PATH_INFO doesn't start with /: %rtCONTENT_LENGTHisInvalid CONTENT_LENGTH: %rsgOne of SCRIPT_NAME or PATH_INFO are required (PATH_INFO should at least be '/' if SCRIPT_NAME is empty)sOSCRIPT_NAME cannot be '/'; it should instead be '', and PATH_INFO should be '/'(RPRQ(RRRSRTRURVRWRX(R+RR twarningstwarnRtkeysRRt check_inputt check_errorstgett startswithtintthas_key(Rtkey((s0/usr/lib/python2.6/site-packages/webtest/lint.pyRsf       #    cCsEx>ddddgD]*}t||ƒptd||f‚qWdS(NR*R-R.R1s-wsgi.input (%r) doesn't have the attribute %s(RER (R'tattr((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR`]s cCsBx;dddgD]*}t||ƒptd||f‚qWdS(NR7R5R9s.wsgi.errors (%r) doesn't have the attribute %s(RER (R4Rg((s0/usr/lib/python2.6/site-packages/webtest/lint.pyRacs cCs¿t|ƒtjptd|‚|iddƒd}t|ƒdjptd|‚t|ƒ}|djptd|‚t|ƒdjp|dd jotid |t ƒndS( Ns Status must be a string (not %r)iiis)Status codes must be three characters: %ridsStatus code is invalid: %rit sjThe status string (%r) should be a three-digit integer followed by a single space and a status explanation( R+RR tsplitR RRdR]R^R(Rt status_codet status_int((s0/usr/lib/python2.6/site-packages/webtest/lint.pyR is   $cCsyt|ƒtjptd|t|ƒf‚h}x?|D]7}t|ƒtjptd|t|ƒf‚t|ƒdjpt‚|\}}|iƒdjptd|‚d||iƒns0  "  7"  ! A