Changeset 40 for trunk/bin/bletchley-http2py
- Timestamp:
- 03/17/13 22:26:27 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/bin/bletchley-http2py
r39 r40 1 #!/usr/bin/env python 2 3 # Requires Python 2.7+1 #!/usr/bin/env python3 2 3 # Requires Python 3+ 4 4 5 5 ''' 6 This script reads a raw HTTP request from stdin and writes to stdout 7 a Python script. The generated script sends the same (or a very similar) 8 request using the httplib/http.client libraries. 6 This script reads a raw HTTP request and writes to stdout a Python 7 script. The generated script sends the same (or a very similar) 8 request using the standard httplib/http.client library, or optionally 9 using the more user friendly python-requests library. 9 10 10 11 Certainly if you have a raw request, you could simply send it via TCP … … 34 35 import sys 35 36 import argparse 36 try:37 from lxml import etree38 except:39 sys.stderr.write('ERROR: Could not import lxml module. Ensure it is installed.\n')40 sys.stderr.write(' Under Debian, the package name is "python-lxml"\n.')41 sys.exit(1)42 37 43 38 parser = argparse.ArgumentParser( … … 48 43 ' For more information, see: http://code.google.com/p/bletchley/wiki/Overview') 49 44 parser.add_argument( 50 'requestfile', type= file, nargs='?', default=sys.stdin,45 'requestfile', type=open, nargs='?', default=sys.stdin, 51 46 help='A file containing an HTTP request. Defaults to stdin if omitted.') 52 47 parser.add_argument( 53 '--burp', action='store_true', help='Input file is a XML export from Burp.' 54 ' (First request in file is used.)') 48 '--requests', action='store_true', help='Generate a script that uses the' 49 ' python-requests module rather than httplib/http.client (experimental).') 50 55 51 args = parser.parse_args() 56 57 if args.burp: 58 safe_parser = etree.ETCompatXMLParser(resolve_entities=False) 59 root = etree.parse(args.requestfile, parser=safe_parser) 60 input_req = root.xpath('/items/item/request')[0].text 61 root = None 62 else: 63 input_req = args.requestfile.read() 64 52 input_req = args.requestfile.read() 65 53 66 54 … … 79 67 port = 80 80 68 use_ssl = False 69 protocol = 'http' 81 70 82 71 headers = [] … … 85 74 break 86 75 # Handle header line continuations 87 if l[0] == '\t':76 if l[0] in ' \t': 88 77 if len(headers) == 0: 89 78 continue … … 108 97 if port == 443: 109 98 use_ssl = True 99 protocol = 'https' 110 100 else: 111 101 host = value 112 102 113 103 114 print('''#!/usr/bin/env python 104 formatted_body = '\n '.join([repr(body[i:i+40].encode()) for i in range(0,len(body),40)]) 105 if formatted_body == '': 106 formatted_body = "b''" 107 108 109 if args.requests: 110 print('''#!/usr/bin/env python3 115 111 116 112 import sys 117 # function with either Python 2.7 or 3.x118 113 try: 119 import http.client as httpc114 import requests 120 115 except: 121 import httplib as httpc 116 sys.stderr.write('ERROR: Could not import requests module. Ensure it is installed.\\n') 117 sys.stderr.write(' Under Debian, the package name is "python3-requests"\\n.') 118 sys.exit(1) 119 120 121 # TODO: ensure the host, port, and SSL settings are correct. 122 host = %s 123 port = %s 124 protocol = %s 125 ''' % (repr(host),repr(port),repr(protocol))) 126 127 headers = dict(headers) 128 # XXX: We don't currently support exactly formatted header 129 # continuations with python requests, but this should be 130 # semantically equivalent. 131 for h in headers.keys(): 132 headers[h] = ' '.join(headers[h]) 133 134 print(''' 135 session = requests.Session() 136 # TODO: use "data" to supply any parameters to be included in the request 137 def sendRequest(session, data=None): 138 method = %s 139 path = %s 140 headers = %s 141 url = "%%s://%%s:%%d%%s" %% (protocol,host,port,path) 142 body = (%s) 143 144 return session.request(method, url, headers=headers, data=body) 145 ''' % (repr(method), repr(path), repr(headers), formatted_body)) 146 147 print(''' 148 149 def fetch(data): 150 global session 151 ret_val = None 152 153 # TODO: customize code here to retrieve what you need from the response(s) 154 # For information on the response object's interface, see: 155 # http://docs.python-requests.org/en/latest/api/#requests.Response 156 response = sendRequest(session, data) 157 print(response.headers) 158 print(repr(response.content)) 159 160 return ret_val 161 162 data = '' 163 fetch(data) 122 164 ''') 123 165 124 166 125 print(''' 167 168 else: 169 print('''#!/usr/bin/env python3 170 171 import sys 172 import http.client as httpc 173 174 126 175 # TODO: ensure the host, port, and SSL settings are correct. 127 176 host = %s … … 130 179 ''' % (repr(host),repr(port),repr(use_ssl))) 131 180 132 chunked_body = '\n '.join([repr(body[i:i+40]) for i in range(0,len(body),40)]) 133 if chunked_body == '': 134 chunked_body = "''" 135 136 print(''' 181 print(''' 137 182 # TODO: use "data" to supply any parameters to be included in the request 138 183 def sendRequest(connection, data=None): … … 142 187 143 188 connection.putrequest(method, path) 144 ''' % (repr(method), repr(path), chunked_body))145 146 for name,values in headers:147 if len(values) > 1:148 continuations = ','.join([repr(v) for v in values[1:]])149 print(''' connection.putheader(%s, %s, %s)''' % (repr(name),repr(values[0]),continuations))150 else:151 print(''' connection.putheader(%s, %s)''' % (repr(name),repr(values[0])))152 153 print('''189 ''' % (repr(method), repr(path), formatted_body)) 190 191 for name,values in headers: 192 if len(values) > 1: 193 continuations = ','.join([repr(v) for v in values[1:]]) 194 print(''' connection.putheader(%s, %s, %s)''' % (repr(name),repr(values[0]),continuations)) 195 else: 196 print(''' connection.putheader(%s, %s)''' % (repr(name),repr(values[0]))) 197 198 print(''' 154 199 if len(body) > 0: 155 200 connection.putheader('Content-Length', len(body)) … … 161 206 162 207 def newConnection(): 163 connection = None164 208 if use_ssl: 165 209 return httpc.HTTPSConnection(host, port)
Note: See TracChangeset
for help on using the changeset viewer.