/[james]/sargasso/!Sargasso/py/http_client.py
ViewVC logotype

Annotation of /sargasso/!Sargasso/py/http_client.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 76 - (hide annotations) (download) (as text)
Sun May 15 12:37:54 2005 UTC (19 years, 6 months ago) by james
File MIME type: text/x-python
File size: 2953 byte(s)
Initial import of Sargasso 1.00.

1 james 76 """Async HTTP fetching.
2    
3     This module is taken from the article
4     http://effbot.org/zone/effnews-1.htm
5     (and the other articles in the series).
6    
7     Copyright 1995-2005 by Fredrik Lundh.
8     see http://effbot.org/zone/copyright.htm
9    
10     With modifications by James Bursa.
11     """
12    
13     import asyncore
14     import socket, time
15     import StringIO
16     import mimetools, urlparse
17    
18    
19     request_headers = []
20    
21    
22     class CloseConnection(Exception):
23     pass
24    
25    
26     class async_http(asyncore.dispatcher_with_send):
27     # asynchronous http client
28    
29     def __init__(self, host, port, path, consumer):
30     asyncore.dispatcher_with_send.__init__(self)
31    
32     self.host = host
33     self.port = port
34     self.path = path
35    
36     self.consumer = consumer
37    
38     self.status = None
39     self.header = None
40    
41     self.bytes_in = 0
42     self.bytes_out = 0
43    
44     self.data = ""
45    
46     self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
47     self.connect((host, port))
48    
49     def handle_connect(self):
50     # connection succeeded
51     headers = ["GET %s HTTP/1.0" % self.path,
52     "Host: %s" % self.host] + request_headers
53     text = "\r\n".join(headers) + "\r\n\r\n"
54     self.send(text)
55     self.bytes_out = self.bytes_out + len(text)
56    
57     def handle_expt(self):
58     # connection failed; notify consumer
59     self.close()
60     self.consumer.http_failed(self)
61    
62     def handle_read(self):
63    
64     data = self.recv(2048)
65     self.bytes_in = self.bytes_in + len(data)
66    
67     if not self.header:
68     # check if we've seen a full header
69     self.data = self.data + data
70    
71     header = self.data.split("\r\n\r\n", 1)
72     if len(header) <= 1:
73     return
74     header, data = header
75    
76     # parse header
77     fp = StringIO.StringIO(header)
78     self.status = fp.readline().split(" ", 2)
79     self.header = mimetools.Message(fp)
80    
81     self.data = ""
82    
83     try:
84     self.consumer.http_header(self)
85     except CloseConnection:
86     self.close()
87     return
88    
89     if not self.connected:
90     return # channel was closed by consumer
91    
92     if data:
93     self.consumer.receive(data)
94    
95     def handle_close(self):
96     self.consumer.close()
97     self.close()
98    
99     def handle_error(self):
100     self.consumer.http_failed(self)
101     self.close()
102    
103    
104     def do_request(uri, consumer):
105    
106     # turn the uri into a valid request
107    
108     scheme, host, path, params, query, fragment = urlparse.urlparse(uri)
109     assert scheme == "http", "only supports HTTP requests"
110     try:
111     host, port = host.split(":", 1)
112     port = int(port)
113     except (TypeError, ValueError):
114     port = 80 # default port
115    
116     if not path:
117     path = "/"
118     if params:
119     path = path + ";" + params
120     if query:
121     path = path + "?" + query
122    
123     return async_http(host, port, path, consumer)

  ViewVC Help
Powered by ViewVC 1.1.26