1
2
3
4
5
6 import urlparse
7
8 try:
9 from cStringIO import StringIO
10 except ImportError:
11 from StringIO import StringIO
12
13 from ..client import Client
14 from ..globals import _manager
15 from ..sock import MAX_BODY
16 from ..util import rewrite_location
17
18 ALLOWED_METHODS = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE']
19
20 BLOCK_SIZE = 4096 * 16
21
22 WEBOB_ERROR = ("Content-Length is set to -1. This usually mean that WebOb has "
23 "already parsed the content body. You should set the Content-Length "
24 "header to the correct value before forwarding your request to the "
25 "proxy: ``req.content_length = str(len(req.body));`` "
26 "req.get_response(proxy)")
27
29 """A proxy wich redirect the request to SERVER_NAME:SERVER_PORT
30 and send HTTP_HOST header"""
31
37
39 port = None
40 scheme = environ['wsgi.url_scheme']
41 if 'SERVER_NAME' in environ:
42 host = environ['SERVER_NAME']
43 else:
44 host = environ['HTTP_HOST']
45 if ':' in host:
46 host, port = host.split(':')
47
48 if not port:
49 if 'SERVER_PORT' in environ:
50 port = environ['SERVER_PORT']
51 else:
52 port = scheme == 'https' and '443' or '80'
53
54 uri = '%s://%s:%s' % (scheme, host, port)
55 return uri
56
57 - def __call__(self, environ, start_response):
58 method = environ['REQUEST_METHOD']
59 if method not in self.allowed_methods:
60 start_response('403 Forbidden', ())
61 return ['']
62
63 if self.strip_script_name:
64 path_info = ''
65 else:
66 path_info = environ['SCRIPT_NAME']
67 path_info += environ['PATH_INFO']
68
69 query_string = environ['QUERY_STRING']
70 if query_string:
71 path_info += '?' + query_string
72
73 host_uri = self.extract_uri(environ)
74 uri = host_uri + path_info
75
76 new_headers = {}
77 for k, v in environ.items():
78 if k.startswith('HTTP_'):
79 k = k[5:].replace('_', '-').title()
80 new_headers[k] = v
81
82 for k, v in (('CONTENT_TYPE', None), ('CONTENT_LENGTH', '0')):
83 v = environ.get(k, None)
84 if v is not None:
85 new_headers[k.replace('_', '-').title()] = v
86
87 if new_headers.get('Content-Length', '0') == '-1':
88 raise ValueError(WEBOB_ERROR)
89
90 response = self.client.request(uri, method, body=environ['wsgi.input'],
91 headers=new_headers)
92
93 if 'location' in response:
94 if self.strip_script_name:
95 prefix_path = environ['SCRIPT_NAME']
96
97 new_location = rewrite_location(host_uri, response.location,
98 prefix_path=prefix_path)
99
100 headers = []
101 for k, v in response.headerslist:
102 if k.lower() == 'location':
103 v = new_location
104 headers.append((k, v))
105 else:
106 headers = response.headerslist
107
108 start_response(response.status, headers)
109
110 if method == "HEAD":
111 return StringIO()
112
113 return response.tee()
114
116 """A proxy based on HTTP_HOST environ variable"""
117
119 port = None
120 scheme = environ['wsgi.url_scheme']
121 host = environ['HTTP_HOST']
122 if ':' in host:
123 host, port = host.split(':')
124
125 if not port:
126 port = scheme == 'https' and '443' or '80'
127
128 uri = '%s://%s:%s' % (scheme, host, port)
129 return uri
130
131
133 """A proxy to redirect all request to a specific uri"""
134
136 super(HostProxy, self).__init__(**kwargs)
137 self.uri = uri.rstrip('/')
138 self.scheme, self.net_loc = urlparse.urlparse(self.uri)[0:2]
139
141 environ['HTTP_HOST'] = self.net_loc
142 return self.uri
143
145 """parse paste config"""
146 config = {}
147 allowed_methods = local_config.get('allowed_methods', None)
148 if allowed_methods:
149 config['allowed_methods'] = [m.upper() for m in allowed_methods.split()]
150 strip_script_name = local_config.get('strip_script_name', 'true')
151 if strip_script_name.lower() in ('false', '0'):
152 config['strip_script_name'] = False
153 config['max_connections'] = int(local_config.get('max_connections', '5'))
154 return config
155
157 """TransparentProxy entry_point"""
158 config = get_config(local_config)
159 print 'Running TransparentProxy with %s' % config
160 return TransparentProxy(**config)
161
163 """HostProxy entry_point"""
164 uri = uri.rstrip('/')
165 config = get_config(local_config)
166 print 'Running HostProxy on %s with %s' % (uri, config)
167 return HostProxy(uri, **config)
168