aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libpathod/app.py3
-rw-r--r--libpathod/language.py25
-rw-r--r--libpathod/pathod.py1
-rw-r--r--libpathod/templates/docs_lang.html21
-rwxr-xr-xpathoc19
-rw-r--r--test/test_language.py21
-rw-r--r--test/test_pathod.py2
7 files changed, 84 insertions, 8 deletions
diff --git a/libpathod/app.py b/libpathod/app.py
index 1fcfa078..78c0fc4a 100644
--- a/libpathod/app.py
+++ b/libpathod/app.py
@@ -1,6 +1,7 @@
import logging, pprint, cStringIO
from flask import Flask, jsonify, render_template, request, abort, make_response
import version, language, utils
+from netlib import http_uastrings
logging.basicConfig(level="DEBUG")
app = Flask(__name__)
@@ -61,7 +62,7 @@ def docs_pathod():
@app.route('/docs/language')
def docs_language():
- return render("docs_lang.html", True, section="docs")
+ return render("docs_lang.html", True, section="docs", uastrings=http_uastrings.UASTRINGS)
@app.route('/docs/pathoc')
diff --git a/libpathod/language.py b/libpathod/language.py
index 79657b37..30788569 100644
--- a/libpathod/language.py
+++ b/libpathod/language.py
@@ -2,7 +2,7 @@ import operator, string, random, mmap, os, time, copy
import abc
from email.utils import formatdate
import contrib.pyparsing as pp
-from netlib import http_status, tcp
+from netlib import http_status, tcp, http_uastrings
import utils
@@ -449,6 +449,28 @@ class ShortcutLocation(_Header):
return ShortcutLocation(self.value.freeze(settings))
+class ShortcutUserAgent(_Header):
+ def __init__(self, value):
+ self.specvalue = value
+ if isinstance(value, basestring):
+ value = ValueLiteral(http_uastrings.get_by_shortcut(value)[2])
+ _Header.__init__(self, ValueLiteral("User-Agent"), value)
+
+ @classmethod
+ def expr(klass):
+ e = pp.Literal("u").suppress()
+ u = reduce(operator.or_, [pp.Literal(i[1]) for i in http_uastrings.UASTRINGS])
+ e += u | Value
+ return e.setParseAction(lambda x: klass(*x))
+
+ def spec(self):
+ return "u%s"%self.specvalue
+
+ def freeze(self, settings):
+ return ShortcutUserAgent(self.value.freeze(settings))
+
+
+
class Body(_Component):
def __init__(self, value):
self.value = value
@@ -824,6 +846,7 @@ class Response(_Message):
InjectAt,
ShortcutContentType,
ShortcutLocation,
+ ShortcutUserAgent,
Raw,
Reason
)
diff --git a/libpathod/pathod.py b/libpathod/pathod.py
index f327ade4..d52af15b 100644
--- a/libpathod/pathod.py
+++ b/libpathod/pathod.py
@@ -30,7 +30,6 @@ class PathodHandler(tcp.BaseHandler):
if self.server.explain:
crafted = crafted.freeze(self.server.request_settings, None)
- print crafted
response_log = language.serve(crafted, self.wfile, self.server.request_settings, None)
log = dict(
type = "crafted",
diff --git a/libpathod/templates/docs_lang.html b/libpathod/templates/docs_lang.html
index f01d61fb..26672bb2 100644
--- a/libpathod/templates/docs_lang.html
+++ b/libpathod/templates/docs_lang.html
@@ -155,6 +155,27 @@
calculate a Content-Length header if a body is set.
</td>
</tr>
+
+ <tr>
+ <td> u<a href="#valuespec">VALUE</a> <br> uSHORTCUT </td>
+
+ <td>
+
+ Set a User-Agent header on this request. You can
+ specify either a complete <a
+ href="#valuespec">VALUE</a>, or a User-Agent shortcut:
+
+ <table class="table table-condensed">
+ {% for i in uastrings %}
+ <tr>
+ <td><b>{{ i[1] }}</b></td>
+ <td>{{ i[0] }}</td>
+ </tr>
+ {% endfor %}
+ </table>
+
+ </td>
+ </tr>
</tbody>
</table>
</div>
diff --git a/pathoc b/pathoc
index 96cb9f0a..1d3f6004 100755
--- a/pathoc
+++ b/pathoc
@@ -1,10 +1,22 @@
#!/usr/bin/env python
import argparse, sys
from libpathod import pathoc, version, language
-from netlib import tcp
+from netlib import tcp, http_uastrings
if __name__ == "__main__":
- parser = argparse.ArgumentParser(description='A perverse HTTP client.')
+ preparser = argparse.ArgumentParser(add_help=False)
+ preparser.add_argument(
+ "--show-uas", dest="showua", action="store_true", default=False,
+ help="Print user agent shortcuts and exit."
+ )
+ pa = preparser.parse_known_args()[0]
+ if pa.showua:
+ print "User agent strings:"
+ for i in http_uastrings.UASTRINGS:
+ print " ", i[1], i[0]
+ sys.exit(0)
+
+ parser = argparse.ArgumentParser(description='A perverse HTTP client.', parents=[preparser])
parser.add_argument(
"-i", dest="sni", type=str, default=False,
help="SSL Server Name Indication"
@@ -33,8 +45,9 @@ if __name__ == "__main__":
'request', type=str, nargs="+",
help='Request specification'
)
+
group = parser.add_argument_group(
- 'Controlling Output',
+ 'Controlling Output',
"""
Some of these options expand generated values for logging - if
you're generating large data, use them with caution.
diff --git a/test/test_language.py b/test/test_language.py
index b02a89dd..d7f7b4cc 100644
--- a/test/test_language.py
+++ b/test/test_language.py
@@ -297,11 +297,30 @@ class TestHeaders:
v3 = v2.freeze({})
assert v2.value.val == v3.value.val
- def test_shortcut_content_type(self):
+ def test_shortcuts(self):
assert language.parse_response({}, "400:c'foo'").headers[0].key.val == "Content-Type"
assert language.parse_response({}, "400:l'foo'").headers[0].key.val == "Location"
+ assert 'Android' in language.parse_response({}, "400:ua").headers[0].value.val
+ assert language.parse_response({}, "400:ua").headers[0].key.val == "User-Agent"
+class TestShortcutUserAgent:
+ def test_location_shortcut(self):
+ e = language.ShortcutUserAgent.expr()
+ v = e.parseString("ua")[0]
+ assert "Android" in str(v.value)
+ assert v.spec() == "ua"
+ assert v.key.val == "User-Agent"
+
+ v = e.parseString("u'foo'")[0]
+ assert "foo" in str(v.value)
+ assert "foo" in v.spec()
+
+ v = e.parseString("u@100'")[0]
+ assert len(str(v.freeze({}).value)) > 100
+ v2 = v.freeze({})
+ v3 = v2.freeze({})
+ assert v2.value.val == v3.value.val
class Test_Action:
diff --git a/test/test_pathod.py b/test/test_pathod.py
index 30498c3a..46b1fb1d 100644
--- a/test/test_pathod.py
+++ b/test/test_pathod.py
@@ -35,7 +35,7 @@ class TestNoWeb(tutils.DaemonTests):
class TestTimeout(tutils.DaemonTests):
- timeout = 0.01
+ timeout = 0.001
def test_noweb(self):
# FIXME: Add float values to spec language, reduce test timeout to
# increase test performance