Ejemplo n.º 1
0
 def _load_post_data(self):
     self._data = ''
     if self.environ['REQUEST_METHOD'] in ('POST', 'PUT'):
         maxlen = int(self.environ['CONTENT_LENGTH'])
         self._data = self.environ['wsgi.input'].read(maxlen)
         if self.environ.get('CONTENT_TYPE', '').startswith('multipart'):
             lines = ['Content-Type: %s' %
                      self.environ.get('CONTENT_TYPE', '')]
             for key, value in self.environ.items():
                 if key.startswith('HTTP_'):
                     lines.append('%s: %s' % (key, value))
             raw = '\r\n'.join(lines) + '\r\n\r\n' + self._data
             msg = email.message_from_string(raw)
             self._post = MultiDict()
             self._files = MultiDict()
             for sub in msg.get_payload():
                 if not isinstance(sub, MessageType):
                     continue
                 name_dict = cgi.parse_header(sub['Content-Disposition'])[1]
                 if 'filename' in name_dict:
                     payload = sub.get_payload()
                     filename = name_dict['filename']
                     if isinstance(payload, list) or not filename.strip():
                         continue
                     filename = name_dict['filename']
                     #XXX: fixes stupid ie bug but can cause problems
                     filename = filename[filename.rfind('\\') + 1:]
                     if 'Content-Type' in sub:
                         content_type = sub['Content-Type']
                     else:
                         content_type = None
                     s = FieldStorage(name_dict['name'], filename,
                                      content_type, payload)
                     self._files.appendlist(name_dict['name'], s)
                 else:
                     value = sub.get_payload()
                     if not self.charset is None:
                         value = value.decode(self.charset, 'ignore')
                     self._post.appendlist(name_dict['name'], value)
         else:
             d = cgi.parse_qs(self._data, True)
             if not self.charset is None:
                 for key, value in d.iteritems():
                     d[key] = [i.decode(self.charset, 'ignore')
                               for i in value]
             self._post = MultiDict(d)
             self._files = MultiDict()
     else:
         self._post = MultiDict()
         self._files = MultiDict()
Ejemplo n.º 2
0
class Request(object):
    """
    The central Request object. It stores all data coming from
    the HTTP client.
    """

    def __init__(self, environ, start_response, charset='utf-8'):
        self.charset = charset
        self.start_response = start_response
        self.environ = environ
        self.environ['REQUEST_URI'] = get_full_url(self.environ)

        # copy a reference to the request object
        # into the environ so wsgi middlewares
        # can communicate with it.
        environ['colubrid.request'] = self

        # get absolute path to script
        root = self.environ.get('SCRIPT_NAME', '/')
        if not root or not root.startswith('/'):
            root = '/' + root
        self.environ['SCRIPT_ROOT'] = root

        # get the full application request
        url = ''.join([
            quote(self.environ['SCRIPT_NAME']),
            quote(self.environ.get('PATH_INFO', ''))
        ])
        if not url.startswith('/'):
            url = '/' + url
        self.environ['APPLICATION_REQUEST'] = url

    def read(self, *args):
        if not hasattr(self, '_buffered_stream'):
            self._buffered_stream = StringIO(self.data)
        return self._buffered_stream.read(*args)

    def readline(self, *args):
        if not hasattr(self, '_buffered_stream'):
            self._buffered_stream = StringIO(self.data)
        return self._buffered_stream.readline(*args)

    def readlines(self, *args):
        while True:
            line = self.readline(*args)
            if not line:
                raise StopIteration()
            yield line

    def _load_post_data(self):
        self._data = ''
        if self.environ['REQUEST_METHOD'] in ('POST', 'PUT'):
            maxlen = int(self.environ['CONTENT_LENGTH'])
            self._data = self.environ['wsgi.input'].read(maxlen)
            if self.environ.get('CONTENT_TYPE', '').startswith('multipart'):
                lines = ['Content-Type: %s' %
                         self.environ.get('CONTENT_TYPE', '')]
                for key, value in self.environ.items():
                    if key.startswith('HTTP_'):
                        lines.append('%s: %s' % (key, value))
                raw = '\r\n'.join(lines) + '\r\n\r\n' + self._data
                msg = email.message_from_string(raw)
                self._post = MultiDict()
                self._files = MultiDict()
                for sub in msg.get_payload():
                    if not isinstance(sub, MessageType):
                        continue
                    name_dict = cgi.parse_header(sub['Content-Disposition'])[1]
                    if 'filename' in name_dict:
                        payload = sub.get_payload()
                        filename = name_dict['filename']
                        if isinstance(payload, list) or not filename.strip():
                            continue
                        filename = name_dict['filename']
                        #XXX: fixes stupid ie bug but can cause problems
                        filename = filename[filename.rfind('\\') + 1:]
                        if 'Content-Type' in sub:
                            content_type = sub['Content-Type']
                        else:
                            content_type = None
                        s = FieldStorage(name_dict['name'], filename,
                                         content_type, payload)
                        self._files.appendlist(name_dict['name'], s)
                    else:
                        value = sub.get_payload()
                        if not self.charset is None:
                            value = value.decode(self.charset, 'ignore')
                        self._post.appendlist(name_dict['name'], value)
            else:
                d = cgi.parse_qs(self._data, True)
                if not self.charset is None:
                    for key, value in d.iteritems():
                        d[key] = [i.decode(self.charset, 'ignore')
                                  for i in value]
                self._post = MultiDict(d)
                self._files = MultiDict()
        else:
            self._post = MultiDict()
            self._files = MultiDict()

    def args(self):
        if not hasattr(self, '_get'):
            query = cgi.parse_qs(self.environ.get('QUERY_STRING', ''), True)
            if not self.charset is None:
                for key, value in query.iteritems():
                    query[key] = [i.decode(self.charset, 'ignore')
                                  for i in value]
            self._get = MultiDict(query)
        return self._get

    def form(self):
        if not hasattr(self, '_post'):
            self._load_post_data()
        return self._post

    def values(self):
        if not hasattr(self, '_values'):
            self._values = MergedMultiDict(self.args, self.form)
        return self._values

    def files(self):
        if not hasattr(self, '_files'):
            self._load_post_data()
        return self._files

    def cookies(self):
        if not hasattr(self, '_cookie'):
            self._cookie = SimpleCookie()
            self._cookie.load(self.environ.get('HTTP_COOKIE', ''))
        return self._cookie

    def data(self):
        if not hasattr(self, '_data'):
            self._load_post_data()
        return self._data

    args = property(args, doc='url paramters')
    form = property(form, doc='form data')
    files = property(files, doc='submitted files')
    values = property(values, doc='url parameters and form data')
    cookies = property(cookies, doc='cookies')
    data = property(data, doc='raw value of input stream')