Ticket #5682: patch_django_5682.20071203.diff

File patch_django_5682.20071203.diff, 12.7 KB (added by David Larlet, 17 years ago)

This time with mod_python, still need tests. Review welcome.

  • django/test/client.py

     
    218218
    219219        return self.request(**r)
    220220
     221    def delete(self, path, data={}, **extra):
     222        "Request a response from the server using DELETE."
     223        r = {
     224            'CONTENT_LENGTH':  None,
     225            'CONTENT_TYPE':    'text/html; charset=utf-8',
     226            'PATH_INFO':       path,
     227            'QUERY_STRING':    urlencode(data, doseq=True),
     228            'REQUEST_METHOD': 'DELETE',
     229        }
     230        r.update(extra)
     231
     232        return self.request(**r)
     233
    221234    def post(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
    222235        "Request a response from the server using POST."
    223236
     
    237250
    238251        return self.request(**r)
    239252
     253    def put(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
     254        "Request a response from the server using PUT."
     255
     256        if content_type is MULTIPART_CONTENT:
     257            put_data = encode_multipart(BOUNDARY, data)
     258        else:
     259            put_data = data
     260
     261        r = {
     262            'CONTENT_LENGTH': len(put_data),
     263            'CONTENT_TYPE':   content_type,
     264            'PATH_INFO':      path,
     265            'REQUEST_METHOD': 'PUT',
     266            'wsgi.input':     StringIO(put_data),
     267        }
     268        r.update(extra)
     269
     270        return self.request(**r)
     271
    240272    def login(self, **credentials):
    241273        """Set the Client to appear as if it has sucessfully logged into a site.
    242274
  • django/http/__init__.py

     
    2121class HttpRequest(object):
    2222    "A basic HTTP request"
    2323
    24     # The encoding used in GET/POST dicts. None means use default setting.
     24    # The encoding used in GET/POST/PUT dicts. None means use default setting.
    2525    _encoding = None
    2626
    2727    def __init__(self):
    28         self.GET, self.POST, self.COOKIES, self.META, self.FILES = {}, {}, {}, {}, {}
     28        self.GET, self.POST, self.PUT, self.COOKIES, self.META, self.DATA, self.FILES = {}, {}, {}, {}, {}, {}, {}
    2929        self.path = ''
    3030        self.method = None
    3131
    3232    def __repr__(self):
    33         return '<HttpRequest\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \
    34             (pformat(self.GET), pformat(self.POST), pformat(self.COOKIES),
    35             pformat(self.META))
     33        return '<HttpRequest\nGET:%s,\nPOST:%s,\nPUT:%s,\nCOOKIES:%s,\nMETA:%s>' % \
     34            (pformat(self.GET), pformat(self.POST), pformat(self.PUT),
     35            pformat(self.COOKIES), pformat(self.META))
    3636
    3737    def __getitem__(self, key):
    38         for d in (self.POST, self.GET):
     38        for d in (self.POST, self.GET, self.PUT):
    3939            if key in d:
    4040                return d[key]
    41         raise KeyError, "%s not found in either POST or GET" % key
     41        raise KeyError, "%s not found in either POST, GET or PUT" % key
    4242
    4343    def has_key(self, key):
    44         return key in self.GET or key in self.POST
     44        return key in self.GET or key in self.POST or key in self.PUT
    4545
    4646    __contains__ = has_key
    4747
     
    8282
    8383    def _set_encoding(self, val):
    8484        """
    85         Sets the encoding used for GET/POST accesses. If the GET or POST
     85        Sets the encoding used for GET/POST/PUT accesses. If the GET, POST or PUT
    8686        dictionary has already been created, it is removed and recreated on the
    8787        next access (so that it is decoded correctly).
    8888        """
     
    9191            del self._get
    9292        if hasattr(self, '_post'):
    9393            del self._post
     94        if hasattr(self, '_put'):
     95            del self._put
    9496
    9597    def _get_encoding(self):
    9698        return self._encoding
     
    98100    encoding = property(_get_encoding, _set_encoding)
    99101
    100102def parse_file_upload(header_dict, post_data):
    101     "Returns a tuple of (POST QueryDict, FILES MultiValueDict)"
     103    "Returns a tuple of (DATA QueryDict, FILES MultiValueDict)"
    102104    import email, email.Message
    103105    from cgi import parse_header
    104106    raw_message = '\r\n'.join(['%s:%s' % pair for pair in header_dict.items()])
    105107    raw_message += '\r\n\r\n' + post_data
    106108    msg = email.message_from_string(raw_message)
    107     POST = QueryDict('', mutable=True)
     109    DATA = QueryDict('', mutable=True)
    108110    FILES = MultiValueDict()
    109111    for submessage in msg.get_payload():
    110112        if submessage and isinstance(submessage, email.Message.Message):
     
    127129                    'content': submessage.get_payload(),
    128130                }))
    129131            else:
    130                 POST.appendlist(name_dict['name'], submessage.get_payload())
    131     return POST, FILES
     132                DATA.appendlist(name_dict['name'], submessage.get_payload())
     133    return DATA, FILES
    132134
    133135class QueryDict(MultiValueDict):
    134136    """
  • django/core/handlers/wsgi.py

     
    9191        except:
    9292            post = '<could not parse>'
    9393        try:
     94            put = pformat(self.PUT)
     95        except:
     96            put = '<could not parse>'
     97        try:
    9498            cookies = pformat(self.COOKIES)
    9599        except:
    96100            cookies = '<could not parse>'
     
    98102            meta = pformat(self.META)
    99103        except:
    100104            meta = '<could not parse>'
    101         return '<WSGIRequest\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \
    102             (get, post, cookies, meta)
     105        return '<WSGIRequest\nGET:%s,\nPOST:%s,\nPUT:%s,\nCOOKIES:%s,\nMETA:%s>' % \
     106            (get, post, put, cookies, meta)
    103107
    104108    def get_full_path(self):
    105109        return '%s%s' % (self.path, self.environ.get('QUERY_STRING', '') and ('?' + self.environ.get('QUERY_STRING', '')) or '')
     
    108112        return 'wsgi.url_scheme' in self.environ \
    109113            and self.environ['wsgi.url_scheme'] == 'https'
    110114
    111     def _load_post_and_files(self):
    112         # Populates self._post and self._files
    113         if self.method == 'POST':
     115    def _load_data_and_files(self):
     116        # Populates self._data and self._files
     117        if self.method in ('POST', 'PUT'):
    114118            if self.environ.get('CONTENT_TYPE', '').startswith('multipart'):
    115119                header_dict = dict([(k, v) for k, v in self.environ.items() if k.startswith('HTTP_')])
    116120                header_dict['Content-Type'] = self.environ.get('CONTENT_TYPE', '')
    117                 self._post, self._files = http.parse_file_upload(header_dict, self.raw_post_data)
     121                self._data, self._files = http.parse_file_upload(header_dict, self.raw_post_data)
    118122            else:
    119                 self._post, self._files = http.QueryDict(self.raw_post_data, encoding=self._encoding), datastructures.MultiValueDict()
     123                self._data, self._files = http.QueryDict(self.raw_post_data, encoding=self._encoding), datastructures.MultiValueDict()
    120124        else:
    121             self._post, self._files = http.QueryDict('', encoding=self._encoding), datastructures.MultiValueDict()
     125            self._data, self._files = http.QueryDict('', encoding=self._encoding), datastructures.MultiValueDict()
    122126
     127    def _load_post_and_files(self):
     128        # Populates self._post, preserve backward compatibility.
     129        if not hasattr(self, '_data'):
     130            self._load_data_and_files()
     131        self._post = self._data
     132
    123133    def _get_request(self):
    124134        if not hasattr(self, '_request'):
    125             self._request = datastructures.MergeDict(self.POST, self.GET)
     135            self._request = datastructures.MergeDict(self.POST, self.PUT, self.GET)
    126136        return self._request
    127137
    128138    def _get_get(self):
     
    136146
    137147    def _get_post(self):
    138148        if not hasattr(self, '_post'):
    139             self._load_post_and_files()
     149            self._post = self.DATA
    140150        return self._post
    141151
    142152    def _set_post(self, post):
    143153        self._post = post
    144154
     155    def _get_put(self):
     156        if not hasattr(self, '_put'):
     157            self._put = self.DATA
     158        return self._put
     159
     160    def _set_put(self, put):
     161        self._put = put
     162
    145163    def _get_cookies(self):
    146164        if not hasattr(self, '_cookies'):
    147165            self._cookies = http.parse_cookie(self.environ.get('HTTP_COOKIE', ''))
     
    152170
    153171    def _get_files(self):
    154172        if not hasattr(self, '_files'):
    155             self._load_post_and_files()
     173            self._load_data_and_files()
    156174        return self._files
    157175
     176    def _get_data(self):
     177        if not hasattr(self, '_data'):
     178            self._load_data_and_files()
     179        return self._data
     180
    158181    def _get_raw_post_data(self):
    159182        try:
    160183            return self._raw_post_data
     
    174197
    175198    GET = property(_get_get, _set_get)
    176199    POST = property(_get_post, _set_post)
     200    PUT = property(_get_put, _set_put)
    177201    COOKIES = property(_get_cookies, _set_cookies)
    178202    FILES = property(_get_files)
     203    DATA = property(_get_data)
    179204    REQUEST = property(_get_request)
    180205    raw_post_data = property(_get_raw_post_data)
    181206
     207
    182208class WSGIHandler(BaseHandler):
    183209    initLock = Lock()
    184210    request_class = WSGIRequest
  • django/core/handlers/modpython.py

     
    2929        except:
    3030            post = '<could not parse>'
    3131        try:
     32            put = pformat(self.PUT)
     33        except:
     34            put = '<could not parse>'
     35        try:
    3236            cookies = pformat(self.COOKIES)
    3337        except:
    3438            cookies = '<could not parse>'
     
    3640            meta = pformat(self.META)
    3741        except:
    3842            meta = '<could not parse>'
    39         return '<ModPythonRequest\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \
    40             (self.path, get, post, cookies, meta)
     43        return '<ModPythonRequest\npath:%s,\nGET:%s,\nPOST:%s,\nPUT:%s,\nCOOKIES:%s,\nMETA:%s>' % \
     44            (self.path, get, post, put, cookies, meta)
    4145
    4246    def get_full_path(self):
    4347        return '%s%s' % (self.path, self._req.args and ('?' + self._req.args) or '')
     
    4953            # mod_python < 3.2.10 doesn't have req.is_https().
    5054            return self._req.subprocess_env.get('HTTPS', '').lower() in ('on', '1')
    5155
    52     def _load_post_and_files(self):
     56    def _load_data_and_files(self):
    5357        "Populates self._post and self._files"
    5458        if 'content-type' in self._req.headers_in and self._req.headers_in['content-type'].startswith('multipart'):
    55             self._post, self._files = http.parse_file_upload(self._req.headers_in, self.raw_post_data)
     59            self._data, self._files = http.parse_file_upload(self._req.headers_in, self.raw_post_data)
    5660        else:
    57             self._post, self._files = http.QueryDict(self.raw_post_data, encoding=self._encoding), datastructures.MultiValueDict()
     61            self._data, self._files = http.QueryDict(self.raw_post_data, encoding=self._encoding), datastructures.MultiValueDict()
    5862
     63    def _load_post_and_files(self):
     64        # Populates self._post, preserve backward compatibility.
     65        if not hasattr(self, '_data'):
     66            self._load_data_and_files()
     67        self._post = self._data
     68
    5969    def _get_request(self):
    6070        if not hasattr(self, '_request'):
    61             self._request = datastructures.MergeDict(self.POST, self.GET)
     71            self._request = datastructures.MergeDict(self.POST, self.PUT, self.GET)
    6272        return self._request
    6373
    6474    def _get_get(self):
     
    7181
    7282    def _get_post(self):
    7383        if not hasattr(self, '_post'):
    74             self._load_post_and_files()
     84            self._post = self.DATA
    7585        return self._post
    7686
    7787    def _set_post(self, post):
    7888        self._post = post
    7989
     90    def _get_put(self):
     91        if not hasattr(self, '_put'):
     92            self._put = self.DATA
     93        return self._put
     94
     95    def _set_put(self, put):
     96        self._put = put
     97
    8098    def _get_cookies(self):
    8199        if not hasattr(self, '_cookies'):
    82100            self._cookies = http.parse_cookie(self._req.headers_in.get('cookie', ''))
     
    87105
    88106    def _get_files(self):
    89107        if not hasattr(self, '_files'):
    90             self._load_post_and_files()
     108            self._load_data_and_files()
    91109        return self._files
    92110
    93111    def _get_meta(self):
     
    129147
    130148    GET = property(_get_get, _set_get)
    131149    POST = property(_get_post, _set_post)
     150    PUT = property(_get_put, _set_put)
    132151    COOKIES = property(_get_cookies, _set_cookies)
    133152    FILES = property(_get_files)
     153    DATA = property(_get_data)
    134154    META = property(_get_meta)
    135155    REQUEST = property(_get_request)
    136156    raw_post_data = property(_get_raw_post_data)
Back to Top