54
54
The server passes requests through to an underlying backing transport,
55
55
which will typically be a LocalTransport looking at the server's filesystem.
57
:ivar _push_back_buffer: a str of bytes that have been read from the stream
58
but not used yet, or None if there are no buffered bytes. Subclasses
59
should make sure to exhaust this buffer before reading more bytes from
60
the stream. See also the _push_back method.
58
def __init__(self, backing_transport):
63
def __init__(self, backing_transport, root_client_path='/'):
59
64
"""Construct new server.
61
66
:param backing_transport: Transport for the directory served.
63
68
# backing_transport could be passed to serve instead of __init__
64
69
self.backing_transport = backing_transport
70
self.root_client_path = root_client_path
65
71
self.finished = False
72
self._push_back_buffer = None
68
74
def _push_back(self, bytes):
69
assert self.push_back is None, (
70
"_push_back called when self.push is %r" % (self.push_back,))
75
"""Return unused bytes to the medium, because they belong to the next
78
This sets the _push_back_buffer to the given bytes.
80
assert self._push_back_buffer is None, (
81
"_push_back called when self._push_back_buffer is %r"
82
% (self._push_back_buffer,))
73
self.push_back = bytes
85
self._push_back_buffer = bytes
87
def _get_push_back_buffer(self):
88
assert self._push_back_buffer != '', (
89
'%s._push_back_buffer should never be the empty string, '
90
'which can be confused with EOF' % (self,))
91
bytes = self._push_back_buffer
92
self._push_back_buffer = None
76
96
"""Serve requests until the client disconnects."""
101
121
bytes = bytes[len(REQUEST_VERSION_TWO):]
103
123
protocol_class = SmartServerRequestProtocolOne
104
protocol = protocol_class(self.backing_transport, self._write_out)
124
protocol = protocol_class(
125
self.backing_transport, self._write_out, self.root_client_path)
105
126
protocol.accept_bytes(bytes)
153
174
class SmartServerSocketStreamMedium(SmartServerStreamMedium):
155
def __init__(self, sock, backing_transport):
176
def __init__(self, sock, backing_transport, root_client_path='/'):
158
179
:param sock: the socket the server will read from. It will be put
159
180
into blocking mode.
161
SmartServerStreamMedium.__init__(self, backing_transport)
182
SmartServerStreamMedium.__init__(
183
self, backing_transport, root_client_path=root_client_path)
162
184
sock.setblocking(True)
163
185
self.socket = sock
165
187
def _serve_one_request_unguarded(self, protocol):
166
188
while protocol.next_read_size():
168
protocol.accept_bytes(self.push_back)
169
self.push_back = None
171
bytes = self._get_bytes(4096)
175
protocol.accept_bytes(bytes)
189
bytes = self._get_bytes(4096)
193
protocol.accept_bytes(bytes)
177
195
self._push_back(protocol.excess_buffer)
179
197
def _get_bytes(self, desired_count):
198
if self._push_back_buffer is not None:
199
return self._get_push_back_buffer()
180
200
# We ignore the desired_count because on sockets it's more efficient to
181
201
# read 4k at a time.
182
if self.push_back is not None:
183
assert self.push_back != '', (
184
'self.push_back should never be the empty string, which can be '
186
bytes = self.push_back
187
self.push_back = None
189
202
return self.socket.recv(4096)
191
204
def terminate_due_to_error(self):
235
248
protocol.accept_bytes(bytes)
237
250
def _get_bytes(self, desired_count):
238
if self.push_back is not None:
239
assert self.push_back != '', (
240
'self.push_back should never be the empty string, which can be '
242
bytes = self.push_back
243
self.push_back = None
251
if self._push_back_buffer is not None:
252
return self._get_push_back_buffer()
245
253
return self._in.read(desired_count)
247
255
def terminate_due_to_error(self):