1
2
3
4
5
6 import urlparse
7 from restkit import ConnectionPool, request
8 from restkit.sock import MAX_BODY
9
10 ALLOWED_METHODS = ['GET', 'HEAD']
11
12 BLOCK_SIZE = 4096 * 16
13
15
19
21 data = self.body.read(BLOCK_SIZE)
22 if not data:
23 raise StopIteration
24 return data
25
28
30 """A proxy wich redirect the request to SERVER_NAME:SERVER_PORT
31 and send HTTP_HOST header"""
32
35 self.pool = pool or ConnectionPool(**kwargs)
36 self.allowed_methods = allowed_methods
37 self.strip_script_name = strip_script_name
38
40 port = None
41 scheme = environ['wsgi.url_scheme']
42 if 'SERVER_NAME' in environ:
43 host = environ['SERVER_NAME']
44 else:
45 host = environ['HTTP_HOST']
46 if ':' in host:
47 host, port = host.split(':')
48
49 if not port:
50 if 'SERVER_PORT' in environ:
51 port = environ['SERVER_PORT']
52 else:
53 port = scheme == 'https' and '443' or '80'
54
55 uri = '%s://%s:%s' % (scheme, host, port)
56 return uri
57
58 - def __call__(self, environ, start_response):
59 method = environ['REQUEST_METHOD']
60 if method not in self.allowed_methods:
61 start_response('403 Forbidden', ())
62 return ['']
63
64 if method in ('POST', 'PUT'):
65 if 'CONTENT_LENGTH' in environ:
66 content_length = int(environ['CONTENT_LENGTH'])
67 body = environ['wsgi.input'].read(content_length)
68 else:
69 body = environ['wsgi.input'].read()
70 else:
71 body=None
72
73 if self.strip_script_name:
74 path_info = ''
75 else:
76 path_info = environ['SCRIPT_NAME']
77 path_info += environ['PATH_INFO']
78
79 query_string = environ['QUERY_STRING']
80 if query_string:
81 path_info += '?' + query_string
82
83 uri = self.extract_uri(environ)+path_info
84
85 new_headers = {}
86 for k, v in environ.items():
87 if k.startswith('HTTP_'):
88 k = k[5:].replace('_', '-').title()
89 new_headers[k] = v
90
91 for k, v in (('CONTENT_TYPE', None), ('CONTENT_LENGTH', '0')):
92 v = environ.get(k, None)
93 if v is not None:
94 new_headers[k.replace('_', '-').title()] = v
95
96 response = request(uri, method,
97 body=body, headers=new_headers,
98 pool_instance=self.pool)
99
100 start_response(response.status, response.headerslist)
101
102 if 'content-length' in response and \
103 int(response['content-length']) <= MAX_BODY:
104 return [response.body]
105
106 return ResponseIter(response)
107
109 """A proxy based on HTTP_HOST environ variable"""
110
112 port = None
113 scheme = environ['wsgi.url_scheme']
114 host = environ['HTTP_HOST']
115 if ':' in host:
116 host, port = host.split(':')
117
118 if not port:
119 port = scheme == 'https' and '443' or '80'
120
121 uri = '%s://%s:%s' % (scheme, host, port)
122 return uri
123
124
126 """A proxy to redirect all request to a specific uri"""
127
129 super(HostProxy, self).__init__(**kwargs)
130 self.uri = uri.rstrip('/')
131 self.scheme, self.net_loc = urlparse.urlparse(self.uri)[0:2]
132
134 environ['HTTP_HOST'] = self.net_loc
135 return self.uri
136
137
139 """A proxy to redirect all request to CouchDB database"""
140 - def __init__(self, db_name='', uri='http://127.0.0.1:5984',
141 allowed_methods=['GET'], **kwargs):
142 uri = uri.rstrip('/')
143 if db_name:
144 uri += '/' + db_name.strip('/')
145 super(CouchdbProxy, self).__init__(uri, allowed_methods=allowed_methods,
146 **kwargs)
147
149 """parse paste config"""
150 config = {}
151 allowed_methods = local_config.get('allowed_methods', None)
152 if allowed_methods:
153 config['allowed_methods'] = [m.upper() for m in allowed_methods.split()]
154 strip_script_name = local_config.get('strip_script_name', 'true')
155 if strip_script_name.lower() in ('false', '0'):
156 config['strip_script_name'] = False
157 config['max_connections'] = int(local_config.get('max_connections', '5'))
158 return config
159
161 """TransparentProxy entry_point"""
162 config = get_config(local_config)
163 print 'Running TransparentProxy with %s' % config
164 return TransparentProxy(**config)
165
167 """HostProxy entry_point"""
168 uri = uri.rstrip('/')
169 config = get_config(local_config)
170 print 'Running HostProxy on %s with %s' % (uri, config)
171 return HostProxy(uri, **config)
172
173 -def make_couchdb_proxy(global_config, db_name='', uri='http://127.0.0.1:5984',
174 **local_config):
175 """CouchdbProxy entry_point"""
176 uri = uri.rstrip('/')
177 config = get_config(local_config)
178 print 'Running CouchdbProxy on %s/%s with %s' % (uri, db_name, config)
179 return CouchdbProxy(db_name=db_name, uri=uri, **config)
180