Exemple #1
0
 def _prep_input(self, method, data, content_type):
     """Return encoded and packed POST data."""
     if data is None or method != 'POST':
         prepped = {
             'input_stream': None,
             'content_length': None,
             'content_type': None,
             }
         if method == 'GET' and data:
             qs = MultiDict()
             for key, value in to_pairs(data):
                 qs.setlistdefault(key).append(value)
             prepped['query_string'] = url_encode(qs)
         return prepped
     else:
         if content_type == 'multipart/form-data':
             data = [(k, _wrap_file(*v)) if isinstance(v, tuple) else (k,v)
                     for k,v in data]
             boundary, payload = encode_multipart(MultiDict(to_pairs(data)))
             content_type = 'multipart/form-data; boundary=' + boundary
         else:
             payload = url_encode(MultiDict(to_pairs(data)))
             content_type = 'application/x-www-form-urlencoded'
         return {
             'input_stream': StringIO(payload),
             'content_length': len(payload),
             'content_type': content_type
             }
Exemple #2
0
def restore_payload(request: Request) -> bytes:
    """
    This method takes a request and restores the original payload from it even after it has been consumed. A werkzeug
    request consumes form/multipart data from the stream, and here we are serializing it back to a request a client
    could make . This is a useful method to have when we are proxying requests, i.e., create outgoing requests from
    incoming requests that were subject to previous parsing.

    TODO: this construct is not great and will definitely be a source of trouble. but something like this will
      inevitably become the the basis of proxying werkzeug requests. The alternative is to build our own request object
      that memoizes the original payload before parsing.
    """
    data = request.data

    if request.method != "POST":
        return data

    # TODO: check how request that encode both files and form are really serialized (not sure this works this way)

    if request.form:
        data += urlencode(list(request.form.items(multi=True))).encode("utf-8")

    if request.files:
        boundary = request.content_type.split("=")[1]

        fields = MultiDict()
        fields.update(request.form)
        fields.update(request.files)

        _, data_files = encode_multipart(fields, boundary)
        data += data_files

    return data
Exemple #3
0
 def _prep_input(self, input_stream, data, content_type):
     if isinstance(data, basestring):
         assert content_type is not None, 'content type required'
     else:
         need_multipart = False
         pairs = []
         debugging = logger.isEnabledFor(DEBUG)
         for key, value in _to_pairs(data):
             if isinstance(value, basestring):
                 if isinstance(value, unicode):
                     value = str(value)
                 if debugging:
                     logger.debug("%r=%r" % (key, value))
                 pairs.append((key, value))
                 continue
             need_multipart = True
             if isinstance(value, tuple):
                 pairs.append((key, File(*value)))
             elif isinstance(value, dict):
                 pairs.append((key, File(**value)))
             elif not isinstance(value, File):
                 pairs.append((key, File(value)))
             else:
                 pairs.append((key, value))
         if need_multipart:
             boundary, data = encode_multipart(pairs)
             if content_type is None:
                 content_type = 'multipart/form-data; boundary=' + \
                     boundary
         else:
             data = urlencode(pairs)
             logger.debug('data: ' + data)
             if content_type is None:
                 content_type = 'application/x-www-form-urlencoded'
     content_length = len(data)
     input_stream = StringIO(data)
     return input_stream, content_length, content_type
Exemple #4
0
 def _prep_input(self, input_stream, data, content_type):
     if isinstance(data, basestring):
         assert content_type is not None, 'content type required'
     else:
         need_multipart = False
         pairs = []
         debugging = logger.isEnabledFor(DEBUG)
         for key, value in _to_pairs(data):
             if isinstance(value, basestring):
                 if isinstance(value, unicode):
                     value = str(value)
                 if debugging:
                     logger.debug("%r=%r" % (key, value))
                 pairs.append((key, value))
                 continue
             need_multipart = True
             if isinstance(value, tuple):
                 pairs.append((key, File(*value)))
             elif isinstance(value, dict):
                 pairs.append((key, File(**value)))
             elif not isinstance(value, File):
                 pairs.append((key, File(value)))
             else:
                 pairs.append((key, value))
         if need_multipart:
             boundary, data = encode_multipart(pairs)
             if content_type is None:
                 content_type = 'multipart/form-data; boundary=' + \
                     boundary
         else:
             data = urlencode(pairs)
             logger.debug('data: ' + data)
             if content_type is None:
                 content_type = 'application/x-www-form-urlencoded'
     content_length = len(data)
     input_stream = StringIO(data)
     return input_stream, content_length, content_type