Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
147 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
""" | ||
Simple accept header parsing to determins which content type we should deliver | ||
back to the caller. This is mostly used by the rdf export functionality | ||
""" | ||
import re | ||
import operator | ||
|
||
# For parsing {name};q=x and {name} style fields from the accept header | ||
accept_re = re.compile("^(?P<ct>[^;]+)[ \t]*(;[ \t]*q=(?P<q>[0-9.]+)){0,1}$") | ||
|
||
accept_types = { | ||
# Name : ContentType, Is Markup?, Extension | ||
"text/html" : ("text/html; charset=utf-8", True, 'html'), | ||
"text/n3" : ("text/n3; charset=utf-8", False, 'n3'), | ||
"text/plain" : ("text/plain; charset=utf-8", False, 'txt'), | ||
"application/rdf+xml" : ("application/rdf+xml; charset=utf-8", True, 'rdf'), | ||
} | ||
accept_by_extension = { | ||
"rdf": "application/rdf+xml", | ||
"n3" : "text/n3" | ||
} | ||
|
||
def parse_extension( file_ext ): | ||
""" | ||
If provided an extension, this function will return the details | ||
for that extension, if we know about it. | ||
""" | ||
ext = accept_by_extension.get(file_ext,None) | ||
if ext: | ||
return accept_types[ext] | ||
return (None,None,None,) | ||
|
||
|
||
def parse_header( accept_header='' ): | ||
""" | ||
Parses the supplied accept header and tries to determine | ||
which content types we can provide the response in that will keep the | ||
client happy. | ||
We will always provide html as the default if we can't see anything else | ||
but we will also need to take into account the q score. | ||
The return values are be content-type,is-markup,extension | ||
""" | ||
if accept_header is None: | ||
accept_header = "" | ||
|
||
acceptable = {} | ||
for typ in accept_header.split(','): | ||
m = accept_re.match(typ) | ||
if m: | ||
key = m.groups(0)[0] | ||
qscore = m.groups(0)[2] or 1.0 | ||
acceptable[key] = float(qscore) | ||
|
||
for ctype in sorted(acceptable.iteritems(), | ||
key=operator.itemgetter(1), | ||
reverse=True): | ||
if ctype[0] in accept_types: | ||
return accept_types[ctype[0]] | ||
|
||
return accept_types["text/html"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
from nose.tools import assert_equal | ||
|
||
import ckan.lib.accept as accept | ||
|
||
class TestAccept: | ||
def test_accept_invalid(self): | ||
ct, markup, ext = accept.parse_header(None) | ||
assert_equal( ct, "text/html; charset=utf-8") | ||
assert_equal( markup, True) | ||
assert_equal( ext, "html") | ||
|
||
def test_accept_invalid2(self): | ||
ct, markup, ext = accept.parse_header("") | ||
assert_equal( ct, "text/html; charset=utf-8") | ||
assert_equal( markup, True) | ||
assert_equal( ext, "html") | ||
|
||
def test_accept_invalid3(self): | ||
ct, markup, ext = accept.parse_header("wombles") | ||
assert_equal( ct, "text/html; charset=utf-8") | ||
assert_equal( markup, True) | ||
assert_equal( ext, "html") | ||
|
||
|
||
def test_accept_valid(self): | ||
a = "text/turtle,application/turtle,application/rdf+xml,text/plain;q=0.8,*/*;q=.5" | ||
ct, markup, ext = accept.parse_header(a) | ||
assert_equal( ct, "application/rdf+xml; charset=utf-8") | ||
assert_equal( markup, True) | ||
assert_equal( ext, "rdf") | ||
|
||
def test_accept_valid2(self): | ||
a = "text/turtle,application/turtle,application/rdf+xml;q=0.9,text/plain;q=0.8,*/*;q=.5" | ||
ct, markup, ext = accept.parse_header(a) | ||
assert_equal( ct, "application/rdf+xml; charset=utf-8") | ||
assert_equal( markup, True) | ||
assert_equal( ext, "rdf") | ||
|
||
def test_accept_valid4(self): | ||
a = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" | ||
ct, markup, ext = accept.parse_header(a) | ||
assert_equal( ct, "text/html; charset=utf-8") | ||
assert_equal( markup, True) | ||
assert_equal( ext, "html") | ||
|
||
def test_accept_valid5(self): | ||
a = "application/rdf+xml;q=0.5,application/xhtml+xml,text/html;q=0.9" | ||
ct, markup, ext = accept.parse_header(a) | ||
assert_equal( ct, "text/html; charset=utf-8") | ||
assert_equal( markup, True) | ||
assert_equal( ext, "html") | ||
|
||
def test_accept_valid6(self): | ||
a = "application/rdf+xml;q=0.9,application/xhtml+xml,text/html;q=0.5" | ||
ct, markup, ext = accept.parse_header(a) | ||
assert_equal( ct, "application/rdf+xml; charset=utf-8") | ||
assert_equal( markup, True) | ||
assert_equal( ext, "rdf") | ||
|
||
def test_accept_valid7(self): | ||
a = "text/turtle,application/turtle,application/rdf+xml;q=0.8,text/plain;q=0.9,*/*;q=.5" | ||
ct, markup, ext = accept.parse_header(a) | ||
assert_equal( ct, "text/plain; charset=utf-8") | ||
assert_equal( markup, False) | ||
assert_equal( ext, "txt") |