def requestReceived(self, command, path, version): """ Called by channel when all data has been received. Overridden because Twisted merges GET and POST into one thing by default. """ self.content.seek(0, 0) self.get = {} self.post = {} self.method, self.uri = command, path self.clientproto = version x = self.uri.split(b'?', 1) print self.method # URI and GET args assignment if len(x) == 1: self.path = self.uri else: self.path, argstring = x self.get = parse_qs(argstring, 1) # cache the client and server information, we'll need this later to be # serialized and sent with the request so CGIs will work remotely self.client = self.channel.transport.getPeer() self.host = self.channel.transport.getHost() # Argument processing ctype = self.requestHeaders.getRawHeaders(b'content-type') if ctype is not None: ctype = ctype[0] # Process POST data if present if self.method == b"POST" and ctype: mfd = b'multipart/form-data' key, pdict = _parseHeader(ctype) if key == b'application/x-www-form-urlencoded': self.post.update(parse_qs(self.content.read(), 1)) elif key == mfd: try: cgiArgs = cgi.parse_multipart(self.content, pdict) if _PY3: # parse_multipart on Python 3 decodes the header bytes # as iso-8859-1 and returns a str key -- we want bytes # so encode it back self.post.update({ x.encode('iso-8859-1'): y for x, y in cgiArgs.items() }) else: self.post.update(cgiArgs) except: # It was a bad request. _respondToBadRequestAndDisconnect(self.channel.transport) return self.content.seek(0, 0) # Continue with rest of request handling self.process()
def requestReceived(self, command, path, version): """ Called by channel when all data has been received. Overridden because Twisted merges GET and POST into one thing by default. """ self.content.seek(0,0) self.get = {} self.post = {} self.method, self.uri = command, path self.clientproto = version x = self.uri.split(b'?', 1) print self.method # URI and GET args assignment if len(x) == 1: self.path = self.uri else: self.path, argstring = x self.get = parse_qs(argstring, 1) # cache the client and server information, we'll need this later to be # serialized and sent with the request so CGIs will work remotely self.client = self.channel.transport.getPeer() self.host = self.channel.transport.getHost() # Argument processing ctype = self.requestHeaders.getRawHeaders(b'content-type') if ctype is not None: ctype = ctype[0] # Process POST data if present if self.method == b"POST" and ctype: mfd = b'multipart/form-data' key, pdict = _parseHeader(ctype) if key == b'application/x-www-form-urlencoded': self.post.update(parse_qs(self.content.read(), 1)) elif key == mfd: try: cgiArgs = cgi.parse_multipart(self.content, pdict) if _PY3: # parse_multipart on Python 3 decodes the header bytes # as iso-8859-1 and returns a str key -- we want bytes # so encode it back self.post.update({x.encode('iso-8859-1'): y for x, y in cgiArgs.items()}) else: self.post.update(cgiArgs) except: # It was a bad request. _respondToBadRequestAndDisconnect(self.channel.transport) return self.content.seek(0, 0) # Continue with rest of request handling self.process()
def requestReceived(self, command, path, version): ctype = self.requestHeaders.getRawHeaders(b'content-type') # if this request is sending multipart data if ctype is not None and ctype[0][:10] == b'multipart/': ctype = ctype[0] clength = self.requestHeaders.getRawHeaders(b'content-length') if clength is not None: clength = int(clength[0]) contentType, contentTypeParameters = _parseHeader(ctype) boundary = contentTypeParameters['boundary'] compliantBoundary = MULTIPART_BOUNDARY_DELIMITER + boundary replacementsMade = 0 originalOk = False newContent = BytesIO() self.content.seek(0) nextLine = self.content.readline() while nextLine and not originalOk: strippedLine = nextLine.strip() if strippedLine == boundary or strippedLine == boundary + MULTIPART_BOUNDARY_DELIMITER: # the incoming payload is non-compliant # in the way Dream Passport is; correct it replacementsMade += 1 newContent.write(MULTIPART_BOUNDARY_DELIMITER + nextLine) elif strippedLine == compliantBoundary: # the incoming payload is compliant, # (this likely means no lines will be # wrong and we should bail early!) originalOk = True newContent.close() else: # this isn't a line we can make judgements about newContent.write(nextLine) nextLine = self.content.readline() if replacementsMade > 0: self.content.close() self.content = newContent self.requestHeaders.setRawHeaders( b'content-length', [str(clength + replacementsMade * 2)]) # finally, hand it on back to the original Request class super(DreamuploaderRequest, self).requestReceived(command, path, version)
def _parse_request_payload(self): content_type = self.getHeader('content-type', '') codecs = { 'application/json': self.__parse_json, 'multipart/form-data': self.__parse_file_upload, 'application/x-www-form-urlencoded': self.__parse_urlencoded, } codec, params = _parseHeader(content_type) self.body = {} try: codec = codecs[codec] except KeyError: if self.content_length: self.setResponseCode(415) raise ValueError('Unknown or unsupported Content-Type.') else: self.body = codec(params)