Beispiel #1
0
    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()
Beispiel #2
0
    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()
Beispiel #3
0
    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)