예제 #1
0
def _convert_files(files):
    """Files can be passed in a variety of formats:

        * {'file': open("bla.f")}
        * {'file': (name, open("bla.f"))}
        * {'file': (name, content-type, open("bla.f"))}
        * Anything that has iteritems method, e.g. MultiDict:
          MultiDict([(name, open()), (name, open())]

        Our goal is to standardize it to unified form of:

        * [(param, (file name, content type, producer))]
    """

    if hasattr(files, "iteritems"):
        files = files.iteritems()

    for param, val in files:
        file_name, content_type, fobj = (None, None, None)
        if isinstance(val, tuple):
            if len(val) == 2:
                file_name, fobj = val
            elif len(val) == 3:
                file_name, content_type, fobj = val
        else:
            fobj = val
            if hasattr(fobj, "name"):
                file_name = path.basename(fobj.name)

        if not content_type:
            content_type = _guess_content_type(file_name)

        yield (param, (file_name, content_type, IBodyProducer(fobj)))
예제 #2
0
        def requestReceived(method, url, version, headers, body):
            self.assertIsInstance(method, bytes)
            self.assertIsInstance(url, urlparse.ParseResult)
            self.assertIsInstance(version, bytes)
            self.assertIsInstance(headers, Headers)
            self.assertTrue(IBodyProducer.providedBy(body))

            self.receivedRequest = (method, url, version, headers, body)
예제 #3
0
파일: client.py 프로젝트: bennr01/treq
def _convert_files(files):
    """Files can be passed in a variety of formats:

        * {'file': open("bla.f")}
        * {'file': (name, open("bla.f"))}
        * {'file': (name, content-type, open("bla.f"))}
        * Anything that has iteritems method, e.g. MultiDict:
          MultiDict([(name, open()), (name, open())]

        Our goal is to standardize it to unified form of:

        * [(param, (file name, content type, producer))]
    """

    if hasattr(files, "iteritems"):
        files = files.iteritems()
    elif hasattr(files, "items"):
        files = files.items()

    for param, val in files:
        file_name, content_type, fobj = (None, None, None)
        if isinstance(val, tuple):
            if len(val) == 2:
                file_name, fobj = val
            elif len(val) == 3:
                file_name, content_type, fobj = val
            else:
                # NB: This is TypeError for backward compatibility. This case
                # used to fall through to `IBodyProducer`, below, which raised
                # TypeError about being unable to coerce None.
                raise TypeError(
                    ("`files` argument must be a sequence of tuples of"
                     " (file_name, file_obj) or"
                     " (file_name, content_type, file_obj),"
                     " but the {!r} tuple has length {}: {!r}").format(
                         param, len(val), val), )
        else:
            fobj = val
            if hasattr(fobj, "name"):
                file_name = FilePath(fobj.name).basename()

        if not content_type:
            content_type = _guess_content_type(file_name)

        # XXX: Shouldn't this call self._data_to_body_producer?
        yield (param, (file_name, content_type, IBodyProducer(fobj)))
예제 #4
0
 def request(self, method, uri, headers=None, bodyProducer=None):
     # type: (bytes, bytes, Optional[Headers], Optional[IBodyProducer]) -> Deferred[IResponse]  # noqa
     if not isinstance(method, bytes):
         raise TypeError("method must be bytes, not {!r} of type {}".format(
             method, type(method)))
     if not isinstance(uri, bytes):
         raise TypeError("uri must be bytes, not {!r} of type {}".format(
             uri, type(uri)))
     if headers is not None and not isinstance(headers, Headers):
         raise TypeError("headers must be {}, not {!r} of type {}".format(
             type(Headers), headers, type(headers)))
     if bodyProducer is not None and not IBodyProducer.providedBy(
             bodyProducer):
         raise TypeError((
             "bodyProducer must implement IBodyProducer, but {!r} does not."
             " Is the implementation marked with @implementer(IBodyProducer)?"
         ).format(bodyProducer))
     d = Deferred()
     record = RequestRecord(method, uri, headers, bodyProducer, d)
     self._callback(record)
     return d
    def assertRequest(self, agent, method, url, headers, body):
        call = self.agent.request.mock_calls[-1][1]
        self.assertEqual(call[0], method)
        self.assertEqual(call[1], url)
        self.assertEqual(call[2], headers)

        if not body:
            #self.assertEqual(call[3], body)
            return

        bodyProducer = call[3]

        self.assertTrue(IBodyProducer.providedBy(bodyProducer))

        output = StringIO()
        consumer = FileConsumer(output)

        def _check_body(_):
            self.assertEqual(output.getvalue(), body)

        d = bodyProducer.startProducing(consumer)
        d.addCallback(_check_body)
        return d
예제 #6
0
    def request(self, method, url, **kwargs):
        method = method.upper()

        # Join parameters provided in the URL
        # and the ones passed as argument.
        params = kwargs.get('params')
        if params:
            url = _combine_query_params(url, params)

        # Convert headers dictionary to
        # twisted raw headers format.
        headers = kwargs.get('headers')
        if headers:
            if isinstance(headers, dict):
                h = Headers({})
                for k, v in headers.iteritems():
                    if isinstance(v, str):
                        h.addRawHeader(k, v)
                    else:
                        h.setRawHeaders(k, v)

                headers = h
        else:
            headers = Headers({})

        # Here we choose a right producer
        # based on the parameters passed in.
        bodyProducer = None
        data = kwargs.get('data')
        files = kwargs.get('files')
        if files:
            # If the files keyword is present we will issue a
            # multipart/form-data request as it suits better for cases
            # with files and/or large objects.
            files = list(_convert_files(files))
            boundary = uuid.uuid4()
            headers.setRawHeaders(
                'content-type', [
                    'multipart/form-data; boundary=%s' % (boundary,)])
            if data:
                data = _convert_params(data)
            else:
                data = []

            bodyProducer = multipart.MultiPartProducer(
                data + files, boundary=boundary)
        elif data:
            # Otherwise stick to x-www-form-urlencoded format
            # as it's generally faster for smaller requests.
            if isinstance(data, (dict, list, tuple)):
                headers.setRawHeaders(
                    'content-type', ['application/x-www-form-urlencoded'])
                data = urlencode(data, doseq=True)
            bodyProducer = IBodyProducer(data)

        cookies = kwargs.get('cookies', {})

        if not isinstance(cookies, CookieJar):
            cookies = cookiejar_from_dict(cookies)

        cookies = merge_cookies(self._cookiejar, cookies)

        wrapped_agent = CookieAgent(self._agent, cookies)

        if kwargs.get('allow_redirects', True):
            wrapped_agent = RedirectAgent(wrapped_agent)

        wrapped_agent = ContentDecoderAgent(wrapped_agent,
                                            [('gzip', GzipDecoder)])

        auth = kwargs.get('auth')
        if auth:
            wrapped_agent = add_auth(wrapped_agent, auth)

        d = wrapped_agent.request(
            method, url, headers=headers,
            bodyProducer=bodyProducer)

        timeout = kwargs.get('timeout')
        if timeout:
            delayedCall = default_reactor(kwargs.get('reactor')).callLater(
                timeout, d.cancel)

            def gotResult(result):
                if delayedCall.active():
                    delayedCall.cancel()
                return result

            d.addBoth(gotResult)

        if not kwargs.get('unbuffered', False):
            d.addCallback(_BufferedResponse)

        return d.addCallback(_Response, cookies)