Merge branch 'master' into tcp_proxy

This commit is contained in:
Maximilian Hils 2014-01-09 18:06:12 +01:00
commit f83508d4bf
6 changed files with 40 additions and 21 deletions

View File

@ -1,4 +1,4 @@
[![Build Status](https://travis-ci.org/mitmproxy/pathod.png)](https://travis-ci.org/mitmproxy/pathod) [![Coverage Status](https://coveralls.io/repos/mitmproxy/pathod/badge.png)](https://coveralls.io/r/mitmproxy/pathod) [![Build Status](https://travis-ci.org/mitmproxy/pathod.png?branch=master)](https://travis-ci.org/mitmproxy/pathod) [![Coverage Status](https://coveralls.io/repos/mitmproxy/pathod/badge.png?branch=master)](https://coveralls.io/r/mitmproxy/pathod)
__pathod__ is a collection of pathological tools for testing and torturing HTTP __pathod__ is a collection of pathological tools for testing and torturing HTTP
clients and servers. The project has three components: clients and servers. The project has three components:

View File

@ -765,11 +765,12 @@ class _Message(object):
def resolve(self, settings, request_host): def resolve(self, settings, request_host):
tokens = self.tokens[:] tokens = self.tokens[:]
if not self.raw: if not self.raw:
if self.body and not utils.get_header("Content-Length", self.headers): if not utils.get_header("Content-Length", self.headers):
length = 0 if not self.body else len(self.body.value.get_generator(settings))
tokens.append( tokens.append(
Header( Header(
ValueLiteral("Content-Length"), ValueLiteral("Content-Length"),
ValueLiteral(str(len(self.body.value.get_generator(settings)))), ValueLiteral(str(length)),
) )
) )
if request_host: if request_host:

View File

@ -15,9 +15,15 @@ class Response:
def __repr__(self): def __repr__(self):
return "Response(%s - %s)"%(self.status_code, self.msg) return "Response(%s - %s)"%(self.status_code, self.msg)
SSLVERSIONS = {
1: tcp.TLSv1_METHOD,
2: tcp.SSLv2_METHOD,
3: tcp.SSLv3_METHOD,
4: tcp.SSLv23_METHOD,
}
class Pathoc(tcp.TCPClient): class Pathoc(tcp.TCPClient):
def __init__(self, host, port, ssl=None, sni=None, clientcert=None): def __init__(self, host, port, ssl=None, sni=None, sslversion=1, clientcert=None):
tcp.TCPClient.__init__(self, host, port) tcp.TCPClient.__init__(self, host, port)
self.settings = dict( self.settings = dict(
staticdir = os.getcwd(), staticdir = os.getcwd(),
@ -25,20 +31,21 @@ class Pathoc(tcp.TCPClient):
) )
self.ssl, self.sni = ssl, sni self.ssl, self.sni = ssl, sni
self.clientcert = clientcert self.clientcert = clientcert
self.sslversion = SSLVERSIONS[sslversion]
def http_connect(self, connect_to, wfile, rfile): def http_connect(self, connect_to):
wfile.write( self.wfile.write(
'CONNECT %s:%s HTTP/1.1\r\n'%tuple(connect_to) + 'CONNECT %s:%s HTTP/1.1\r\n'%tuple(connect_to) +
'\r\n' '\r\n'
) )
wfile.flush() self.wfile.flush()
l = rfile.readline() l = self.rfile.readline()
if not l: if not l:
raise PathocError("Proxy CONNECT failed") raise PathocError("Proxy CONNECT failed")
parsed = http.parse_response_line(l) parsed = http.parse_response_line(l)
if not parsed[1] == 200: if not parsed[1] == 200:
raise PathocError("Proxy CONNECT failed: %s - %s"%(parsed[1], parsed[2])) raise PathocError("Proxy CONNECT failed: %s - %s"%(parsed[1], parsed[2]))
headers = http.read_headers(rfile) headers = http.read_headers(self.rfile)
def connect(self, connect_to=None): def connect(self, connect_to=None):
""" """
@ -47,10 +54,10 @@ class Pathoc(tcp.TCPClient):
""" """
tcp.TCPClient.connect(self) tcp.TCPClient.connect(self)
if connect_to: if connect_to:
self.http_connect(connect_to, self.wfile, self.rfile) self.http_connect(connect_to)
if self.ssl: if self.ssl:
try: try:
self.convert_to_ssl(sni=self.sni, cert=self.clientcert) self.convert_to_ssl(sni=self.sni, cert=self.clientcert, method=self.sslversion)
except tcp.NetLibError, v: except tcp.NetLibError, v:
raise PathocError(str(v)) raise PathocError(str(v))

View File

@ -123,8 +123,8 @@ class PathodHandler(tcp.BaseHandler):
) )
try: try:
content = http.read_http_body_request( content = http.read_http_body(
self.rfile, self.wfile, headers, httpversion, None self.rfile, headers, None, True
) )
except http.HttpError, s: except http.HttpError, s:
s = str(s) s = str(s)

15
pathoc
View File

@ -60,7 +60,11 @@ if __name__ == "__main__":
"-i", dest="sni", type=str, default=False, "-i", dest="sni", type=str, default=False,
help="SSL Server Name Indication" help="SSL Server Name Indication"
) )
group.add_argument(
"--sslversion", dest="sslversion", type=int, default=1,
choices=[1, 2, 3],
help="Use a specified protocol - TLSv1, SSLv2, SSLv3. Default to TLSv1."
)
group = parser.add_argument_group( group = parser.add_argument_group(
'Controlling Output', 'Controlling Output',
@ -124,7 +128,14 @@ if __name__ == "__main__":
try: try:
for i in range(args.repeat): for i in range(args.repeat):
p = pathoc.Pathoc(args.host, port, ssl=args.ssl, sni=args.sni, clientcert=args.clientcert) p = pathoc.Pathoc(
args.host,
port,
ssl=args.ssl,
sni=args.sni,
sslversion=args.sslversion,
clientcert=args.clientcert
)
try: try:
p.connect(connect_to) p.connect(connect_to)
except (tcp.NetLibError, pathoc.PathocError), v: except (tcp.NetLibError, pathoc.PathocError), v:

View File

@ -136,16 +136,16 @@ class TestDaemon(_TestDaemon):
def test_connect_fail(self): def test_connect_fail(self):
to = ("foobar", 80) to = ("foobar", 80)
c = pathoc.Pathoc("127.0.0.1", self.d.port) c = pathoc.Pathoc("127.0.0.1", self.d.port)
r, w = cStringIO.StringIO(), cStringIO.StringIO() c.rfile, c.wfile = cStringIO.StringIO(), cStringIO.StringIO()
tutils.raises("connect failed", c.http_connect, to, w, r) tutils.raises("connect failed", c.http_connect, to)
r = cStringIO.StringIO( c.rfile = cStringIO.StringIO(
"HTTP/1.1 500 OK\r\n" "HTTP/1.1 500 OK\r\n"
) )
tutils.raises("connect failed", c.http_connect, to, w, r) tutils.raises("connect failed", c.http_connect, to)
r = cStringIO.StringIO( c.rfile = cStringIO.StringIO(
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
) )
c.http_connect(to, w, r) c.http_connect(to)