def test_support_wildcards(self): mime_types_supported = ['image/*', 'application/xml'] # match using a type wildcard self.assertEqual( best_match(mime_types_supported, 'image/png'), 'image/*') # match using a wildcard for both requested and supported self.assertEqual(best_match(mime_types_supported, 'image/*'), 'image/*')
def _GET_HEAD_common(self, request, verb): """ The following code is reproduced almost verbatim in deferred_render_DELETE in about.py. So if you change this code, you'll likely need to change that, and vice versa. """ usage = registry.findUsage(httpObjectCategoryName, verb, TagInstanceResource) registry.checkRequest(usage, request) # This will raise TNoInstanceOnObject if there's no instance, # and that will return a 404 (see util.py). tvalue, tagValue = yield self.facadeClient.getTagInstance( self.session, self.path, self.objectId) value = guessValue(tvalue) accept = request.getHeader('accept') or '*/*' if tvalue.valueType == ThriftValueType.BINARY_TYPE: contentType = tvalue.binaryKeyMimeType if mimeparse.best_match([contentType], accept) == '': raise error.NotAcceptable() body = value # Mark this value as unwrappable for JSON request._fluiddb_jsonp_unwrappable = None else: contentType = mimeparse.best_match( contentTypesForPrimitiveValue, accept) if contentType == '': raise error.NotAcceptable() try: serializer = util.primitiveTypeSerializer[contentType] except KeyError: raise TInternalError('No serializer for %r.' % contentType) else: body = serializer(value) typeValue = self._getTypeHeader(tvalue.valueType) request.setHeader(util.buildHeader('Type'), typeValue) request.setHeader('Content-length', str(len(body))) request.setHeader('Content-type', contentType) # setting the Last-Modified header for fluiddb/id makes no sense if tagValue and tagValue.creationTime: request.setHeader( 'Last-modified', tagValue.creationTime.strftime('%a, %d %b %Y %H:%M:%S')) request.setResponseCode(usage.successCode) defer.returnValue(body)
def _GET_HEAD_common(self, request, verb): """ The following code is reproduced almost verbatim in deferred_render_DELETE in about.py. So if you change this code, you'll likely need to change that, and vice versa. """ usage = registry.findUsage(httpObjectCategoryName, verb, TagInstanceResource) registry.checkRequest(usage, request) # This will raise TNoInstanceOnObject if there's no instance, # and that will return a 404 (see util.py). tvalue, tagValue = yield self.facadeClient.getTagInstance( self.session, self.path, self.objectId) value = guessValue(tvalue) accept = request.getHeader('accept') or '*/*' if tvalue.valueType == ThriftValueType.BINARY_TYPE: contentType = tvalue.binaryKeyMimeType if mimeparse.best_match([contentType], accept) == '': raise error.NotAcceptable() body = value # Mark this value as unwrappable for JSON request._fluiddb_jsonp_unwrappable = None else: contentType = mimeparse.best_match(contentTypesForPrimitiveValue, accept) if contentType == '': raise error.NotAcceptable() try: serializer = util.primitiveTypeSerializer[contentType] except KeyError: raise TInternalError('No serializer for %r.' % contentType) else: body = serializer(value) typeValue = self._getTypeHeader(tvalue.valueType) request.setHeader(util.buildHeader('Type'), typeValue) request.setHeader('Content-length', str(len(body))) request.setHeader('Content-type', contentType) # setting the Last-Modified header for fluiddb/id makes no sense if tagValue and tagValue.creationTime: request.setHeader( 'Last-modified', tagValue.creationTime.strftime('%a, %d %b %Y %H:%M:%S')) request.setResponseCode(usage.successCode) defer.returnValue(body)
def test_best_match_many_slashes(self): """ L{best_match} returns an emtpy string if the mime type contains multiple slashes. """ self.assertEqual('', best_match(['application/json'], 'application/json/parse'))
def test_best_match_with_misplaced_semicolon(self): """ L{best_match} returns an empty string if the MIME type contains a semicolon in an inappropriate spot. """ # The semicolon after 'application/xml' doesn't conform to the MIME # type format. It should be a comma. accept = 'text/html,application/xml;image/png,image/*;q=0.9,*/*;q=0.8' self.assertEqual('', best_match(['text/html'], accept))
def getResponsePayloadTypeFromAcceptHeader(self, request): if not self.responsePayloads: raise error.InternalError('Usage with no response payloads.') accept = request.getHeader('accept') or '*/*' responseType = mimeparse.best_match( self.responsePayloads.keys(), accept) try: payload = self.responsePayloads[responseType] except KeyError: raise error.NotAcceptable() else: return payload.format
def test_best_match(self): mime_types_supported = ['application/xbel+xml', 'application/xml'] # direct match self.assertEqual( best_match(mime_types_supported, 'application/xbel+xml'), 'application/xbel+xml') # direct match with a q parameter self.assertEqual( best_match(mime_types_supported, 'application/xbel+xml; q=1'), 'application/xbel+xml') # direct match of our second choice with a q parameter self.assertEqual( best_match(mime_types_supported, 'application/xml; q=1'), 'application/xml') # match using a subtype wildcard self.assertEqual( best_match(mime_types_supported, 'application/*; q=1'), 'application/xml') # match using a type wildcard self.assertEqual( best_match(mime_types_supported, '*/*'), 'application/xml') mime_types_supported = ['application/xbel+xml', 'text/xml'] # match using a type versus a lower weighted subtype self.assertEqual( best_match(mime_types_supported, 'text/*;q=0.5,*/*; q=0.1'), 'text/xml') # fail to match anything self.assertEqual( best_match(mime_types_supported, 'text/html,application/atom+xml; q=0.9'), '') # common AJAX scenario mime_types_supported = ['application/json', 'text/html'] self.assertEqual( best_match(mime_types_supported, 'application/json, text/javascript, */*'), 'application/json') # verify fitness ordering self.assertEqual( best_match(mime_types_supported, 'application/json, text/html;q=0.9'), 'application/json')
def _GET_HEAD_common(self, request, verb): """ I handle the common actions taken by GET and HEAD requests, which are virtually identical, except HEAD drops the body. This code, apart from the yield self._setObjectId(), is taken verbatim from _GET_HEAD_common in objects.py. So if you change this code, you'll likely need to change that, and vice versa. @param request: The HTTP request. @param verb: A C{str}, either 'GET' or 'HEAD'. @return: A C{Deferred} which fires with the body of a GET request, having set all the response headers that are common to GET and HEAD. (The body will be dropped (below) for HEAD requests.) """ usage = registry.findUsage(httpAboutCategoryName, verb, AboutTagInstanceResource) registry.checkRequest(usage, request) yield self._setObjectId() # This will raise TNoInstanceOnObject if there's no instance, # and that will return a 404 (see util.py). tvalue, tagValue = yield self.facadeClient.getTagInstance( self.session, self.path, self.objectId) value = guessValue(tvalue) accept = request.getHeader('accept') or '*/*' if tvalue.valueType == ThriftValueType.BINARY_TYPE: contentType = tvalue.binaryKeyMimeType if mimeparse.best_match([contentType], accept) == '': raise error.NotAcceptable() body = value # Mark this value as unwrappable for JSON request._fluiddb_jsonp_unwrappable = None else: contentType = mimeparse.best_match(contentTypesForPrimitiveValue, accept) if contentType == '': raise error.NotAcceptable() try: serializer = util.primitiveTypeSerializer[contentType] except KeyError: raise TInternalError('No serializer for %r.' % contentType) else: body = serializer(value) typeValue = self._getTypeHeader(tvalue.valueType) request.setHeader(util.buildHeader('Type'), typeValue) request.setHeader('Content-length', str(len(body))) request.setHeader('Content-type', contentType) # setting the Last-Modified header for fluiddb/id makes no sense if tagValue and tagValue.creationTime: request.setHeader( 'Last-modified', tagValue.creationTime.strftime('%a, %d %b %Y %H:%M:%S')) request.setResponseCode(usage.successCode) defer.returnValue(body)
def _GET_HEAD_common(self, request, verb): """ I handle the common actions taken by GET and HEAD requests, which are virtually identical, except HEAD drops the body. This code, apart from the yield self._setObjectId(), is taken verbatim from _GET_HEAD_common in objects.py. So if you change this code, you'll likely need to change that, and vice versa. @param request: The HTTP request. @param verb: A C{str}, either 'GET' or 'HEAD'. @return: A C{Deferred} which fires with the body of a GET request, having set all the response headers that are common to GET and HEAD. (The body will be dropped (below) for HEAD requests.) """ usage = registry.findUsage(httpAboutCategoryName, verb, AboutTagInstanceResource) registry.checkRequest(usage, request) yield self._setObjectId() # This will raise TNoInstanceOnObject if there's no instance, # and that will return a 404 (see util.py). tvalue, tagValue = yield self.facadeClient.getTagInstance( self.session, self.path, self.objectId) value = guessValue(tvalue) accept = request.getHeader('accept') or '*/*' if tvalue.valueType == ThriftValueType.BINARY_TYPE: contentType = tvalue.binaryKeyMimeType if mimeparse.best_match([contentType], accept) == '': raise error.NotAcceptable() body = value # Mark this value as unwrappable for JSON request._fluiddb_jsonp_unwrappable = None else: contentType = mimeparse.best_match( contentTypesForPrimitiveValue, accept) if contentType == '': raise error.NotAcceptable() try: serializer = util.primitiveTypeSerializer[contentType] except KeyError: raise TInternalError('No serializer for %r.' % contentType) else: body = serializer(value) typeValue = self._getTypeHeader(tvalue.valueType) request.setHeader(util.buildHeader('Type'), typeValue) request.setHeader('Content-length', str(len(body))) request.setHeader('Content-type', contentType) # setting the Last-Modified header for fluiddb/id makes no sense if tagValue and tagValue.creationTime: request.setHeader( 'Last-modified', tagValue.creationTime.strftime('%a, %d %b %Y %H:%M:%S')) request.setResponseCode(usage.successCode) defer.returnValue(body)