Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Ticket #598: nbs.py

Line 
1 #!/usr/bin/python2.4
2
3 import socket
4 import errno
5
6
7 class nbf(object):
8
9
10         """non-blocking socket friendly file like object to WSGI spec PEP 333"""
11
12
13         def __init__(self, socket):
14
15                 self._socket = socket
16                 self._rbuf = ''
17                 self._rsize = 8192
18
19
20         def read(self, size=None):
21
22                 # self._socket.recv into the buffer
23                 # return at most size bytes from the buffer
24                 # if size is None, return data until EOF (connection close)
25
26                 pass
27
28
29         def _readline_1(self, size=None):
30
31                 # size ignored - not supported according to PEP 333
32                 # should we raise an exception ? which one ?
33
34                 # approach #1: behave like blocking version of readline
35
36                 while True:
37                         while True:
38                                 try:
39                                         chunk = self._socket.recv(self._rsize)
40                                         if not chunk:
41                                                 return ''
42                                         self._rbuf += chunk
43                                         break
44                                 except socket.timeout:
45                                         pass
46                         try:
47                                 eol = self._rbuf.index('\r\n')
48                                 line = self._rbuf[:eol]
49                                 self._rbuf = self._rbuf[eol+2:]
50                                 return line
51                         except ValueError:
52                                 pass
53
54
55         def _readline_2(self, size=None):
56
57                 # size ignored - not supported according to PEP 333
58                 # should we raise an exception ? which one ?
59
60                 # approach #2: timeouts are raised but we ensure buffering
61                 # of received data so that subsequent readline() invocations
62                 # pickup where the incoming data stream left off
63
64                 while True:
65                         while True:
66                                 try:
67                                         chunk = self._socket.recv(self._rsize)
68                                         if not chunk:
69                                                 return ''
70                                         self._rbuf += chunk
71                                         break
72                                 except socket.timeout:
73                                         raise
74                         try:
75                                 eol = self._rbuf.index('\r\n')
76                                 line = self._rbuf[:eol]
77                                 self._rbuf = self._rbuf[eol+2:]
78                                 return line
79                         except ValueError:
80                                 pass
81
82
83         readline = _readline_2
84
85
86         def readlines(self, hint=None):
87
88                 # ignore hint, according to PEP 333
89
90                 pass
91
92
93         def __iter__(self):
94
95                 return self
96
97
98         def next(self):
99
100                 # return readline() or StopIteration on connection close
101
102                 pass
103
104
105         def flush(self):
106
107                 pass
108
109
110         def write(self, str):
111
112                 pass
113
114
115         def writelines(self, seq):
116
117                 pass
118
119
120
121 class nbs(socket.socket):
122
123         def __init__(self, *args, **kwargs):
124
125                 socket.socket.__init__(self, *args, **kwargs)
126
127
128         def accept(self, *args, **kwargs):
129
130                 c, a = socket.socket.accept(self, *args, **kwargs)
131                 return nbs(_sock=c), a
132
133
134         def makefile(self, *args, **kwargs):
135
136                 return nbf(self)
137
138
139         def sendall(self, buf):
140                 pending = len(buf)
141                 offset = 0
142                 while pending:
143                         try:
144                                 sent = self.send(buf[offset:])
145                                 pending -= sent
146                                 offset += sent
147                         except socket.error, e:
148                                 if e[0]!=errno.EAGAIN and e[0]!=errno.EWOULDBLOCK:
149                                         raise
150
151
152 if __name__ == '__main__':
153
154         s = nbs(socket.AF_INET, socket.SOCK_STREAM)
155         s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
156         s.bind(('',8080))
157         s.listen(4)
158         c,a = s.accept()
159         c.settimeout(5)
160         f = c.makefile()
161         print "readline result:", f.readline().strip()
162         c.sendall('got it\r\n')
163         c.close()
164         s.close()
165

Hosted by WebFaction

Log in as guest/cpguest to create tickets