Example #1
0
def iter_mime_headers_and_bodies(wsgi_input, mime_boundary, read_chunk_size):
    mime_documents_iter = iter_multipart_mime_documents(
        wsgi_input, mime_boundary, read_chunk_size)

    for file_like in mime_documents_iter:
        hdrs = parse_mime_headers(file_like)
        yield (hdrs, file_like)
Example #2
0
def iter_mime_headers_and_bodies(wsgi_input, mime_boundary, read_chunk_size):
    mime_documents_iter = iter_multipart_mime_documents(
        wsgi_input, mime_boundary, read_chunk_size)

    for file_like in mime_documents_iter:
        hdrs = parse_mime_headers(file_like)
        yield (hdrs, file_like)
Example #3
0
    def _translate_form(self, env, boundary):
        """
        Translates the form data into subrequests and issues a
        response.

        :param env: The WSGI environment dict.
        :param boundary: The MIME type boundary to look for.
        :returns: status_line, headers_list, body
        """
        keys = self._get_keys(env)
        if six.PY3:
            boundary = boundary.encode('utf-8')
        status = message = ''
        attributes = {}
        file_attributes = {}
        subheaders = []
        file_count = 0
        for fp in iter_multipart_mime_documents(
                env['wsgi.input'], boundary, read_chunk_size=READ_CHUNK_SIZE):
            hdrs = parse_mime_headers(fp)
            disp, attrs = parse_content_disposition(
                hdrs.get('Content-Disposition', ''))
            if disp == 'form-data' and attrs.get('filename'):
                file_count += 1
                try:
                    if file_count > int(attributes.get('max_file_count') or 0):
                        status = '400 Bad Request'
                        message = 'max file count exceeded'
                        break
                except ValueError:
                    raise FormInvalid('max_file_count not an integer')
                file_attributes = attributes.copy()
                file_attributes['filename'] = attrs['filename'] or 'filename'
                if 'content-type' not in attributes and 'content-type' in hdrs:
                    file_attributes['content-type'] = \
                        hdrs['Content-Type'] or 'application/octet-stream'
                if 'content-encoding' not in attributes and \
                        'content-encoding' in hdrs:
                    file_attributes['content-encoding'] = \
                        hdrs['Content-Encoding']
                status, subheaders = \
                    self._perform_subrequest(env, file_attributes, fp, keys)
                if not status.startswith('2'):
                    break
            else:
                data = b''
                mxln = MAX_VALUE_LENGTH
                while mxln:
                    chunk = fp.read(mxln)
                    if not chunk:
                        break
                    mxln -= len(chunk)
                    data += chunk
                while fp.read(READ_CHUNK_SIZE):
                    pass
                if six.PY3:
                    data = data.decode('utf-8')
                if 'name' in attrs:
                    attributes[attrs['name'].lower()] = data.rstrip('\r\n--')
        if not status:
            status = '400 Bad Request'
            message = 'no files to process'

        headers = [(k, v) for k, v in subheaders
                   if k.lower().startswith('access-control')]

        redirect = attributes.get('redirect')
        if not redirect:
            body = status
            if message:
                body = status + '\r\nFormPost: ' + message.title()
            headers.extend([('Content-Type', 'text/plain'),
                            ('Content-Length', len(body))])
            if six.PY3:
                body = body.encode('utf-8')
            return status, headers, body
        status = status.split(' ', 1)[0]
        if '?' in redirect:
            redirect += '&'
        else:
            redirect += '?'
        redirect += 'status=%s&message=%s' % (quote(status), quote(message))
        body = '<html><body><p><a href="%s">' \
               'Click to continue...</a></p></body></html>' % redirect
        if six.PY3:
            body = body.encode('utf-8')
        headers.extend(
            [('Location', redirect), ('Content-Length', str(len(body)))])
        return '303 See Other', headers, body
Example #4
0
    def _translate_form(self, env, boundary):
        """
        Translates the form data into subrequests and issues a
        response.

        :param env: The WSGI environment dict.
        :param boundary: The MIME type boundary to look for.
        :returns: status_line, headers_list, body
        """
        keys = self._get_keys(env)
        if six.PY3:
            boundary = boundary.encode('utf-8')
        status = message = ''
        attributes = {}
        subheaders = []
        file_count = 0
        for fp in iter_multipart_mime_documents(
                env['wsgi.input'], boundary, read_chunk_size=READ_CHUNK_SIZE):
            hdrs = parse_mime_headers(fp)
            disp, attrs = parse_content_disposition(
                hdrs.get('Content-Disposition', ''))
            if disp == 'form-data' and attrs.get('filename'):
                file_count += 1
                try:
                    if file_count > int(attributes.get('max_file_count') or 0):
                        status = '400 Bad Request'
                        message = 'max file count exceeded'
                        break
                except ValueError:
                    raise FormInvalid('max_file_count not an integer')
                attributes['filename'] = attrs['filename'] or 'filename'
                if 'content-type' not in attributes and 'content-type' in hdrs:
                    attributes['content-type'] = \
                        hdrs['Content-Type'] or 'application/octet-stream'
                if 'content-encoding' not in attributes and \
                        'content-encoding' in hdrs:
                    attributes['content-encoding'] = hdrs['Content-Encoding']
                status, subheaders = \
                    self._perform_subrequest(env, attributes, fp, keys)
                if not status.startswith('2'):
                    break
            else:
                data = b''
                mxln = MAX_VALUE_LENGTH
                while mxln:
                    chunk = fp.read(mxln)
                    if not chunk:
                        break
                    mxln -= len(chunk)
                    data += chunk
                while fp.read(READ_CHUNK_SIZE):
                    pass
                if six.PY3:
                    data = data.decode('utf-8')
                if 'name' in attrs:
                    attributes[attrs['name'].lower()] = data.rstrip('\r\n--')
        if not status:
            status = '400 Bad Request'
            message = 'no files to process'

        headers = [(k, v) for k, v in subheaders
                   if k.lower().startswith('access-control')]

        redirect = attributes.get('redirect')
        if not redirect:
            body = status
            if message:
                body = status + '\r\nFormPost: ' + message.title()
            headers.extend([('Content-Type', 'text/plain'),
                            ('Content-Length', len(body))])
            if six.PY3:
                body = body.encode('utf-8')
            return status, headers, body
        status = status.split(' ', 1)[0]
        if '?' in redirect:
            redirect += '&'
        else:
            redirect += '?'
        redirect += 'status=%s&message=%s' % (quote(status), quote(message))
        body = '<html><body><p><a href="%s">' \
               'Click to continue...</a></p></body></html>' % redirect
        if six.PY3:
            body = body.encode('utf-8')
        headers.extend(
            [('Location', redirect), ('Content-Length', str(len(body)))])
        return '303 See Other', headers, body