Huge cleanup of content viewers.

This commit is contained in:
Aldo Cortesi 2012-08-18 17:08:17 +12:00
parent 5c80450ce7
commit 11c63dcb9f
5 changed files with 362 additions and 343 deletions

View File

@ -159,10 +159,10 @@ class StatusBar(common.WWrap):
r.append("[")
r.append(("heading_key", "P"))
r.append(":%s]"%utils.unparse_url(*self.master.server.config.reverse_proxy))
if self.master.state.default_body_view != contentview.VIEW_AUTO:
if self.master.state.default_body_view.name != "Auto":
r.append("[")
r.append(("heading_key", "M"))
r.append(":%s]"%contentview.VIEW_NAMES[self.master.state.default_body_view])
r.append(":%s]"%self.master.state.default_body_view.name)
opts = []
if self.master.anticache:
@ -255,7 +255,7 @@ class ConsoleState(flow.State):
flow.State.__init__(self)
self.focus = None
self.follow_focus = None
self.default_body_view = contentview.VIEW_AUTO
self.default_body_view = contentview.ViewAuto
self.view_flow_mode = common.VIEW_FLOW_REQUEST
self.last_script = ""
self.last_saveload = ""
@ -736,7 +736,7 @@ class ConsoleMaster(flow.FlowMaster):
return self.state.set_intercept(txt)
def change_default_display_mode(self, t):
v = contentview.VIEW_SHORTCUTS.get(t)
v = contentview.get_by_shortcut(t)
self.state.default_body_view = v
if self.currentflow:
self.refresh_flow(self.currentflow)
@ -835,7 +835,7 @@ class ConsoleMaster(flow.FlowMaster):
elif k == "M":
self.prompt_onekey(
"Global default display mode",
contentview.VIEW_PROMPT,
contentview.view_prompts,
self.change_default_display_mode
)
elif k == "P":

View File

@ -9,78 +9,20 @@ from ..contrib import jsbeautifier, html2text
VIEW_CUTOFF = 1024*50
VIEW_AUTO = 0
VIEW_JSON = 1
VIEW_XML = 2
VIEW_URLENCODED = 3
VIEW_MULTIPART = 4
VIEW_JAVASCRIPT = 5
VIEW_IMAGE = 6
VIEW_RAW = 7
VIEW_HEX = 8
VIEW_HTML = 9
VIEW_OUTLINE = 10
VIEW_AMF = 11
VIEW_NAMES = {
VIEW_AUTO: "Auto",
VIEW_JSON: "JSON",
VIEW_XML: "XML",
VIEW_URLENCODED: "URL-encoded",
VIEW_MULTIPART: "Multipart Form",
VIEW_JAVASCRIPT: "JavaScript",
VIEW_IMAGE: "Image",
VIEW_RAW: "Raw",
VIEW_HEX: "Hex",
VIEW_HTML: "HTML",
VIEW_OUTLINE: "HTML Outline",
}
def _view_text(content, total, limit):
"""
Generates a body for a chunk of text.
"""
txt = []
for i in utils.cleanBin(content).splitlines():
txt.append(
urwid.Text(("text", i), wrap="any")
)
trailer(total, txt, limit)
return txt
VIEW_PROMPT = [
("auto detect", "a"),
("hex", "e"),
("html", "h"),
("image", "i"),
("javascript", "j"),
("html outline", "o"),
("json", "s"),
("raw", "r"),
("multipart", "m"),
("urlencoded", "u"),
("xml", "x"),
]
VIEW_SHORTCUTS = {
"a": VIEW_AUTO,
"x": VIEW_XML,
"h": VIEW_HTML,
"i": VIEW_IMAGE,
"j": VIEW_JAVASCRIPT,
"s": VIEW_JSON,
"u": VIEW_URLENCODED,
"m": VIEW_MULTIPART,
"o": VIEW_OUTLINE,
"r": VIEW_RAW,
"e": VIEW_HEX,
}
CONTENT_TYPES_MAP = {
"text/html": VIEW_HTML,
"application/json": VIEW_JSON,
"text/xml": VIEW_XML,
"multipart/form-data": VIEW_MULTIPART,
"application/x-www-form-urlencoded": VIEW_URLENCODED,
"application/x-javascript": VIEW_JAVASCRIPT,
"application/javascript": VIEW_JAVASCRIPT,
"text/javascript": VIEW_JAVASCRIPT,
"image/png": VIEW_IMAGE,
"image/jpeg": VIEW_IMAGE,
"image/gif": VIEW_IMAGE,
"image/vnd.microsoft.icon": VIEW_IMAGE,
"image/x-icon": VIEW_IMAGE,
}
def trailer(clen, txt, limit):
rem = clen - limit
if rem > 0:
@ -96,228 +38,310 @@ def trailer(clen, txt, limit):
)
def _view_text(content, total, limit):
"""
Generates a body for a chunk of text.
"""
txt = []
for i in utils.cleanBin(content).splitlines():
txt.append(
urwid.Text(("text", i), wrap="any")
)
trailer(total, txt, limit)
return txt
class ViewAuto:
name = "Auto"
prompt = ("auto", "a")
content_types = []
def view_raw(hdrs, content, limit):
txt = _view_text(content[:limit], len(content), limit)
return "Raw", txt
class ViewRaw:
name = "Raw"
prompt = ("raw", "r")
content_types = []
def __call__(self, hdrs, content, limit):
txt = _view_text(content[:limit], len(content), limit)
return "Raw", txt
def view_hex(hdrs, content, limit):
txt = []
for offset, hexa, s in utils.hexdump(content[:limit]):
txt.append(urwid.Text([
("offset", offset),
" ",
("text", hexa),
" ",
("text", s),
]))
trailer(len(content), txt, limit)
return "Hex", txt
def view_xml(hdrs, content, limit):
parser = lxml.etree.XMLParser(remove_blank_text=True, resolve_entities=False, strip_cdata=False, recover=False)
try:
document = lxml.etree.fromstring(content, parser)
except lxml.etree.XMLSyntaxError:
return None
docinfo = document.getroottree().docinfo
prev = []
p = document.getroottree().getroot().getprevious()
while p is not None:
prev.insert(
0,
lxml.etree.tostring(p)
)
p = p.getprevious()
doctype=docinfo.doctype
if prev:
doctype += "\n".join(prev).strip()
doctype = doctype.strip()
s = lxml.etree.tostring(
document,
pretty_print=True,
xml_declaration=True,
doctype=doctype or None,
encoding = docinfo.encoding
)
txt = []
for i in s[:limit].strip().split("\n"):
txt.append(
urwid.Text(("text", i)),
)
trailer(len(content), txt, limit)
return "XML-like data", txt
def view_html(hdrs, content, limit):
if utils.isXML(content):
parser = lxml.etree.HTMLParser(strip_cdata=True, remove_blank_text=True)
d = lxml.html.fromstring(content, parser=parser)
docinfo = d.getroottree().docinfo
s = lxml.etree.tostring(d, pretty_print=True, doctype=docinfo.doctype)
return "HTML", _view_text(s[:limit], len(s), limit)
def view_outline(hdrs, content, limit):
content = content.decode("utf-8")
h = html2text.HTML2Text(baseurl="")
h.ignore_images = True
h.body_width = 0
content = h.handle(content)
txt = _view_text(content[:limit], len(content), limit)
return "HTML Outline", txt
def view_json(hdrs, content, limit):
lines = utils.pretty_json(content)
if lines:
class ViewHex:
name = "Hex"
prompt = ("hex", "e")
content_types = []
def __call__(self, hdrs, content, limit):
txt = []
sofar = 0
for i in lines:
sofar += len(i)
for offset, hexa, s in utils.hexdump(content[:limit]):
txt.append(urwid.Text([
("offset", offset),
" ",
("text", hexa),
" ",
("text", s),
]))
trailer(len(content), txt, limit)
return "Hex", txt
class ViewXML:
name = "XML"
prompt = ("xml", "x")
content_types = ["text/xml"]
def __call__(self, hdrs, content, limit):
parser = lxml.etree.XMLParser(remove_blank_text=True, resolve_entities=False, strip_cdata=False, recover=False)
try:
document = lxml.etree.fromstring(content, parser)
except lxml.etree.XMLSyntaxError:
return None
docinfo = document.getroottree().docinfo
prev = []
p = document.getroottree().getroot().getprevious()
while p is not None:
prev.insert(
0,
lxml.etree.tostring(p)
)
p = p.getprevious()
doctype=docinfo.doctype
if prev:
doctype += "\n".join(prev).strip()
doctype = doctype.strip()
s = lxml.etree.tostring(
document,
pretty_print=True,
xml_declaration=True,
doctype=doctype or None,
encoding = docinfo.encoding
)
txt = []
for i in s[:limit].strip().split("\n"):
txt.append(
urwid.Text(("text", i)),
)
if sofar > limit:
break
trailer(sum(len(i) for i in lines), txt, limit)
return "JSON", txt
trailer(len(content), txt, limit)
return "XML-like data", txt
def view_multipart(hdrs, content, limit):
v = hdrs.get("content-type")
if v:
v = utils.parse_content_type(v[0])
if not v:
return
boundary = v[2].get("boundary")
if not boundary:
return
rx = re.compile(r'\bname="([^"]+)"')
keys = []
vals = []
for i in content.split("--" + boundary):
parts = i.splitlines()
if len(parts) > 1 and parts[0][0:2] != "--":
match = rx.search(parts[1])
if match:
keys.append(match.group(1) + ":")
vals.append(utils.cleanBin(
"\n".join(parts[3+parts[2:].index(""):])
))
r = [
urwid.Text(("highlight", "Form data:\n")),
]
r.extend(common.format_keyvals(
zip(keys, vals),
key = "header",
val = "text"
))
return "Multipart form", r
def view_urlencoded(hdrs, content, limit):
lines = utils.urldecode(content)
if lines:
body = common.format_keyvals(
[(k+":", v) for (k, v) in lines],
key = "header",
val = "text"
)
return "URLEncoded form", body
def view_javascript(hdrs, content, limit):
opts = jsbeautifier.default_options()
opts.indent_size = 2
res = jsbeautifier.beautify(content[:limit], opts)
return "JavaScript", _view_text(res, len(content), limit)
def view_image(hdrs, content, limit):
try:
img = Image.open(cStringIO.StringIO(content))
except IOError:
return None
parts = [
("Format", str(img.format_description)),
("Size", "%s x %s px"%img.size),
("Mode", str(img.mode)),
]
for i in sorted(img.info.keys()):
if i != "exif":
parts.append(
(str(i), str(img.info[i]))
)
if hasattr(img, "_getexif"):
ex = img._getexif()
if ex:
for i in sorted(ex.keys()):
tag = TAGS.get(i, i)
parts.append(
(str(tag), str(ex[i]))
class ViewJSON:
name = "JSON"
prompt = ("json", "j")
content_types = ["application/json"]
def __call__(self, hdrs, content, limit):
lines = utils.pretty_json(content)
if lines:
txt = []
sofar = 0
for i in lines:
sofar += len(i)
txt.append(
urwid.Text(("text", i)),
)
clean = []
for i in parts:
clean.append([utils.cleanBin(i[0]), utils.cleanBin(i[1])])
fmt = common.format_keyvals(
clean,
key = "header",
val = "text"
)
return "%s image"%img.format, fmt
if sofar > limit:
break
trailer(sum(len(i) for i in lines), txt, limit)
return "JSON", txt
def view_amf(hdrs, content, limit):
s = utils.pretty_amf(content)
if s:
return "AMF", _view_text(s[:limit], len(s), limit)
PRETTY_FUNCTION_MAP = {
VIEW_XML: view_xml,
VIEW_HTML: view_html,
VIEW_JSON: view_json,
VIEW_URLENCODED: view_urlencoded,
VIEW_MULTIPART: view_multipart,
VIEW_JAVASCRIPT: view_javascript,
VIEW_IMAGE: view_image,
VIEW_HEX: view_hex,
VIEW_RAW: view_raw,
VIEW_OUTLINE: view_outline,
}
class ViewHTML:
name = "HTML"
prompt = ("html", "h")
content_types = ["text/html"]
def __call__(self, hdrs, content, limit):
if utils.isXML(content):
parser = lxml.etree.HTMLParser(strip_cdata=True, remove_blank_text=True)
d = lxml.html.fromstring(content, parser=parser)
docinfo = d.getroottree().docinfo
s = lxml.etree.tostring(d, pretty_print=True, doctype=docinfo.doctype)
return "HTML", _view_text(s[:limit], len(s), limit)
class ViewHTMLOutline:
name = "HTML Outline"
prompt = ("html outline", "o")
content_types = ["text/html"]
def __call__(self, hdrs, content, limit):
content = content.decode("utf-8")
h = html2text.HTML2Text(baseurl="")
h.ignore_images = True
h.body_width = 0
content = h.handle(content)
txt = _view_text(content[:limit], len(content), limit)
return "HTML Outline", txt
class ViewURLEncoded:
name = "URL-encoded"
prompt = ("urlencoded", "u")
content_types = ["application/x-www-form-urlencoded"]
def __call__(self, hdrs, content, limit):
lines = utils.urldecode(content)
if lines:
body = common.format_keyvals(
[(k+":", v) for (k, v) in lines],
key = "header",
val = "text"
)
return "URLEncoded form", body
class ViewMultipart:
name = "Multipart Form"
prompt = ("multipart", "m")
content_types = ["multipart/form-data"]
def __call__(self, hdrs, content, limit):
v = hdrs.get("content-type")
if v:
v = utils.parse_content_type(v[0])
if not v:
return
boundary = v[2].get("boundary")
if not boundary:
return
rx = re.compile(r'\bname="([^"]+)"')
keys = []
vals = []
for i in content.split("--" + boundary):
parts = i.splitlines()
if len(parts) > 1 and parts[0][0:2] != "--":
match = rx.search(parts[1])
if match:
keys.append(match.group(1) + ":")
vals.append(utils.cleanBin(
"\n".join(parts[3+parts[2:].index(""):])
))
r = [
urwid.Text(("highlight", "Form data:\n")),
]
r.extend(common.format_keyvals(
zip(keys, vals),
key = "header",
val = "text"
))
return "Multipart form", r
class ViewAMF:
name = "AMF"
prompt = ("amf", "f")
content_types = ["application/x-amf"]
def __call__(self, hdrs, content, limit):
s = utils.pretty_amf(content)
if s:
return "AMF", _view_text(s[:limit], len(s), limit)
class ViewJavaScript:
name = "JavaScript"
prompt = ("javascript", "j")
content_types = [
"application/x-javascript",
"application/javascript",
"text/javascript"
]
def __call__(self, hdrs, content, limit):
opts = jsbeautifier.default_options()
opts.indent_size = 2
res = jsbeautifier.beautify(content[:limit], opts)
return "JavaScript", _view_text(res, len(content), limit)
class ViewImage:
name = "Image"
prompt = ("image", "i")
content_types = [
"image/png",
"image/jpeg",
"image/gif",
"image/vnd.microsoft.icon",
"image/x-icon",
]
def __call__(self, hdrs, content, limit):
try:
img = Image.open(cStringIO.StringIO(content))
except IOError:
return None
parts = [
("Format", str(img.format_description)),
("Size", "%s x %s px"%img.size),
("Mode", str(img.mode)),
]
for i in sorted(img.info.keys()):
if i != "exif":
parts.append(
(str(i), str(img.info[i]))
)
if hasattr(img, "_getexif"):
ex = img._getexif()
if ex:
for i in sorted(ex.keys()):
tag = TAGS.get(i, i)
parts.append(
(str(tag), str(ex[i]))
)
clean = []
for i in parts:
clean.append([utils.cleanBin(i[0]), utils.cleanBin(i[1])])
fmt = common.format_keyvals(
clean,
key = "header",
val = "text"
)
return "%s image"%img.format, fmt
views = [
ViewAuto(),
ViewRaw(),
ViewHex(),
ViewJSON(),
ViewXML(),
ViewHTML(),
ViewHTMLOutline(),
ViewJavaScript(),
ViewURLEncoded(),
ViewMultipart(),
ViewImage(),
]
try:
import pyamf
views.append(ViewAMF())
except ImportError: # pragma nocover
pass
content_types_map = {}
for i in views:
for ct in i.content_types:
l = content_types_map.setdefault(ct, [])
l.append(i)
view_prompts = [i.prompt for i in views]
def get_by_shortcut(c):
for i in views:
if i.prompt[1] == c:
return i
def get(name):
for i in views:
if i.name == name:
return i
def get_view_func(viewmode, hdrs, content):
"""
Returns a function object.
"""
if viewmode == VIEW_AUTO:
if viewmode.name == "Auto":
ctype = hdrs.get("content-type")
if ctype:
ctype = ctype[0]
ct = utils.parse_content_type(ctype) if ctype else None
if ct:
viewmode = CONTENT_TYPES_MAP.get("%s/%s"%(ct[0], ct[1]))
if not viewmode and utils.isXML(content):
viewmode = VIEW_XML
return PRETTY_FUNCTION_MAP.get(viewmode, view_raw)
ct = "%s/%s"%(ct[0], ct[1])
if ct in content_types_map:
return content_types_map[ct][0]
elif utils.isXML(content):
return ViewXML
return ViewRaw
else:
return viewmode
def get_content_view(viewmode, hdrItems, content, limit):
@ -339,32 +363,14 @@ def get_content_view(viewmode, hdrItems, content, limit):
ret = func(hdrs, content, limit)
# Third-party viewers can fail in unexpected ways...
except Exception, e:
s = traceback.format_exc()
return "", _view_text(s, len(s), len(s))
#s = traceback.format_exc()
#return "", _view_text(s, len(s), len(s))
ret = None
if not ret:
viewmode = VIEW_RAW
ret = view_raw(hdrs, content, limit)
ret = get("Raw")(hdrs, content, limit)
msg.append("Couldn't parse: falling back to Raw")
else:
msg.append(ret[0])
return " ".join(msg), ret[1]
#
# Enable optional decoding methods at runtime
#
# AMF decoding requires pyamf
try:
import pyamf
VIEW_SHORTCUTS["f"] = VIEW_AMF
VIEW_PROMPT.append(("amf", "f"))
VIEW_NAMES[VIEW_AMF] = "AMF"
CONTENT_TYPES_MAP["application/x-amf"] = VIEW_AMF
PRETTY_FUNCTION_MAP[VIEW_AMF] = view_amf
except ImportError:
pass

View File

@ -180,7 +180,7 @@ class FlowView(common.WWrap):
" ",
('heading', "["),
('heading_key', "m"),
('heading', (":%s]"%contentview.VIEW_NAMES[viewmode])),
('heading', (":%s]"%viewmode.name)),
],
align="right"
)
@ -392,7 +392,7 @@ class FlowView(common.WWrap):
self.state.add_flow_setting(
self.flow,
(self.state.view_flow_mode, "prettyview"),
contentview.VIEW_SHORTCUTS.get(t)
contentview.get_by_shortcut(t)
)
self.master.refresh_flow(self.flow)
@ -500,7 +500,7 @@ class FlowView(common.WWrap):
self.master.refresh_flow(self.flow)
self.master.statusbar.message("")
elif key == "m":
p = list(contentview.VIEW_PROMPT)
p = list(contentview.view_prompts)
p.insert(0, ("clear", "c"))
self.master.prompt_onekey(
"Display mode",

View File

@ -92,7 +92,7 @@ def pretty_amf(s):
try:
import pyamf
from pyamf import remoting
except ImportError:
except ImportError: # pragma nocover
return None
envelope = remoting.decode(s)
@ -102,7 +102,6 @@ def pretty_amf(s):
data = {}
data['amfVersion'] = envelope.amfVersion
for target, message in iter(envelope):
one_message = {}
if hasattr(message, 'status'):

View File

@ -13,82 +13,91 @@ class TestContentView:
def test_get_view_func(self):
f = cv.get_view_func(
cv.VIEW_HEX,
cv.get("Hex"),
flow.ODictCaseless(),
"foo"
)
assert f is cv.view_hex
assert f.name == "Hex"
f = cv.get_view_func(
cv.VIEW_AUTO,
cv.get("Auto"),
flow.ODictCaseless(),
"foo"
)
assert f is cv.view_raw
assert f.name == "Raw"
f = cv.get_view_func(
cv.VIEW_AUTO,
cv.get("Auto"),
flow.ODictCaseless(
[["content-type", "text/html"]],
),
"foo"
)
assert f is cv.view_html
assert f.name == "HTML"
f = cv.get_view_func(
cv.VIEW_AUTO,
cv.get("Auto"),
flow.ODictCaseless(
[["content-type", "text/flibble"]],
),
"foo"
)
assert f is cv.view_raw
assert f.name == "Raw"
f = cv.get_view_func(
cv.VIEW_AUTO,
cv.get("Auto"),
flow.ODictCaseless(
[["content-type", "text/flibble"]],
),
"<xml></xml>"
)
assert f is cv.view_xml
assert f.name == "XML"
try:
import pyamf
f = cv.get_view_func(
cv.VIEW_AUTO,
cv.get("Auto"),
flow.ODictCaseless(
[["content-type", "application/x-amf"]],
),
""
)
assert f is cv.view_amf
assert f.name == "AMF"
except ImportError:
pass
def test_view_urlencoded(self):
d = utils.urlencode([("one", "two"), ("three", "four")])
assert cv.view_urlencoded([], d, 100)
assert not cv.view_urlencoded([], "foo", 100)
v = cv.ViewURLEncoded()
assert v([], d, 100)
assert not v([], "foo", 100)
def test_view_html(self):
v = cv.ViewHTML()
s = "<html><br><br></br><p>one</p></html>"
assert cv.view_html([], s, 1000)
assert v([], s, 1000)
s = "gobbledygook"
assert not cv.view_html([], s, 1000)
assert not v([], s, 1000)
def test_view_html_outline(self):
v = cv.ViewHTMLOutline()
s = "<html><br><br></br><p>one</p></html>"
assert v([], s, 1000)
def test_view_json(self):
cv.VIEW_CUTOFF = 100
assert cv.view_json([], "{}", 1000)
assert not cv.view_json([], "{", 1000)
assert cv.view_json([], "[" + ",".join(["0"]*cv.VIEW_CUTOFF) + "]", 1000)
assert cv.view_json([], "[1, 2, 3, 4, 5]", 5)
v = cv.ViewJSON()
assert v([], "{}", 1000)
assert not v([], "{", 1000)
assert v([], "[" + ",".join(["0"]*cv.VIEW_CUTOFF) + "]", 1000)
assert v([], "[1, 2, 3, 4, 5]", 5)
def test_view_xml(self):
assert cv.view_xml([], "<foo></foo>", 1000)
assert not cv.view_xml([], "<foo>", 1000)
v = cv.ViewXML()
assert v([], "<foo></foo>", 1000)
assert not v([], "<foo>", 1000)
s = """<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet title="XSL_formatting"?>
<rss
@ -97,44 +106,49 @@ class TestContentView:
version="2.0">
</rss>
"""
assert cv.view_xml([], s, 1000)
assert v([], s, 1000)
def test_view_raw(self):
assert cv.view_raw([], "foo", 1000)
v = cv.ViewRaw()
assert v([], "foo", 1000)
def test_view_javascript(self):
assert cv.view_javascript([], "[1, 2, 3]", 100)
assert cv.view_javascript([], "[1, 2, 3", 100)
assert cv.view_javascript([], "function(a){[1, 2, 3]}", 100)
v = cv.ViewJavaScript()
assert v([], "[1, 2, 3]", 100)
assert v([], "[1, 2, 3", 100)
assert v([], "function(a){[1, 2, 3]}", 100)
def test_view_hex(self):
assert cv.view_hex([], "foo", 1000)
v = cv.ViewHex()
assert v([], "foo", 1000)
def test_view_image(self):
v = cv.ViewImage()
p = tutils.test_data.path("data/image.png")
assert cv.view_image([], file(p).read(), sys.maxint)
assert v([], file(p).read(), sys.maxint)
p = tutils.test_data.path("data/image.gif")
assert cv.view_image([], file(p).read(), sys.maxint)
assert v([], file(p).read(), sys.maxint)
p = tutils.test_data.path("data/image-err1.jpg")
assert cv.view_image([], file(p).read(), sys.maxint)
assert v([], file(p).read(), sys.maxint)
p = tutils.test_data.path("data/image.ico")
assert cv.view_image([], file(p).read(), sys.maxint)
assert v([], file(p).read(), sys.maxint)
assert not cv.view_image([], "flibble", sys.maxint)
assert not v([], "flibble", sys.maxint)
def test_view_amf(self):
try:
import pyamf
v = cv.ViewAMF()
p = tutils.test_data.path("data/test.amf")
assert cv.view_amf([], file(p).read(), sys.maxint)
assert v([], file(p).read(), sys.maxint)
except ImportError:
pass
def test_view_multipart(self):
view = cv.ViewMultipart()
v = """
--AaB03x
Content-Disposition: form-data; name="submit-name"
@ -145,24 +159,24 @@ Larry
h = flow.ODictCaseless(
[("Content-Type", "multipart/form-data; boundary=AaB03x")]
)
assert cv.view_multipart(h, v, 1000)
assert view(h, v, 1000)
h = flow.ODictCaseless()
assert not cv.view_multipart(h, v, 1000)
assert not view(h, v, 1000)
h = flow.ODictCaseless(
[("Content-Type", "multipart/form-data")]
)
assert not cv.view_multipart(h, v, 1000)
assert not view(h, v, 1000)
h = flow.ODictCaseless(
[("Content-Type", "unparseable")]
)
assert not cv.view_multipart(h, v, 1000)
assert not view(h, v, 1000)
def test_get_content_view(self):
r = cv.get_content_view(
cv.VIEW_RAW,
cv.get("Raw"),
[["content-type", "application/json"]],
"[1, 2, 3]",
1000
@ -170,7 +184,7 @@ Larry
assert "Raw" in r[0]
r = cv.get_content_view(
cv.VIEW_AUTO,
cv.get("Auto"),
[["content-type", "application/json"]],
"[1, 2, 3]",
1000
@ -178,7 +192,7 @@ Larry
assert r[0] == "JSON"
r = cv.get_content_view(
cv.VIEW_AUTO,
cv.get("Auto"),
[["content-type", "application/json"]],
"[1, 2",
1000
@ -186,7 +200,7 @@ Larry
assert "Raw" in r[0]
r = cv.get_content_view(
cv.VIEW_AUTO,
cv.get("Auto"),
[
["content-type", "application/json"],
["content-encoding", "gzip"]
@ -198,7 +212,7 @@ Larry
assert "JSON" in r[0]
r = cv.get_content_view(
cv.VIEW_XML,
cv.get("XML"),
[
["content-type", "application/json"],
["content-encoding", "gzip"]