forked from abhinavsingh/proxy.py
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplugin_examples.py
More file actions
109 lines (79 loc) · 3.26 KB
/
plugin_examples.py
File metadata and controls
109 lines (79 loc) · 3.26 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
"""
proxy.py
~~~~~~~~
Lightweight Programmable HTTP, HTTPS, WebSockets Proxy Server in a single Python file.
:copyright: (c) 2013-present by Abhinav Singh.
:license: BSD, see LICENSE for more details.
"""
import os
import tempfile
import time
from typing import Optional, BinaryIO
from urllib import parse as urlparse
import proxy
class RedirectToCustomServerPlugin(proxy.HttpProxyBasePlugin):
"""Modifies client request to redirect all incoming requests to a fixed server address."""
UPSTREAM_SERVER = b'http://localhost:8899'
def before_upstream_connection(self) -> None:
# Redirect all non-https requests to inbuilt WebServer.
if self.request.method != b'CONNECT':
self.request.url = urlparse.urlsplit(self.UPSTREAM_SERVER)
self.request.set_host_port()
def on_upstream_connection(self) -> None:
pass
def handle_upstream_response(self, raw: bytes) -> bytes:
return raw
def on_upstream_connection_close(self) -> None:
pass
class FilterByUpstreamHostPlugin(proxy.HttpProxyBasePlugin):
"""Drop traffic by inspecting upstream host."""
FILTERED_DOMAINS = [b'google.com', b'www.google.com']
def before_upstream_connection(self) -> None:
if self.request.host in self.FILTERED_DOMAINS:
raise proxy.HttpRequestRejected(
status_code=418, reason=b'I\'m a tea pot')
def on_upstream_connection(self) -> None:
pass
def handle_upstream_response(self, raw: bytes) -> bytes:
return raw
def on_upstream_connection_close(self) -> None:
pass
class CacheResponsesPlugin(proxy.HttpProxyBasePlugin):
"""Caches Upstream Server Responses."""
CACHE_DIR = tempfile.gettempdir()
def __init__(self, config: proxy.HttpProtocolConfig, client: proxy.TcpClientConnection,
request: proxy.HttpParser) -> None:
super().__init__(config, client, request)
self.cache_file_path: Optional[str] = None
self.cache_file: Optional[BinaryIO] = None
def before_upstream_connection(self) -> None:
pass
def on_upstream_connection(self) -> None:
self.cache_file_path = os.path.join(
self.CACHE_DIR,
'%s-%s.txt' % (proxy.text_(self.request.host), str(time.time())))
self.cache_file = open(self.cache_file_path, "wb")
def handle_upstream_response(self, chunk: bytes) -> bytes:
if self.cache_file:
self.cache_file.write(chunk)
return chunk
def on_upstream_connection_close(self) -> None:
if self.cache_file:
self.cache_file.close()
proxy.logger.info('Cached response at %s', self.cache_file_path)
class ManInTheMiddlePlugin(proxy.HttpProxyBasePlugin):
"""Modifies upstream server responses."""
def before_upstream_connection(self) -> None:
pass
def on_upstream_connection(self) -> None:
pass
def handle_upstream_response(self, raw: bytes) -> bytes:
body = b'Hello from man in the middle'
response = proxy.CRLF.join([
b'HTTP/1.1 200 OK',
b'Content-Length: ' + proxy.bytes_(str(len(body))),
proxy.CRLF,
]) + body
return response
def on_upstream_connection_close(self) -> None:
pass