class Multipart: """Responsible of the parsing of multipart encoded `request.body`.""" __slots__ = ('app', 'form', 'files', '_parser', '_current', '_current_headers', '_current_params') def __init__(self, app): self.app = app def initialize(self, content_type: str): self._parser = Parser(self, content_type.encode()) self.form = self.app.Form() self.files = self.app.Files() return self.form, self.files def feed_data(self, data: bytes): self._parser.feed_data(data) def on_part_begin(self): self._current_headers = {} def on_header(self, field: bytes, value: bytes): self._current_headers[field] = value def on_headers_complete(self): disposition_type, params = parse_content_disposition( self._current_headers.get(b'Content-Disposition')) if not disposition_type: return self._current_params = params if b'Content-Type' in self._current_headers: self._current = BytesIO() self._current.filename = extract_filename(params) self._current.content_type = self._current_headers[b'Content-Type'] self._current.params = params else: self._current = '' def on_data(self, data: bytes): if b'Content-Type' in self._current_headers: self._current.write(data) else: self._current += data.decode() def on_part_complete(self): name = self._current_params.get(b'name', b'').decode() if b'Content-Type' in self._current_headers: if name not in self.files: self.files[name] = [] self._current.seek(0) self.files[name].append(self._current) else: if name not in self.form: self.form[name] = [] self.form[name].append(self._current) self._current = None
class Handler: def __init__(self, boundary): self.parts = [] self.parser = Parser(self, boundary) self.on_body_begin_called = 0 self.on_body_complete_called = 0 self.on_headers_complete_called = 0 def feed_data(self, data): self.parser.feed_data(data) def on_body_begin(self): self.on_body_begin_called += 1 print('on_body_begin') def on_part_begin(self): self._current = namedtuple('Data', ['headers', 'content']) self._current.headers = {} self._current.content = b'' print('on_part_begin') def on_header(self, field, value): self._current.headers[field] = value print(field, value) def on_headers_complete(self): self.on_headers_complete_called += 1 print('on_headers_complete') def on_data(self, data: bytes): self._current.content += data def on_part_complete(self): self.parts.append(self._current) self._current = None print('on_part_complete') def on_body_complete(self): self.on_body_complete_called += 1 print('on_body_complete')
def __init__(self, boundary): self.parts = [] self.parser = Parser(self, boundary) self.on_body_begin_called = 0 self.on_body_complete_called = 0 self.on_headers_complete_called = 0
def initialize(self, content_type: str): self._parser = Parser(self, content_type.encode()) self.form = self.app.Form() self.files = self.app.Files() return self.form, self.files
def __init__(self, content_type: str): self._parser = Parser(self, content_type.encode()) self.form = Form() self.files = Files()