#NEWLINE# def validate_etags( request , response , autotags = False ) : #NEWLINE# #INDENT# "Validate the current ETag against If-Match, If-None-Match headers.\n\n    If autotags is True, an ETag response-header value will be provided\n    from an MD5 hash of the response body (unless some other code has\n    already provided an ETag header). If False (the default), the ETag\n    will not be automatic.\n\n    WARNING: the autotags feature is not designed for URL's which allow\n    methods other than GET. For example, if a POST to the same URL returns\n    no content, the automatic ETag will be incorrect, breaking a fundamental\n    use for entity tags in a possibly destructive fashion. Likewise, if you\n    raise 304 Not Modified, the response body will be empty, the ETag hash\n    will be incorrect, and your application will break.\n    See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24\n    " #NEWLINE# if hasattr ( response , 'ETag' ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# status = response . status #NEWLINE# etag = response . headers . get ( 'ETag' ) #NEWLINE# if ( ( not etag ) and autotags ) : #NEWLINE# #INDENT# if ( status == 200 ) : #NEWLINE# #INDENT# etag = response . collapse_body ( ) #NEWLINE# etag = ( '"%s"' % hashlib . md5 . new ( etag ) . hexdigest ( ) ) #NEWLINE# response . headers [ 'ETag' ] = etag #NEWLINE# #UNINDENT# #UNINDENT# response . ETag = etag #NEWLINE# if ( ( status >= 200 ) and ( status <= 299 ) ) : #NEWLINE# #INDENT# conditions = ( request . headers . elements ( 'If-Match' ) or [ ] ) #NEWLINE# conditions = [ str ( x ) for x in conditions ] #NEWLINE# if ( conditions and ( not ( ( conditions == [ '*' ] ) or ( etag in response ) ) ) ) : #NEWLINE# #INDENT# return httperror ( request , response , 412 , description = ( 'If-Match failed: ETag %r did not match %r' % ( etag , conditions ) ) ) #NEWLINE# #UNINDENT# conditions = ( request . headers . elements ( 'If-None-Match' ) or [ ] ) #NEWLINE# conditions = [ str ( x ) for x in conditions ] #NEWLINE# if ( ( conditions == [ '*' ] ) or ( etag in conditions ) ) : #NEWLINE# #INDENT# if ( request . method in ( 'GET' , 'HEAD' ) ) : #NEWLINE# #INDENT# return redirect ( request , response , [ ] , code = 304 ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return httperror ( request , response , 412 , description = ( 'If-None-Match failed: ETag %r matched %r' % ( etag , conditions ) ) )