def generate_response(self, environ, start_response): if self.content_length is not None: del self.content_length headerlist = list(self.headerlist) accept_value = environ.get('HTTP_ACCEPT', '') accept = MIMEAccept(accept_value) match = accept.best_match(['text/html', 'application/json']) if match == 'text/html': content_type = 'text/html' body = self.html_body(environ) elif match == 'application/json': content_type = 'application/json' body = self.json_body(environ) else: content_type = 'text/plain' body = self.plain_body(environ) resp = Response( body, status=self.status, headerlist=headerlist, content_type=content_type, ) resp.content_type = content_type return resp(environ, start_response)
def generate_response(self, environ, start_response): if self.content_length is not None: del self.content_length headerlist = list(self.headerlist) accept_value = environ.get('HTTP_ACCEPT', '') accept = MIMEAccept(accept_value) match = accept.best_match(['text/html', 'application/json']) if match == 'text/html': content_type = 'text/html' body = self.html_body(environ) elif match == 'application/json': content_type = 'application/json' body = self.json_body(environ) else: content_type = 'text/plain' body = self.plain_body(environ) extra_kw = {} if isinstance(body, text_type): extra_kw.update(charset='utf-8') resp = Response(body, status=self.status, headerlist=headerlist, content_type=content_type, **extra_kw ) resp.content_type = content_type return resp(environ, start_response)
def test_match(): mimeaccept = MIMEAccept('Content-Type', 'image/jpg') assert mimeaccept._match('image/jpg', 'image/jpg') assert mimeaccept._match('image/*', 'image/jpg') assert mimeaccept._match('*/*', 'image/jpg') assert not mimeaccept._match('text/html', 'image/jpg') assert_raises(ValueError, mimeaccept._match, 'image/jpg', '*/*')
def test_accept_mixedcase(): """3.7 Media Types [...] The type, subtype, and parameter attribute names are case- insensitive.""" mimeaccept = MIMEAccept('text/HtMl') assert mimeaccept.accept_html()
def test_mimeaccept_contains(): mimeaccept = MIMEAccept('A/a, B/b, C/c') assert 'A/a' in mimeaccept assert 'A/*' in mimeaccept assert '*/a' in mimeaccept assert not 'A/b' in mimeaccept assert not 'B/a' in mimeaccept
def match_accept(header, shortcodes): """ Match an Accept header against a list of shortcodes, in order of preference. A few examples: >>> header = "application/xml,application/xhtml+xml,text/html" >>> match_accept(header, ['html', 'json', 'xml']) ['html', 'xml'] >>> header2 = "application/json,application/xml" >>> match_accept(header2, ['html', 'json', 'xml']) ['json', 'xml'] >>> match_accept(header2, ['html', 'xml', 'json']) ['xml', 'json'] """ server_types = map(MIMETYPES.__getitem__, shortcodes) client_types = list(MIMEAccept(header)) matches = [] for mimetype in server_types: if mimetype in client_types: matches.append(mimetype) return map(shortcodes.__getitem__, map(server_types.index, matches))
def test_it_sets_response_header_based_on_value_of_accept( self, pyramid_request, testview, accept, expected_header ): pyramid_request.accept = MIMEAccept(accept) res = version_media_type_header(testview)(None, pyramid_request) assert res.headers["Hypothesis-Media-Type"] == expected_header
def test_it_does_not_modify_context_if_any_accept_values_ok( self, pyramid_request, testview): # At least one of these is valid pyramid_request.accept = MIMEAccept("application/json, foo/bar") fake_context = mock.Mock() validate_media_types(testview)(fake_context, pyramid_request) context, _ = testview.call_args[0] assert context == fake_context
def test_it_replaces_context_with_415_if_accept_set_and_invalid( self, pyramid_request, testview): # None of these is valid pyramid_request.accept = MIMEAccept( "application/something+json, foo/bar") fake_context = mock.Mock() validate_media_types(testview)(fake_context, pyramid_request) context, _ = testview.call_args[0] assert isinstance(context, HTTPUnsupportedMediaType)
def get_api_format(self, request): if request.GET.get('format') in self._formats_list: return request.GET['format'] elif request.GET.get('format'): return None mimetype = MIMEAccept(request.META.get('HTTP_ACCEPT', 'application/json')).best_match( [f[1] for f in self.api_formats], default_match=self.default_mimetype ) return self._mimetype_lookup[mimetype] if mimetype else None
def canHandle(self, environ): accept = MIMEAccept(environ.get('HTTP_ACCEPT', 'application/json')) accept_charset = AcceptCharset( environ.get('HTTP_ACCEPT_CHARSET', 'utf-8')) accept_language = AcceptLanguage( environ.get('HTTP_ACCEPT_LANGUAGE', 'de-DE')) # Write a real rule here. # This one doesn't handle OPTIONS or GET return 'application/json' in accept
def test_match(): mimeaccept = MIMEAccept('image/jpg') assert mimeaccept._match('image/jpg', 'image/jpg') assert mimeaccept._match('image/*', 'image/jpg') assert mimeaccept._match('*/*', 'image/jpg') assert not mimeaccept._match('text/html', 'image/jpg') assert_raises(ValueError, mimeaccept._match, 'image/jpg', '*/*')
def test_wildcard_matching(): """ Wildcard matching forces the match to take place against the type or subtype of the mask and offer (depending on where the wildcard matches) """ mimeaccept = MIMEAccept("type/subtype") matches = [ ("*/*", "*/*"), ("*/*", "A/*"), ("*/*", "*/a"), ("*/*", "A/a"), ("A/*", "*/*"), ("A/*", "A/*"), ("A/*", "*/a"), ("A/*", "A/a"), ("*/a", "*/*"), ("*/a", "A/*"), ("*/a", "*/a"), ("*/a", "A/a"), ("A/a", "*/*"), ("A/a", "A/*"), ("A/a", "*/a"), ("A/a", "A/a"), # Offers might not contain a subtype ("*/*", "*"), ("A/*", "*"), ("*/a", "*"), ] for mask, offer in matches: assert mimeaccept._match(mask, offer) # Test malformed mask and offer variants where either is missing # a type or subtype assert mimeaccept._match("A", offer) assert mimeaccept._match(mask, "a") mismatches = [("B/b", "A/*"), ("B/*", "A/a"), ("B/*", "A/*"), ("*/b", "*/a")] for mask, offer in mismatches: assert not mimeaccept._match(mask, offer)
def test_match(): mimeaccept = MIMEAccept('image/jpg') assert mimeaccept._match('image/jpg', 'image/jpg') assert mimeaccept._match('image/*', 'image/jpg') assert mimeaccept._match('*/*', 'image/jpg') assert not mimeaccept._match('text/html', 'image/jpg') mismatches = [('B/b', 'A/a'), ('B/b', 'B/a'), ('B/b', 'A/b'), ('A/a', 'B/b'), ('B/a', 'B/b'), ('A/b', 'B/b')] for mask, offer in mismatches: assert not mimeaccept._match(mask, offer)
def test_mime_init(): mimeaccept = MIMEAccept('image/jpg') assert mimeaccept._parsed == [('image/jpg', 1)] mimeaccept = MIMEAccept('image/png, image/jpg;q=0.5') assert mimeaccept._parsed == [('image/png', 1), ('image/jpg', 0.5)] mimeaccept = MIMEAccept('image, image/jpg;q=0.5') assert mimeaccept._parsed == [('image/jpg', 0.5)] mimeaccept = MIMEAccept('*/*') assert mimeaccept._parsed == [('*/*', 1)] mimeaccept = MIMEAccept('*/png') assert mimeaccept._parsed == [] mimeaccept = MIMEAccept('image/pn*') assert mimeaccept._parsed == [] mimeaccept = MIMEAccept('imag*/png') assert mimeaccept._parsed == [] mimeaccept = MIMEAccept('image/*') assert mimeaccept._parsed == [('image/*', 1)]
def test_match(): mimeaccept = MIMEAccept("image/jpg") assert mimeaccept._match("image/jpg", "image/jpg") assert mimeaccept._match("image/*", "image/jpg") assert mimeaccept._match("*/*", "image/jpg") assert not mimeaccept._match("text/html", "image/jpg") mismatches = [("B/b", "A/a"), ("B/b", "B/a"), ("B/b", "A/b"), ("A/a", "B/b"), ("B/a", "B/b"), ("A/b", "B/b")] for mask, offer in mismatches: assert not mimeaccept._match(mask, offer)
def test_match(): mimeaccept = MIMEAccept('image/jpg') assert mimeaccept._match('image/jpg', 'image/jpg') assert mimeaccept._match('image/*', 'image/jpg') assert mimeaccept._match('*/*', 'image/jpg') assert not mimeaccept._match('text/html', 'image/jpg') mismatches = [ ('B/b', 'A/a'), ('B/b', 'B/a'), ('B/b', 'A/b'), ('A/a', 'B/b'), ('B/a', 'B/b'), ('A/b', 'B/b') ] for mask, offer in mismatches: assert not mimeaccept._match(mask, offer)
def test_wildcard_matching(): """ Wildcard matching forces the match to take place against the type or subtype of the mask and offer (depending on where the wildcard matches) """ mimeaccept = MIMEAccept('type/subtype') matches = [ ('*/*', '*/*'), ('*/*', 'A/*'), ('*/*', '*/a'), ('*/*', 'A/a'), ('A/*', '*/*'), ('A/*', 'A/*'), ('A/*', '*/a'), ('A/*', 'A/a'), ('*/a', '*/*'), ('*/a', 'A/*'), ('*/a', '*/a'), ('*/a', 'A/a'), ('A/a', '*/*'), ('A/a', 'A/*'), ('A/a', '*/a'), ('A/a', 'A/a'), # Offers might not contain a subtype ('*/*', '*'), ('A/*', '*'), ('*/a', '*')] for mask, offer in matches: assert mimeaccept._match(mask, offer) # Test malformed mask and offer variants where either is missing # a type or subtype assert mimeaccept._match('A', offer) assert mimeaccept._match(mask, 'a') mismatches = [ ('B/b', 'A/*'), ('B/*', 'A/a'), ('B/*', 'A/*'), ('*/b', '*/a')] for mask, offer in mismatches: assert not mimeaccept._match(mask, offer)
def prepare(self, environ): if not self.has_body and not self.empty_body: html_comment = '' comment = self.comment or '' accept_value = environ.get('HTTP_ACCEPT', '') accept = MIMEAccept(accept_value) # Attempt to match text/html or application/json, if those don't # match, we will fall through to defaulting to text/plain match = accept.best_match(['text/html', 'application/json']) if match == 'text/html': self.content_type = 'text/html' escape = _html_escape page_template = self.html_template_obj br = '<br/>' if comment: html_comment = '<!-- %s -->' % escape(comment) elif match == 'application/json': self.content_type = 'application/json' self.charset = None escape = _no_escape br = '\n' if comment: html_comment = escape(comment) class JsonPageTemplate(object): def __init__(self, excobj): self.excobj = excobj def substitute(self, status, body): jsonbody = self.excobj._json_formatter( status=status, body=body, title=self.excobj.title, environ=environ) return json.dumps(jsonbody) page_template = JsonPageTemplate(self) else: self.content_type = 'text/plain' escape = _no_escape page_template = self.plain_template_obj br = '\n' if comment: html_comment = escape(comment) args = { 'br': br, 'explanation': escape(self.explanation), 'detail': escape(self.detail or ''), 'comment': escape(comment), 'html_comment': html_comment, } body_tmpl = self.body_template_obj if HTTPException.body_template_obj is not body_tmpl: # Custom template; add headers to args for k, v in environ.items(): if (not k.startswith('wsgi.')) and ('.' in k): # omit custom environ variables, stringifying them may # trigger code that should not be executed here; see # https://github.com/Pylons/pyramid/issues/239 continue args[k] = escape(v) for k, v in self.headers.items(): args[k.lower()] = escape(v) body = body_tmpl.substitute(args) page = page_template.substitute(status=self.status, body=body) if isinstance(page, text_type): page = page.encode(self.charset if self.charset else 'UTF-8') self.app_iter = [page] self.body = page
def test_accept_html(): mimeaccept = MIMEAccept('image/jpg') assert not mimeaccept.accept_html() mimeaccept = MIMEAccept('image/jpg, text/html') assert mimeaccept.accept_html()
def test_accept_html(): mimeaccept = MIMEAccept('Content-Type', 'image/jpg') assert not mimeaccept.accept_html() mimeaccept = MIMEAccept('Content-Type', 'image/jpg, text/html') assert mimeaccept.accept_html()
def test_accept_json(): mimeaccept = MIMEAccept("text/html, *; q=.2, */*; q=.2") assert mimeaccept.best_match(["application/json"]) == "application/json"
def test_accept_json(): mimeaccept = MIMEAccept('text/html, *; q=.2, */*; q=.2') assert mimeaccept.best_match(['application/json']) == 'application/json'
def test_match_uppercase_q(): """The relative-quality-factor "q" parameter is defined as an exact string in "14.1 Accept" BNF grammar""" mimeaccept = MIMEAccept('image/jpg; q=.4, Image/pNg; Q=.2, image/*; q=.05') assert mimeaccept._parsed == [('image/jpg', 0.4), ('image/png', 1), ('image/*', 0.05)]
def test_match_mixedcase(): mimeaccept = MIMEAccept('image/jpg; q=.2, Image/pNg; Q=.4, image/*; q=.05') assert mimeaccept.best_match(['Image/JpG']) == 'Image/JpG' assert mimeaccept.best_match(['image/Tiff']) == 'image/Tiff' assert mimeaccept.best_match(['image/Tiff', 'image/PnG', 'image/jpg']) == 'image/PnG'
def MIMEAccept(self, *args, **kwargs): from webob.acceptparse import MIMEAccept return MIMEAccept(*args, **kwargs)
def test_match_mixedcase(): mimeaccept = MIMEAccept("image/jpg; q=.2, Image/pNg; Q=.4, image/*; q=.05") assert mimeaccept.best_match(["Image/JpG"]) == "Image/JpG" assert mimeaccept.best_match(["image/Tiff"]) == "image/Tiff" assert mimeaccept.best_match(["image/Tiff", "image/PnG", "image/jpg"]) == "image/PnG"
def test_accept_html(): mimeaccept = MIMEAccept("image/jpg") assert not mimeaccept.accept_html() mimeaccept = MIMEAccept("image/jpg, text/html") assert mimeaccept.accept_html()