-
Notifications
You must be signed in to change notification settings - Fork 103
Expand file tree
/
Copy pathserver.py
More file actions
152 lines (127 loc) · 4.89 KB
/
server.py
File metadata and controls
152 lines (127 loc) · 4.89 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import os
import platform
import socket
import subprocess
import time
from .client import Client
from .exceptions import ProxyServerError
class RemoteServer(object):
def __init__(self, host, port):
"""
Initialises a RemoteServer object
:param host: The host of the proxy server.
:param port: The port of the proxy server.
"""
self.host = host
self.port = port
@property
def url(self):
"""
Gets the url that the proxy is running on. This is not the URL clients
should connect to.
"""
return "http://%s:%d" % (self.host, self.port)
def create_proxy(self, params=None):
"""
Gets a client class that allow to set all the proxy details that you
may need to.
:param dict params: Dictionary where you can specify params
like httpProxy and httpsProxy
"""
params = params if params is not None else {}
client = Client(self.url[7:], params)
return client
def _is_listening(self):
try:
socket_ = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_.settimeout(1)
socket_.connect((self.host, self.port))
socket_.close()
return True
except socket.error:
return False
class Server(RemoteServer):
def __init__(self, path='browsermob-proxy', options=None):
"""
Initialises a Server object
:param str path: Path to the browsermob proxy batch file
:param dict options: Dictionary that can hold the port.
More items will be added in the future.
This defaults to an empty dictionary
"""
options = options if options is not None else {}
path_var_sep = ':'
if platform.system() == 'Windows':
path_var_sep = ';'
if not path.endswith('.bat'):
path += '.bat'
exec_not_on_path = True
for directory in os.environ['PATH'].split(path_var_sep):
if(os.path.isfile(os.path.join(directory, path))):
exec_not_on_path = False
break
if not os.path.isfile(path) and exec_not_on_path:
raise ProxyServerError("Browsermob-Proxy binary couldn't be found "
"in path provided: %s" % path)
self.path = path
self.host = options.get('address', '0.0.0.0')
self.port = options.get('port', 8080)
port_range = (self.port + 1, self.port + 501)
proxy_port_range = options.get('proxyPortRange', port_range)
ttl = options.get('ttl', 0)
use_littleproxy = options.get('use-littleproxy', True)
self.process = None
if platform.system() == 'Darwin':
self.command = ['sh']
else:
self.command = []
self.command += [path,
'--address=%s' % self.host,
'--port=%s' % self.port,
'--proxyPortRange=%s-%s' % proxy_port_range,
'--ttl=%s' % ttl,
'--use-littleproxy=%s' % use_littleproxy]
def start(self, options=None):
"""
This will start the browsermob proxy and then wait until it can
interact with it
:param dict options: Dictionary that can hold the path and filename
of the log file with resp. keys of `log_path` and `log_file`
"""
if options is None:
options = {}
log_path = options.get('log_path', os.getcwd())
log_file = options.get('log_file', 'server.log')
retry_sleep = options.get('retry_sleep', 0.5)
retry_count = options.get('retry_count', 60)
log_path_name = os.path.join(log_path, log_file)
self.log_file = open(log_path_name, 'w')
self.process = subprocess.Popen(self.command,
stdout=self.log_file,
stderr=subprocess.STDOUT)
count = 0
while not self._is_listening():
if self.process.poll():
message = (
"The Browsermob-Proxy server process failed to start. "
"Check {0}"
"for a helpful error message.".format(self.log_file))
raise ProxyServerError(message)
time.sleep(retry_sleep)
count += 1
if count == retry_count:
self.stop()
raise ProxyServerError("Can't connect to Browsermob-Proxy")
def stop(self):
"""
This will stop the process running the proxy
"""
if self.process.poll() is not None:
return
try:
self.process.kill()
self.process.wait()
except AttributeError:
# kill may not be available under windows environment
pass
self.log_file.close()