def _make_writer(self): for k, v in self.headers.iteritems(multi=True, preserve_case=True): line = b': '.join([bytes(k), bytes(v)]) + b'\r\n' state = M.HaveLine(line) self.state = state self.bytes_written += len(line) yield state state = M.HaveLine(b'\r\n') self.state = state self.bytes_written += 2 yield state self.state = M.Complete
def from_bytes(cls, bytestr): # TODO: generify bio = BytesIO(bytestr) reader = ResponseReader() state = reader.state while True: if state is M.Complete: break elif state.type == M.NeedLine.type: line = bio.readline() # TODO: limit? next_state = M.HaveLine(value=line) elif state.type == M.NeedData.type: data = bio.read(state.amount) # TODO: can this block or return None if empty etc? next_state = M.HaveData(value=data) elif state.type == M.NeedPeek.type: peeked = bio.peek(state.amount) if not peeked: pass # TODO: again, what happens on end of stream next_state = M.HavePeek(amount=peeked) else: raise RuntimeError('Unknown state %r' % (state,)) state = reader.send(next_state) return reader.raw_response
def from_bytes(cls, bstr): instance = cls() for line in bstr.splitlines(True): instance.reader.send(M.HaveLine(line)) if not instance.complete: raise InvalidHeaders('Missing header termination') return instance
def test_HeadersReader(): reader = P.HeadersReader() repr(reader) assert reader.state is M.NeedLine for line in _HEADER_LINES: state = reader.send(M.HaveLine(line)) assert state is M.NeedLine assert reader.state is state state = reader.send(M.HaveLine('\n')) assert state is M.Complete assert reader.state is state assert reader.complete assert reader.headers == _HEADER_PARSED
def _make_writer(self): for chunk in self.body.send_chunk(): header = '%x\r\n' % len(chunk) for state in (M.HaveLine(header), M.HaveData(chunk), M.HaveLine('\r\n')): self.state = state yield self.state # maybe we got an empty chunk; if so, don't send an additional # end chunk if chunk: for state in (M.HaveLine('0\r\n'), M.HaveLine('\r\n')): self.state = state yield self.state self.state = M.Complete
def read(self): self.state = self.reader.state while not self.reader.complete: if self.state.type == M.NeedLine.type: line = self.read_line() next_state = M.HaveLine(value=line) elif self.state.type == M.NeedData.type: data = self.read_data(self.state.amount) next_state = M.HaveData(value=data) elif self.state.type == M.NeedPeek.type: peeked = self.read_peek(self.state.amount) next_state = M.HavePeek(value=peeked) else: raise RuntimeError('Unknown state {0!r}'.format(self.state)) self.state = self.reader.send(next_state) return True
def _make_writer(self): rl = bytes(self.request_line) + '\r\n' self.bytes_written += len(rl) self.state = M.HaveLine(rl) yield self.state for m in iter(self.headers): self.bytes_written += self.headers.bytes_written self.state = m yield m if self.body: for m in iter(self.body): self.bytes_written += self.body.bytes_written self.state = m yield m self.state = M.Complete yield self.state
def _make_writer(self): sl = bytes(self.status_line) + '\r\n' self.bytes_written += len(sl) self.state = M.HaveLine(sl) yield self.state for m in iter(self.headers): self.bytes_written += self.headers.bytes_written self.state = m yield m if not self.body: self.state = M.Complete return for m in iter(self.body): self.bytes_written += self.body.bytes_written self.state = m yield m self.state = M.Complete