-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathhttp.py
More file actions
132 lines (103 loc) · 4.29 KB
/
Copy pathhttp.py
File metadata and controls
132 lines (103 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import Cookie
import formatters
import httplib2
import json
import oauth2 as oauth
import os
import subprocess
import version
class Http(object):
def __init__(self, args, logger, verb):
self.args = args
self.logger = logger
self.verb = verb
def run(self, url, path, pipe=None, headers=None, cookies=None, body=""):
self.url = url
host = self.url.netloc
httpclient = self.init_httpclient()
httpclient.follow_redirects = False
httplib2.debuglevel = self.args.debuglevel
# check for authentication credentials
if "@" in host:
split = host.split("@")
if len(split) > 1:
host = split[1]
creds = split[0].split(":")
httpclient.add_credentials(creds[0], creds[1])
else:
host = split[0]
uri = "{0}://{1}{2}".format(self.url.scheme, host, path)
if not self.args.disable_cookies:
self.set_request_cookies(cookies, headers)
if not "host" in headers:
headers["host"] = host
if not "accept-encoding" in headers:
headers["accept-encoding"] = "gzip, deflate"
if not "user-agent" in headers:
headers["user-agent"] = "httpsh/" + version.VERSION
self.logger.print_text("Connecting to " + uri)
response, content = httpclient.request(
uri, method=self.verb, body=body, headers=headers)
self.handle_response(response, content, headers, cookies, pipe)
def init_httpclient(self):
http = None
keysfile = os.path.join(os.path.expanduser("~"),
".httpshell", self.url.netloc + ".json")
if os.path.isfile(keysfile):
try:
with open(keysfile, "r") as file:
keys = json.load(file)
token = None
consumer = oauth.Consumer(keys["consumer"]["consumer-key"],
keys["consumer"]["consumer-secret"])
if "access" in keys:
token = oauth.Token(keys["access"]["access-token"],
keys["access"]["access-token-secret"])
http = oauth.Client(consumer, token)
self.logger.print_text("Using OAuth config in " + keysfile)
except:
self.logger.print_error(
"Failed reading OAuth data from: " + keysfile)
else:
http = httplib2.Http()
return http
def set_request_cookies(self, cookies, headers):
if self.url.netloc in cookies:
l = []
cookie = cookies[self.url.netloc]
# very basic cookie support atm. no expiry, etc.
for morsel in cookie.values():
l.append(morsel.key + "=" + morsel.coded_value)
headers["cookie"] = "; ".join(l)
def handle_response(self, response, content, headers, cookies, pipe=None):
self.logger.print_response_code(response)
if self.args.show_headers:
self.logger.print_headers(headers.items(), True)
self.logger.print_headers(response.items())
if not self.args.disable_cookies:
self.store_response_cookies(response, cookies)
if self.args.auto_format:
mimetype = response["content-type"]
if mimetype:
content = formatters.format_by_mimetype(
content, mimetype.split(";")[0])
if pipe:
content = self.pipe_data(pipe, content)
self.logger.print_data(content)
def store_response_cookies(self, response, cookies):
if "set-cookie" in response:
header = response["set-cookie"]
cookie = Cookie.SimpleCookie(header)
cookies[self.url.netloc] = cookie
# pipes output to external commands like xmllint, tidy for filtering
def pipe_data(self, command, data):
result = None
p = subprocess.Popen(command, shell=True, bufsize=-1,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
output, error = p.communicate(data)
if error:
self.logger.print_text()
self.logger.print_error(error.decode("utf-8"))
else:
result = output.decode("utf-8")
return result