1
2
3
4
5
6 import asyncore
7 import socket
8 import urlparse
9 import mimetools
10 import cStringIO
11 import core
12
13 import logging
14 log = logging.getLogger("tangled.client")
15
17 """
18 This is the response object returned by L{AsyncHTTPClient}.
19 """
21 self.data = ""
22 self.header = ""
23 self.finished = False
24 self.server_address = addr
25
28
29 - def feed(self, data):
31
34
36 self.status = int(status[1])
37 try:
38 self.reason = status[2]
39 except IndexError:
40 self.reason = ""
41
42
44 """
45 Asynchronous HTTP client, based on
46 http://effbot.org/librarybook/SimpleAsyncHTTP.py
47 """
48 - def __init__(self, url, command="GET", data="", consumer=None):
49 asyncore.dispatcher_with_send.__init__(self)
50 parsed = urlparse.urlparse(url)
51 self._request = '%s %s HTTP/1.1\r\n' % (command, parsed.path)
52 self._request = self._request + 'Host: %s\r\n' % parsed.netloc
53 if len(data) > 0:
54 self._request = self._request + 'Content-Length: %d\r\n\r\n%s' % (len(data), data)
55 else:
56 self._request = self._request + "\r\n"
57 addr = parsed.netloc.split(":")
58 host = addr[0]
59 try:
60 port = int(addr[1])
61 except IndexError:
62 port = 80
63 self.consumer = consumer
64 if self.consumer is None:
65 self.consumer = Response((host, port))
66 self.response = self.consumer
67 self.status = None
68 self.header = None
69 self.data = ""
70 self._result = core.Deferred()
71 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
72 self.connect((host, port))
73
76
78 self.send(self._request)
79
83
89
91 data = self.recv(2048)
92 if not self.header:
93 self.data = self.data + data
94 i = self.data.find("\r\n\r\n")
95 if i != -1:
96
97 fp = cStringIO.StringIO(self.data[:i+4])
98
99 status = fp.readline()
100 self.status = status.split(" ", 2)
101
102 self.header = mimetools.Message(fp)
103
104 data = self.data[i+4:]
105 self.data = ""
106
107 self.notify_header()
108 if not self.connected:
109 return
110
111 if self.header:
112 self.consumer.feed(data)
113
118
119 -def request(url, command="GET", data=""):
120 """
121 Helper function to make a request without needing
122 to know about L{AsyncHTTPClient}.
123 """
124 c = AsyncHTTPClient(url, command, data)
125 return c.request()
126
127 if __name__=="__main__":
128 import optparse
129
130 parser = optparse.OptionParser()
131
132 parser.add_option("-n", "--number", dest="number", type="int",
133 help="Number of connections")
134 parser.add_option("-c", "--concurrent", dest="concurrent", type="int",
135 help="Number of concurrent connections")
136 parser.add_option("-p", "--printresponse", dest="printresponse", action="store_true", default=False,
137 help="Number of concurrent connections")
138
139 (options, args) = parser.parse_args()
140
141 num = 0
142 for n in range(0, options.number, options.concurrent):
143 clients = [AsyncHTTPClient(args[0]) for i in range(options.concurrent)]
144 asyncore.loop()
145 if options.printresponse:
146 for c in clients:
147 print c.response.header
148 print c.response.data
149 num += len(clients)
150 print "Completed", num, "requests"
151