-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcaching_client.py
More file actions
72 lines (62 loc) · 2.49 KB
/
caching_client.py
File metadata and controls
72 lines (62 loc) · 2.49 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
import evhttpconn
import settings
import re
from compressor import compress
class CachingClient(evhttpconn.Connection):
def __init__(self, loop, sock, page):
super(CachingClient, self).__init__(loop, sock)
self.loop = loop
self.page = page
self.cache = self.page.cache
self.can_compress = False
def on_headers(self, key, value):
if key == 'content-type':
self.can_compress = False
for c in settings.compress_content:
if c.match(value):
self.can_compress = True
break
def on_headers_end(self, message):
self.send_back(message)
self.page.response_headers_len = len(message)
def on_chunk(self, chunk):
self.send_back(chunk)
def on_complete(self):
self.cache.release(len(self.page.response))
self.page.response = self.page.partial_response
self.page.partial_response = ''
self.page.complete = True
self.close()
# start compression
if len(self.page.response) > 100:
response = self.page.response
def on_compressed(data):
if response != self.page.response:
return
headers = re.sub(r'(!\r)\n', '\r\n', response[:self.page.response_headers_len])
headers = re.sub(r'content-length\s*:[^\r]*\r\n', '', headers)
headers = headers[:-2] + ('content-length: %i\r\ncontent-encoding: deflate\r\n\r\n' % len(data))
self.page.compressed = headers + data
compress(self.loop, response[self.page.response_headers_len:], on_compressed)
def on_close(self):
super(CachingClient, self).on_close()
for listener in self.page.listeners:
listener.terminate()
del self.page.listeners[:]
self.page.backend = None
def send_back(self, data):
if not data:
return
for listener in self.page.listeners:
listener.send(data)
if self.page.can_cache:
existing = len(self.page.partial_response)
additional = len(data)
if (existing + additional) > settings.max_cache_content_length:
self.cache.purge(self.page)
elif not self.cache.reserve(additional):
self.cache.purge(self.page)
elif self.page.can_cache:
self.page.partial_response += data
else:
self.cache.release(additional)