transproxpy.py
author Radek Brich <radek.brich@devl.cz>
Sun, 23 Feb 2014 21:32:04 +0100
changeset 0 cef7ea3df9c2
permissions -rwxr-xr-x
Transproxpy.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     1
#! /usr/bin/env python3
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     2
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     3
"""transproxpy - Simple forwarding HTTP server
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     4
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     5
Works as transparent proxy - client doesn't need to know about it
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     6
and nothing has to be set on end-user machine.
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     7
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     8
Transproxpy listens on specified port, resends requests to remote server
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     9
(as found in Host header) and resends responses from the server back to the client.
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    10
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    11
Should be installed on gateway machine, which routes traffic from clients
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    12
to remote servers. Configure iptables like this:
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    13
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    14
    # Redirect all requests incoming from interface wlan0 and destined to 10.0.0.5:80
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    15
    iptables -t nat -A PREROUTING -i wlan0 -p tcp -d 10.0.0.5 --dport 80 -j REDIRECT --to-port 8080
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    16
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    17
Intented usage is to monitor HTTP traffic and manipulate request/response headers and content,
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    18
for debugging purposes and fun.
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    19
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    20
2014-02-23 Radek Brich
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    21
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    22
"""
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    23
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    24
from http.server import HTTPServer, BaseHTTPRequestHandler
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    25
from http.client import HTTPConnection, HTTPException
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    26
from socketserver import ThreadingMixIn
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    27
import logging
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    28
import gzip
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    29
import re
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    30
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    31
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    32
# Settings
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    33
proxy_port = 8080
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    34
log_level = logging.INFO
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    35
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    36
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    37
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    38
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    39
    pass
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    40
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    41
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    42
class DumpHeaders:
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    43
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    44
    def __init__(self, headers):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    45
        self.headers = headers
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    46
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    47
    def __str__(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    48
        return '\n'.join('    %-19s %s' % (k+':', v) for k, v in self.headers.items())
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    49
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    50
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    51
class ProxyRequestHandler(BaseHTTPRequestHandler):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    52
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    53
    # Allow persistent connections
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    54
    protocol_version = 'HTTP/1.1'
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    55
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    56
    def __init__(self, *args, **kwargs):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    57
        for command in ('GET', 'POST'):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    58
            setattr(self, 'do_' + command, self._handle_request)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    59
        self._fconn = None
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    60
        self.log = logging.getLogger(__name__)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    61
        BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    62
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    63
    def _handle_request(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    64
        self.log.info('Orig request: %s %s', self.command, self.path)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    65
        self.log.debug('Headers:\n%s', DumpHeaders(self.headers))
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    66
        resp = self._forward_request()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    67
        self.response_status = resp.status
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    68
        self.response_reason = resp.reason
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    69
        self.response_headers = resp.headers
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    70
        self.response_body = resp.read(int(resp.headers.get('content-length')))
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    71
        self.log.info('Orig response: %s %s', self.response_status, self.response_reason)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    72
        self.log.debug('Headers:\n%s', DumpHeaders(self.response_headers))
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    73
        self.manipulate_response()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    74
        self.response_headers.replace_header('content-length', str(len(self.response_body)))
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    75
        self.log.info('Proxy response: %s %s', self.response_status, self.response_reason)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    76
        self.log.debug('Headers:\n%s', DumpHeaders(self.response_headers))
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    77
        self.send_response(self.response_status, self.response_reason)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    78
        for name, value in self.response_headers.items():
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    79
            self.send_header(name, value)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    80
        self.end_headers()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    81
        self.log.debug('start write')
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    82
        self.wfile.write(self.response_body)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    83
        self.log.debug('done write')
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    84
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    85
    def _forward_request(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    86
        if self.command == 'POST':
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    87
            content_len = int(self.headers.get('content-length'))
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    88
            body = self.rfile.read(content_len)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    89
            self.log.debug('Body: %s', body)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    90
        else:
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    91
            body = None
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    92
        if not self._fconn:
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    93
            self._connect_target()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    94
        self.log.info('Proxy request: %s %s', self.command, self.path)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    95
        try:
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    96
            self._fconn.request(self.command, self.path, body, self.headers)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    97
            return self._fconn.getresponse()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    98
        except HTTPException:
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    99
            # Try again, in case that server just closed connection.
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   100
            self._fconn.close()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   101
            self._connect_target()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   102
            self._fconn.request(self.command, self.path, body, self.headers)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   103
            return self._fconn.getresponse()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   104
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   105
    def _connect_target(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   106
        host = self.headers.get('host')
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   107
        self.log.info('Connect to %s:80', host)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   108
        self._fconn = HTTPConnection(host, timeout=30)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   109
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   110
    def setup(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   111
        super().setup()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   112
        self.log.info('Connect from %s:%s', *self.client_address)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   113
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   114
    def finish(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   115
        self.log.info('--- Disconnect ---')
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   116
        super().finish()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   117
        if self._fconn:
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   118
            self._fconn.close()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   119
            self._fconn = None
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   120
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   121
    def handle_one_request(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   122
        self.log.info('--- Request ---')
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   123
        super().handle_one_request()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   124
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   125
    def log_error(self, fmt, *args):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   126
        self.log.error(fmt, *args)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   127
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   128
    def log_message(self, format_, *args):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   129
        pass
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   130
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   131
    def _prepare_body(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   132
        if self.response_headers.get('content-encoding') == 'gzip':
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   133
            self.response_body = gzip.decompress(self.response_body)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   134
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   135
    def _finish_body(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   136
        if self.response_headers.get('content-encoding') == 'gzip':
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   137
            self.response_body = gzip.compress(self.response_body)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   138
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   139
    def manipulate_response(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   140
        """Manipulate response from server.
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   141
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   142
        Request parameters are available as usual, see BaseHTTPRequestHandler.
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   143
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   144
        Response from server is available in variables (and can be altered):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   145
        * self.response_status
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   146
        * self.response_reason
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   147
        * self.response_headers
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   148
        * self.response_body
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   149
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   150
        Before touching response_body, call `_prepare_body` and when finished call `_finish_body`.
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   151
        These take care of compression and content_length header.
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   152
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   153
        """
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   154
        pass
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   155
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   156
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   157
class ExampleRequestHandler(ProxyRequestHandler):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   158
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   159
    """Example proxying request handler.
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   160
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   161
    Manipulate content of one JavaScript file, leave rest as is.
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   162
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   163
    """
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   164
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   165
    def manipulate_response(self):
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   166
        # Enable web control interface for AV receiver Yamaha HTR-4066
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   167
        # by moving the model name from "low" list a little higher :-)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   168
        if self.path == '/JavaScripts/scr0.js':
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   169
            self._prepare_body()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   170
            self.response_body = re.sub(br'^ "HTR-4066",', br'', self.response_body, flags=re.MULTILINE)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   171
            self.response_body = re.sub(br'^( var g_modelName6xx = \[)', br'\1"HTR-4066",', self.response_body, flags=re.MULTILINE)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   172
            self._finish_body()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   173
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   174
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   175
if __name__ == "__main__":
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   176
    logging.basicConfig(level=log_level,
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   177
        format="%(asctime)s %(threadName)s %(levelname)s: %(message)s", datefmt="%H:%M:%S")
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   178
    transproxpy = ThreadingHTTPServer(('', proxy_port), ExampleRequestHandler)
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   179
    transproxpy.serve_forever()
cef7ea3df9c2 Transproxpy.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   180