Ejemplo n.º 1
0
    def get(self, distro=None, comp=None):

        db = self.settings['db']
        (expired, dt) = yield self._cache_expired('components', {'distro': distro, 'component': comp})
        if not expired:
            self.set_status(304)
            return
        if not dt:
            self.set_status(404)
            return
        self.add_header('Last-Modified', httputil.format_timestamp(dt))
        self.set_header('Content-Type', 'application/octet-stream')

        doc = yield db.cacus.components.find_one({'distro': distro, 'component': comp})
        if doc:
            s = common.config['repo_daemon']
            if s['proxy_storage']:
                headers = [ ('Content-Length', doc['size']), ('Last-Modified', httputil.format_timestamp(dt)) ]
                yield self.stream_from_storage(doc['sources_file'], headers=headers)
            else:
                # we use x-accel-redirect instead of direct proxying via storage plugin to allow 
                # user to offload cacus' StorageHandler if current storage allows it
                url = os.path.join(s['repo_base'], s['storage_subdir'], doc['sources_file'])
                app_log.info("Redirecting %s/%s/source/Sources to %s", distro, comp, arch, url)
                self.add_header("X-Accel-Redirect", url)
                self.set_status(200)
        else:
            self.set_status(404)
Ejemplo n.º 2
0
    def test_static_if_modified_since_time_zone(self):
        # Instead of the value from Last-Modified, make requests with times
        # chosen just before and after the known modification time
        # of the file to ensure that the right time zone is being used
        # when parsing If-Modified-Since.
        stat = os.stat(relpath('static/robots.txt'))

        response = self.fetch('/static/robots.txt', headers={
            'If-Modified-Since': format_timestamp(stat.st_mtime - 1)})
        self.assertEqual(response.code, 200)
        response = self.fetch('/static/robots.txt', headers={
            'If-Modified-Since': format_timestamp(stat.st_mtime + 1)})
        self.assertEqual(response.code, 304)
Ejemplo n.º 3
0
 def rel_as_dict(self, rel) :
     return {"uuid" : None if rel.uuid.startswith("pseudo:") else rel.uuid,
             "date_created" : httputil.format_timestamp(rel.date_created),
             "deleted" : getattr(rel, "deleted", None),
             "name" : rel.name,
             "subject" : rel.subject_uuid,
             "object" : rel.object_uuid,
             "payload" : rel.payload}
Ejemplo n.º 4
0
    def set_cookie(self, name, value, expires_days=30, version=None,
                   domain=None, expires=None, path="/", **kwargs):
        """ Sets the given cookie name/value with the given options. Set value
        to None to clear. The cookie value is secured using
        `flexx.config.cookie_secret`; don't forget to set that config
        value in your server. Additional keyword arguments are set on
        the Cookie.Morsel directly.
        """
        # This code is taken (in modified form) from the Tornado project
        # Copyright 2009 Facebook
        # Licensed under the Apache License, Version 2.0

        # Assume tornado is available ...
        from tornado.escape import native_str
        from tornado.httputil import format_timestamp
        from tornado.web import create_signed_value

        # Clear cookie?
        if value is None:
            value = ""
            expires = datetime.datetime.utcnow() - datetime.timedelta(days=365)
        else:
            secret = config.cookie_secret
            value = create_signed_value(secret, name, value, version=version,
                                        key_version=None)

        # The cookie library only accepts type str, in both python 2 and 3
        name = native_str(name)
        value = native_str(value)
        if re.search(r"[\x00-\x20]", name + value):
            # Don't let us accidentally inject bad stuff
            raise ValueError("Invalid cookie %r: %r" % (name, value))
        if name in self._cookies:
            del self._cookies[name]
        self._cookies[name] = value
        morsel = self._cookies[name]
        if domain:
            morsel["domain"] = domain
        if expires_days is not None and not expires:
            expires = datetime.datetime.utcnow() + datetime.timedelta(
                days=expires_days)
        if expires:
            morsel["expires"] = format_timestamp(expires)
        if path:
            morsel["path"] = path
        for k, v in kwargs.items():
            if k == 'max_age':
                k = 'max-age'
            # skip falsy values for httponly and secure flags because
            # SimpleCookie sets them regardless
            if k in ['httponly', 'secure'] and not v:
                continue
            morsel[k] = v

        self._exec('document.cookie = "%s";' %
                   morsel.OutputString().replace('"', '\\"'))
Ejemplo n.º 5
0
 def blob_as_dict(self, blob, with_content=False) :
     ret = {"uuid" : blob.uuid,
            "date_created" : httputil.format_timestamp(blob.date_created),
            "editor_email" : blob.editor_email,
            "content_type" : blob.content_type}
     if blob.content_type.startswith("mime:text/") :
         ret["summary"] = self.blob_summary(blob)
     if with_content :
         ret["content"] = blob.content.stuff
     return ret
Ejemplo n.º 6
0
 def set_default_headers(self):
     default_headers = {
         "Server": "TornadoServer/%s" % tornado.version,
         "Content-Type": "text/event-stream",
         "access-control-allow-origin": "*",
         "connection": "keep-alive",
         "Date": httputil.format_timestamp(time.time()),
     }
     default_headers.update(self.custom_headers())
     self._headers = httputil.HTTPHeaders(default_headers)
Ejemplo n.º 7
0
 def redirect_after(self, request):
     "Perform a redirect to ``target``"
     date = request.params.get("date")
     if date:
         retry_after = str(httputil.format_timestamp(datetime.fromtimestamp(float(date))))
     else:
         retry_after = "1"
     target = request.params.get("target", "/")
     headers = [("Location", target), ("Retry-After", retry_after)]
     return Response(status="303 See Other", headers=headers)
Ejemplo n.º 8
0
 def clear(self):
     """Resets all headers and content for this response."""
     self._headers = httputil.HTTPHeaders({
         "Server": "Durotar/%s" % durotar.version,
         "Content-Type": "text/html; charset=UTF-8",
         "Date": httputil.format_timestamp(time.time()),
     })
     self.set_default_headers()
     self._write_buffer = []
     self._status_code = 200
     self._reason = httputil.responses[200]
Ejemplo n.º 9
0
 def redirect_after(self, request):
     "Perform a redirect to ``target``"
     date = request.params.get('date')
     if date:
         retry_after = str(httputil.format_timestamp(
                 datetime.fromtimestamp(float(date))))
     else:
         retry_after = '1'
     target = request.params.get('target', '/')
     headers = [('Location', target), ('Retry-After', retry_after)]
     return Response(status='303 See Other', headers=headers)
Ejemplo n.º 10
0
    def assert_modified(self, url, mod_date):
        response = self.fetch(
            url, if_modified_since=(mod_date - timedelta(seconds=1)))

        # 200 OK, not 304 Not Modified.
        self.assertEqual(200, response.code)
        self.assertEqual(
            httputil.format_timestamp(mod_date),
            response.headers['Last-Modified'])

        response = self.fetch(url, if_modified_since=mod_date)
        self.assertEqual(304, response.code)
Ejemplo n.º 11
0
 def clear(self):
     self._headers = httputil.HTTPHeaders({
         'Server':
         self.config.web.get('name'),
         'Content-Type':
         'application/json; charset=UTF-8',
         'Date':
         httputil.format_timestamp(time.time()),
     })
     self.set_default_headers()
     self._write_buffer = []
     self._status_code = HTTPStatus.OK.value
     self._reason = HTTPStatus.OK.value
Ejemplo n.º 12
0
 def redirect_after(self, request: httputil.HTTPServerRequest) -> Response:
     "Perform a redirect to ``target``"
     params = request_params(request)
     date = params.get("date")
     if date:
         retry_after = str(
             httputil.format_timestamp(
                 datetime.utcfromtimestamp(float(date))))
     else:
         retry_after = "1"
     target = params.get("target", "/")
     headers = [("Location", target), ("Retry-After", retry_after)]
     return Response(status="303 See Other", headers=headers)
Ejemplo n.º 13
0
    def get(self, distro=None, gpg=None):
        db = self.settings['db']
        (expired, dt) = yield self._cache_expired('distros', {'distro': distro})
        if not expired:
            self.set_status(304)
            return
        self.add_header('Last-Modified', httputil.format_timestamp(dt))
        self.set_header('Content-Type', 'application/octet-stream')

        doc = yield db.cacus.distros.find_one({'distro': distro})
        if gpg:
            self.write(doc['release_gpg'])
        else:
            self.write(doc['release_file'])
Ejemplo n.º 14
0
 def clear(self):
     """Resets all headers and content for this response."""
     self._headers = httputil.HTTPHeaders({
         "Server":
         "Durotar/%s" % durotar.version,
         "Content-Type":
         "text/html; charset=UTF-8",
         "Date":
         httputil.format_timestamp(time.time()),
     })
     self.set_default_headers()
     self._write_buffer = []
     self._status_code = 200
     self._reason = httputil.responses[200]
Ejemplo n.º 15
0
 def _convert_header_value(self, value):
     if isinstance(value, bytes):
         pass
     elif isinstance(value, unicode_type):
         value = value.encode("utf-8")
     elif isinstance(value, numbers.Integral):
         return str(value)
     elif isinstance(value, datetime.datetime):
         return httputil.format_timestamp(value)
     else:
         raise TypeError("Unsupported header value %r" % value)
     if len(value) > 4000 or RequestHandler._INVALID_HEADER_CHAR_RE.search(value):
         raise ValueError("Unsafe header value %r", value)
     return value
Ejemplo n.º 16
0
 def _convert_header_value(self, value):
     if isinstance(value, bytes):
         pass
     elif isinstance(value, unicode_type):
         value = value.encode('utf-8')
     elif isinstance(value, numbers.Integral):
         return str(value)
     elif isinstance(value, datetime.datetime):
         return httputil.format_timestamp(value)
     else:
         raise TypeError("Unsupported header value %r" % value)
     if (len(value) > 4000
             or RequestHandler._INVALID_HEADER_CHAR_RE.search(value)):
         raise ValueError("Unsafe header value %r", value)
     return value
Ejemplo n.º 17
0
    def upload_file(self, file_data, file_path, content_type=None):
        """上传文件到oss服务器上

        :param file_data: 文件的数据
        :param file_path: 保存到OSS的路径
        :return:
        """
        oss = OssAPI(self.regional_node, self.id, self.key)
        expires = format_timestamp(datetime.datetime.today() + datetime.timedelta(days=+90))
        header = {'expires': expires,
                  'Cache-Control': 'max-age=%s' % (90*24*60*60)}
        if content_type:
            res = oss.put_object_from_string(self.bucket, file_path, file_data, headers=header, content_type=content_type)
        else:
            res = oss.put_object_from_string(self.bucket, file_path, file_data)
        if 200 == res.status:
            return True, file_path
        else:
            # log
            res_message = "OSS ERROR\n%s\n%s" % (res.status, res.read())
            logging.info(res_message)
            return False, u'上传文件出错!'
Ejemplo n.º 18
0
    def force_clear_cookie(self, name, path="/", domain=None):
        """Deletes the cookie with the given name.

        Tornado's cookie handling currently (Jan 2018) stores cookies in a dict
        keyed by name, so it can only modify one cookie with a given name per
        response. The browser can store multiple cookies with the same name
        but different domains and/or paths. This method lets us clear multiple
        cookies with the same name.

        Due to limitations of the cookie protocol, you must pass the same
        path and domain to clear a cookie as were used when that cookie
        was set (but there is no way to find out on the server side
        which values were used for a given cookie).
        """
        name = escape.native_str(name)
        expires = datetime.datetime.utcnow() - datetime.timedelta(days=365)

        morsel = Morsel()
        morsel.set(name, '', '""')
        morsel['expires'] = httputil.format_timestamp(expires)
        morsel['path'] = path
        if domain:
            morsel['domain'] = domain
        self.add_header("Set-Cookie", morsel.OutputString())
Ejemplo n.º 19
0
    def force_clear_cookie(self, name, path="/", domain=None):
        """Deletes the cookie with the given name.

        Tornado's cookie handling currently (Jan 2018) stores cookies in a dict
        keyed by name, so it can only modify one cookie with a given name per
        response. The browser can store multiple cookies with the same name
        but different domains and/or paths. This method lets us clear multiple
        cookies with the same name.

        Due to limitations of the cookie protocol, you must pass the same
        path and domain to clear a cookie as were used when that cookie
        was set (but there is no way to find out on the server side
        which values were used for a given cookie).
        """
        name = escape.native_str(name)
        expires = datetime.datetime.utcnow() - datetime.timedelta(days=365)

        morsel = Morsel()
        morsel.set(name, '', '""')
        morsel['expires'] = httputil.format_timestamp(expires)
        morsel['path'] = path
        if domain:
            morsel['domain'] = domain
        self.add_header("Set-Cookie", morsel.OutputString())
Ejemplo n.º 20
0
 def set_default_headers(self):
     self._headers = httputil.HTTPHeaders(
         {"Date": httputil.format_timestamp(time.time())})
Ejemplo n.º 21
0
 def test_format(self):
     format = "%A, %d-%b-%y %H:%M:%S GMT"
     expected = 'Sunday, 27-Jan-13 18:43:20 GMT'
     self.assertEqual(format_timestamp(self.TIMESTAMP, format),
                      expected)
Ejemplo n.º 22
0
    def __init__(self,
                 url,
                 method="GET",
                 headers=None,
                 body=None,
                 auth_username=None,
                 auth_password=None,
                 auth_mode=None,
                 connect_timeout=None,
                 request_timeout=None,
                 if_modified_since=None,
                 follow_redirects=None,
                 max_redirects=None,
                 user_agent=None,
                 use_gzip=None,
                 network_interface=None,
                 streaming_callback=None,
                 header_callback=None,
                 prepare_curl_callback=None,
                 proxy_host=None,
                 proxy_port=None,
                 proxy_username=None,
                 proxy_password=None,
                 proxy_auth_mode=None,
                 allow_nonstandard_methods=None,
                 validate_cert=None,
                 ca_certs=None,
                 allow_ipv6=None,
                 client_key=None,
                 client_cert=None,
                 body_producer=None,
                 expect_100_continue=False,
                 decompress_response=None,
                 ssl_options=None,
                 key=None):

        self.headers = headers
        if if_modified_since:
            self.headers["If-Modified-Since"] = httputil.format_timestamp(
                if_modified_since)
        self.proxy_host = proxy_host
        self.proxy_port = proxy_port
        self.proxy_username = proxy_username
        self.proxy_password = proxy_password
        self.proxy_auth_mode = proxy_auth_mode
        self.url = url
        self.method = method
        self.body = body
        self.body_producer = body_producer
        self.auth_username = auth_username
        self.auth_password = auth_password
        self.auth_mode = auth_mode
        self.connect_timeout = connect_timeout
        self.request_timeout = request_timeout
        self.follow_redirects = follow_redirects
        self.max_redirects = max_redirects
        self.user_agent = user_agent
        self.key = key
        if decompress_response is not None:
            self.decompress_response = decompress_response
        else:
            self.decompress_response = use_gzip
        self.network_interface = network_interface
        self.streaming_callback = streaming_callback
        self.header_callback = header_callback
        self.prepare_curl_callback = prepare_curl_callback
        self.allow_nonstandard_methods = allow_nonstandard_methods
        self.validate_cert = validate_cert
        self.ca_certs = ca_certs
        self.allow_ipv6 = allow_ipv6
        self.client_key = client_key
        self.client_cert = client_cert
        self.ssl_options = ssl_options
        self.expect_100_continue = expect_100_continue
        self.start_time = time.time()
Ejemplo n.º 23
0
    def __init__(self,
                 url,
                 method="GET",
                 headers=None,
                 body=None,
                 auth_username=None,
                 auth_password=None,
                 auth_mode=None,
                 connect_timeout=None,
                 request_timeout=None,
                 if_modified_since=None,
                 follow_redirects=None,
                 max_redirects=None,
                 user_agent=None,
                 use_gzip=None,
                 network_interface=None,
                 streaming_callback=None,
                 header_callback=None,
                 prepare_curl_callback=None,
                 proxy_host=None,
                 proxy_port=None,
                 proxy_username=None,
                 proxy_password=None,
                 allow_nonstandard_methods=None,
                 validate_cert=None,
                 ca_certs=None,
                 allow_ipv6=None,
                 client_key=None,
                 client_cert=None,
                 parent_trace=None,
                 endpoint=None):
        r"""All parameters except ``url`` are optional.

        :arg string url: URL to fetch
        :arg string method: HTTP method, e.g. "GET" or "POST"
        :arg headers: Additional HTTP headers to pass on the request
        :arg body: HTTP body to pass on the request
        :type headers: `~tornado.httputil.HTTPHeaders` or `dict`
        :arg string auth_username: Username for HTTP authentication
        :arg string auth_password: Password for HTTP authentication
        :arg string auth_mode: Authentication mode; default is "basic".
           Allowed values are implementation-defined; ``curl_httpclient``
           supports "basic" and "digest"; ``simple_httpclient`` only supports
           "basic"
        :arg float connect_timeout: Timeout for initial connection in seconds
        :arg float request_timeout: Timeout for entire request in seconds
        :arg if_modified_since: Timestamp for ``If-Modified-Since`` header
        :type if_modified_since: `datetime` or `float`
        :arg bool follow_redirects: Should redirects be followed automatically
           or return the 3xx response?
        :arg int max_redirects: Limit for ``follow_redirects``
        :arg string user_agent: String to send as ``User-Agent`` header
        :arg bool use_gzip: Request gzip encoding from the server
        :arg string network_interface: Network interface to use for request.
           ``curl_httpclient`` only; see note below.
        :arg callable streaming_callback: If set, ``streaming_callback`` will
           be run with each chunk of data as it is received, and
           ``HTTPResponse.body`` and ``HTTPResponse.buffer`` will be empty in
           the final response.
        :arg callable header_callback: If set, ``header_callback`` will
           be run with each header line as it is received (including the
           first line, e.g. ``HTTP/1.0 200 OK\r\n``, and a final line
           containing only ``\r\n``.  All lines include the trailing newline
           characters).  ``HTTPResponse.headers`` will be empty in the final
           response.  This is most useful in conjunction with
           ``streaming_callback``, because it's the only way to get access to
           header data while the request is in progress.
        :arg callable prepare_curl_callback: If set, will be called with
           a ``pycurl.Curl`` object to allow the application to make additional
           ``setopt`` calls.
        :arg string proxy_host: HTTP proxy hostname.  To use proxies,
           ``proxy_host`` and ``proxy_port`` must be set; ``proxy_username`` and
           ``proxy_pass`` are optional.  Proxies are currently only supported
           with ``curl_httpclient``.
        :arg int proxy_port: HTTP proxy port
        :arg string proxy_username: HTTP proxy username
        :arg string proxy_password: HTTP proxy password
        :arg bool allow_nonstandard_methods: Allow unknown values for ``method``
           argument?
        :arg bool validate_cert: For HTTPS requests, validate the server's
           certificate?
        :arg string ca_certs: filename of CA certificates in PEM format,
           or None to use defaults.  See note below when used with
           ``curl_httpclient``.
        :arg bool allow_ipv6: Use IPv6 when available?  Default is false in
           ``simple_httpclient`` and true in ``curl_httpclient``
        :arg string client_key: Filename for client SSL key, if any.  See
           note below when used with ``curl_httpclient``.
        :arg string client_cert: Filename for client SSL certificate, if any.
           See note below when used with ``curl_httpclient``.
        :arg string parent_trace: parent trace id.
        :arg string endpoint: request endpoint.

        .. note::

            When using ``curl_httpclient`` certain options may be
            inherited by subsequent fetches because ``pycurl`` does
            not allow them to be cleanly reset.  This applies to the
            ``ca_certs``, ``client_key``, ``client_cert``, and
            ``network_interface`` arguments.  If you use these
            options, you should pass them on every request (you don't
            have to always use the same values, but it's not possible
            to mix requests that specify these options with ones that
            use the defaults).

        .. versionadded:: 3.1
           The ``auth_mode`` argument.
        """
        # Note that some of these attributes go through property setters
        # defined below.
        self.headers = headers
        if if_modified_since:
            self.headers["If-Modified-Since"] = httputil.format_timestamp(
                if_modified_since)
        self.proxy_host = proxy_host
        self.proxy_port = proxy_port
        self.proxy_username = proxy_username
        self.proxy_password = proxy_password
        self.url = url
        self.method = method
        self.body = body
        self.auth_username = auth_username
        self.auth_password = auth_password
        self.auth_mode = auth_mode
        self.connect_timeout = connect_timeout
        self.request_timeout = request_timeout
        self.follow_redirects = follow_redirects
        self.max_redirects = max_redirects
        self.user_agent = user_agent
        self.use_gzip = use_gzip
        self.network_interface = network_interface
        self.streaming_callback = streaming_callback
        self.header_callback = header_callback
        self.prepare_curl_callback = prepare_curl_callback
        self.allow_nonstandard_methods = allow_nonstandard_methods
        self.validate_cert = validate_cert
        self.ca_certs = ca_certs
        self.allow_ipv6 = allow_ipv6
        self.client_key = client_key
        self.client_cert = client_cert
        self.start_time = time.time()
        self._parent_trace = parent_trace
        self._endpoint = endpoint
        self.trace = None

        if options.client_trace:
            if self._parent_trace is None:
                self.trace = Trace(method)
            else:
                self.trace = self._parent_trace.child(method)
            if self._endpoint is not None:
                self.trace.set_endpoint(self._endpoint)
            else:
                self._endpoint = Endpoint(ipv4=socket.gethostbyname(
                    socket.gethostname()),
                                          port=0,
                                          service_name=service_name)
                self.trace.set_endpoint(self._endpoint)

            self.headers.set('X-B3-TraceId', [hex_str(self.trace.trace_id)])
            self.headers.set('X-B3-SpanId', [hex_str(self.trace.span_id)])
            if trace.parent_span_id is not None:
                self.headers.set('X-B3-ParentSpanId',
                                 [hex_str(self.trace.parent_span_id)])

            self.trace.record(Annotation.string('HTTPClient REQ', self.url))
Ejemplo n.º 24
0
    def set_cookie(self,
                   name,
                   value,
                   domain=None,
                   expires=None,
                   path="/",
                   expires_days=None,
                   **kwargs):
        """Sets an outgoing cookie name/value with the given options.

        Newly-set cookies are not immediately visible via `get_cookie`;
        they are not present until the next request.

        expires may be a numeric timestamp as returned by `time.time`,
        a time tuple as returned by `time.gmtime`, or a
        `datetime.datetime` object.

        Additional keyword arguments are set on the cookies.Morsel
        directly.

        https://docs.python.org/3/library/http.cookies.html#http.cookies.Morsel

        ---

        Taken from Tornado's web module:

        https://github.com/tornadoweb/tornado/blob/
        627eafb3ce21a777981c37a5867b5f1956a4dc16/tornado/web.py#L528

        The main reason for bundling this in here is to allow use of the
        SameSite attribute for cookies via our vendored cookies library.

        """
        # The cookie library only accepts type str, in both python 2 and 3
        name = native_str(name)
        value = native_str(value)
        if re.search(r"[\x00-\x20]", name + value):
            # Don't let us accidentally inject bad stuff
            raise ValueError("Invalid cookie %r: %r" % (name, value))
        if not hasattr(self, "_new_cookie"):
            self._new_cookie = cookies.SimpleCookie()
        if name in self._new_cookie:
            del self._new_cookie[name]
        self._new_cookie[name] = value
        morsel = self._new_cookie[name]
        if domain:
            morsel["domain"] = domain
        if expires_days is not None and not expires:
            expires = datetime.utcnow() + timedelta(days=expires_days)
        if expires:
            morsel["expires"] = httputil.format_timestamp(expires)
        if path:
            morsel["path"] = path
        for k, v in kwargs.items():
            if k == 'max_age':
                k = 'max-age'

            # skip falsy values for httponly and secure flags because
            # SimpleCookie sets them regardless
            if k in ['httponly', 'secure'] and not v:
                continue

            morsel[k] = v
Ejemplo n.º 25
0
    def __init__(self, url, method="GET", headers=None, body=None,
                 auth_username=None, auth_password=None,
                 connect_timeout=None, request_timeout=None,
                 if_modified_since=None, follow_redirects=None,
                 max_redirects=None, user_agent=None, use_gzip=None,
                 network_interface=None, streaming_callback=None,
                 header_callback=None, prepare_curl_callback=None,
                 proxy_host=None, proxy_port=None, proxy_username=None,
                 proxy_password=None, allow_nonstandard_methods=None,
                 validate_cert=None, ca_certs=None,
                 allow_ipv6=None,
                 client_key=None, client_cert=None):
        r"""All parameters except ``url`` are optional.

        :arg string url: URL to fetch
        :arg string method: HTTP method, e.g. "GET" or "POST"
        :arg headers: Additional HTTP headers to pass on the request
        :type headers: `~tornado.httputil.HTTPHeaders` or `dict`
        :arg string auth_username: Username for HTTP "Basic" authentication
        :arg string auth_password: Password for HTTP "Basic" authentication
        :arg float connect_timeout: Timeout for initial connection in seconds
        :arg float request_timeout: Timeout for entire request in seconds
        :arg if_modified_since: Timestamp for ``If-Modified-Since`` header
        :type if_modified_since: `datetime` or `float`
        :arg bool follow_redirects: Should redirects be followed automatically
           or return the 3xx response?
        :arg int max_redirects: Limit for ``follow_redirects``
        :arg string user_agent: String to send as ``User-Agent`` header
        :arg bool use_gzip: Request gzip encoding from the server
        :arg string network_interface: Network interface to use for request
        :arg callable streaming_callback: If set, ``streaming_callback`` will
           be run with each chunk of data as it is received, and
           ``HTTPResponse.body`` and ``HTTPResponse.buffer`` will be empty in
           the final response.
        :arg callable header_callback: If set, ``header_callback`` will
           be run with each header line as it is received (including the
           first line, e.g. ``HTTP/1.0 200 OK\r\n``, and a final line
           containing only ``\r\n``.  All lines include the trailing newline
           characters).  ``HTTPResponse.headers`` will be empty in the final
           response.  This is most useful in conjunction with
           ``streaming_callback``, because it's the only way to get access to
           header data while the request is in progress.
        :arg callable prepare_curl_callback: If set, will be called with
           a ``pycurl.Curl`` object to allow the application to make additional
           ``setopt`` calls.
        :arg string proxy_host: HTTP proxy hostname.  To use proxies,
           ``proxy_host`` and ``proxy_port`` must be set; ``proxy_username`` and
           ``proxy_pass`` are optional.  Proxies are currently only supported
           with ``curl_httpclient``.
        :arg int proxy_port: HTTP proxy port
        :arg string proxy_username: HTTP proxy username
        :arg string proxy_password: HTTP proxy password
        :arg bool allow_nonstandard_methods: Allow unknown values for ``method``
           argument?
        :arg bool validate_cert: For HTTPS requests, validate the server's
           certificate?
        :arg string ca_certs: filename of CA certificates in PEM format,
           or None to use defaults.  Note that in ``curl_httpclient``, if
           any request uses a custom ``ca_certs`` file, they all must (they
           don't have to all use the same ``ca_certs``, but it's not possible
           to mix requests with ``ca_certs`` and requests that use the defaults.
        :arg bool allow_ipv6: Use IPv6 when available?  Default is false in
           ``simple_httpclient`` and true in ``curl_httpclient``
        :arg string client_key: Filename for client SSL key, if any
        :arg string client_cert: Filename for client SSL certificate, if any
        """
        if headers is None:
            headers = httputil.HTTPHeaders()
        if if_modified_since:
            headers["If-Modified-Since"] = httputil.format_timestamp(
                if_modified_since)
        self.proxy_host = proxy_host
        self.proxy_port = proxy_port
        self.proxy_username = proxy_username
        self.proxy_password = proxy_password
        self.url = url
        self.method = method
        self.headers = headers
        self.body = utf8(body)
        self.auth_username = auth_username
        self.auth_password = auth_password
        self.connect_timeout = connect_timeout
        self.request_timeout = request_timeout
        self.follow_redirects = follow_redirects
        self.max_redirects = max_redirects
        self.user_agent = user_agent
        self.use_gzip = use_gzip
        self.network_interface = network_interface
        self.streaming_callback = stack_context.wrap(streaming_callback)
        self.header_callback = stack_context.wrap(header_callback)
        self.prepare_curl_callback = stack_context.wrap(prepare_curl_callback)
        self.allow_nonstandard_methods = allow_nonstandard_methods
        self.validate_cert = validate_cert
        self.ca_certs = ca_certs
        self.allow_ipv6 = allow_ipv6
        self.client_key = client_key
        self.client_cert = client_cert
        self.start_time = time.time()
Ejemplo n.º 26
0
 def check(self, value):
     self.assertEqual(format_timestamp(value), self.EXPECTED)
Ejemplo n.º 27
0
 def __init__(
     self,
     url: str,
     method: str = "GET",
     headers: Union[Dict[str, str], httputil.HTTPHeaders] = None,
     body: Union[bytes, str] = None,
     auth_username: str = None,
     auth_password: str = None,
     auth_mode: str = None,
     connect_timeout: float = None,
     request_timeout: float = None,
     if_modified_since: Union[float, datetime.datetime] = None,
     follow_redirects: bool = None,
     max_redirects: int = None,
     user_agent: str = None,
     use_gzip: bool = None,
     network_interface: str = None,
     streaming_callback: Callable[[bytes], None] = None,
     header_callback: Callable[[str], None] = None,
     prepare_curl_callback: Callable[[Any], None] = None,
     proxy_host: str = None,
     proxy_port: int = None,
     proxy_username: str = None,
     proxy_password: str = None,
     proxy_auth_mode: str = None,
     allow_nonstandard_methods: bool = None,
     validate_cert: bool = None,
     ca_certs: str = None,
     allow_ipv6: bool = None,
     client_key: str = None,
     client_cert: str = None,
     body_producer: Callable[[Callable[[bytes], None]],
                             "Future[None]"] = None,
     expect_100_continue: bool = False,
     decompress_response: bool = None,
     ssl_options: Union[Dict[str, Any], ssl.SSLContext] = None,
 ) -> None:
     # Note that some of these attributes go through property setters
     # defined below.
     self.headers = headers
     if if_modified_since:
         self.headers["If-Modified-Since"] = httputil.format_timestamp(
             if_modified_since)
     self.proxy_host = proxy_host
     self.proxy_port = proxy_port
     self.proxy_username = proxy_username
     self.proxy_password = proxy_password
     self.proxy_auth_mode = proxy_auth_mode
     self.url = url
     self.method = method
     self.body = body
     self.body_producer = body_producer
     self.auth_username = auth_username
     self.auth_password = auth_password
     self.auth_mode = auth_mode
     self.connect_timeout = connect_timeout
     self.request_timeout = request_timeout
     self.follow_redirects = follow_redirects
     self.max_redirects = max_redirects
     self.user_agent = user_agent
     if decompress_response is not None:
         self.decompress_response = decompress_response  # type: Optional[bool]
     else:
         self.decompress_response = use_gzip
     self.network_interface = network_interface
     self.streaming_callback = streaming_callback
     self.header_callback = header_callback
     self.prepare_curl_callback = prepare_curl_callback
     self.allow_nonstandard_methods = allow_nonstandard_methods
     self.validate_cert = validate_cert
     self.ca_certs = ca_certs
     self.allow_ipv6 = allow_ipv6
     self.client_key = client_key
     self.client_cert = client_cert
     self.ssl_options = ssl_options
     self.expect_100_continue = expect_100_continue
     self.start_time = time.time()
Ejemplo n.º 28
0
    def get(self):  # def get(self, course_code, assignment_code=None):

        [course_code, assignment_code] = self.get_params(["course_id", "assignment_id"])

        if not (course_code and assignment_code):
            note = "Assigment call requires both a course code and an assignment code!!"
            self.log.info(note)
            self.finish({"success": False, "note": note})
            return

        this_user = self.nbex_user

        if not course_code in this_user["courses"]:
            note = f"User not subscribed to course {course_code}"
            self.log.info(note)
            self.finish({"success": False, "note": note})
            return

        # Find the course being referred to
        with scoped_session() as session:
            course = Course.find_by_code(
                db=session, code=course_code, org_id=this_user["org_id"], log=self.log
            )
            if course is None:
                note = f"Course {course_code} does not exist"
                self.log.info(note)
                self.finish({"success": False, "note": note})
                return  # needs a proper 'fail' here

            note = ""
            self.log.debug(f"Course:{course_code} assignment:{assignment_code}")

            # The location for the data-object is actually held in the 'released' action for the given assignment
            # We want the last one...
            assignment = AssignmentModel.find_by_code(
                db=session,
                code=assignment_code,
                course_id=course.id,
                action=AssignmentActions.released.value,
            )

            if assignment is None:
                note = f"Assignment {assignment_code} does not exist"
                self.log.info(note)
                self.finish({"success": False, "note": note})
                return  # needs a proper 'fail' here

            self._headers = httputil.HTTPHeaders(
                {
                    "Content-Type": "application/gzip",
                    "Date": httputil.format_timestamp(time.time()),
                }
            )

            data = b""

            release_file = None

            action = Action.find_most_recent_action(
                db=session,
                assignment_id=assignment.id,
                action=AssignmentActions.released,
                log=self.log,
            )
            release_file = action.location

            if release_file:
                try:
                    with open(release_file, "r+b") as handle:
                        data = handle.read()
                except Exception as e:  # TODO: exception handling
                    self.log.warning(f"Error: {e}")  # TODO: improve error message
                    self.log.info(f"Unable to open file")

                    # error 500??
                    raise Exception

                self.log.info(
                    f"Adding action {AssignmentActions.fetched.value} for user {this_user['id']} against assignment {assignment.id}"
                )
                action = Action(
                    user_id=this_user["id"],
                    assignment_id=assignment.id,
                    action=AssignmentActions.fetched,
                    location=release_file,
                )
                session.add(action)
                self.log.info("record of fetch action committed")
                self.finish(data)
            else:
                self.log.info("no release file found")
                raise Exception
Ejemplo n.º 29
0
    def __init__(self,
                 url,
                 method="GET",
                 headers=None,
                 body=None,
                 auth_username=None,
                 auth_password=None,
                 auth_mode=None,
                 connect_timeout=None,
                 request_timeout=None,
                 if_modified_since=None,
                 follow_redirects=None,
                 max_redirects=None,
                 user_agent=None,
                 use_gzip=None,
                 network_interface=None,
                 streaming_callback=None,
                 header_callback=None,
                 prepare_curl_callback=None,
                 proxy_host=None,
                 proxy_port=None,
                 proxy_username=None,
                 proxy_password=None,
                 allow_nonstandard_methods=None,
                 validate_cert=None,
                 ca_certs=None,
                 allow_ipv6=None,
                 client_key=None,
                 client_cert=None):
        r"""All parameters except ``url`` are optional.

        :arg string url: URL to fetch
        :arg string method: HTTP method, e.g. "GET" or "POST"
        :arg headers: Additional HTTP headers to pass on the request
        :type headers: `~tornado.httputil.HTTPHeaders` or `dict`
        :arg string auth_username: Username for HTTP authentication
        :arg string auth_password: Password for HTTP authentication
        :arg string auth_mode: Authentication mode; default is "basic".
           Allowed values are implementation-defined; ``curl_httpclient``
           supports "basic" and "digest"; ``simple_httpclient`` only supports
           "basic"
        :arg float connect_timeout: Timeout for initial connection in seconds
        :arg float request_timeout: Timeout for entire request in seconds
        :arg if_modified_since: Timestamp for ``If-Modified-Since`` header
        :type if_modified_since: `datetime` or `float`
        :arg bool follow_redirects: Should redirects be followed automatically
           or return the 3xx response?
        :arg int max_redirects: Limit for ``follow_redirects``
        :arg string user_agent: String to send as ``User-Agent`` header
        :arg bool use_gzip: Request gzip encoding from the server
        :arg string network_interface: Network interface to use for request
        :arg callable streaming_callback: If set, ``streaming_callback`` will
           be run with each chunk of data as it is received, and
           ``HTTPResponse.body`` and ``HTTPResponse.buffer`` will be empty in
           the final response.
        :arg callable header_callback: If set, ``header_callback`` will
           be run with each header line as it is received (including the
           first line, e.g. ``HTTP/1.0 200 OK\r\n``, and a final line
           containing only ``\r\n``.  All lines include the trailing newline
           characters).  ``HTTPResponse.headers`` will be empty in the final
           response.  This is most useful in conjunction with
           ``streaming_callback``, because it's the only way to get access to
           header data while the request is in progress.
        :arg callable prepare_curl_callback: If set, will be called with
           a ``pycurl.Curl`` object to allow the application to make additional
           ``setopt`` calls.
        :arg string proxy_host: HTTP proxy hostname.  To use proxies,
           ``proxy_host`` and ``proxy_port`` must be set; ``proxy_username`` and
           ``proxy_pass`` are optional.  Proxies are currently only supported
           with ``curl_httpclient``.
        :arg int proxy_port: HTTP proxy port
        :arg string proxy_username: HTTP proxy username
        :arg string proxy_password: HTTP proxy password
        :arg bool allow_nonstandard_methods: Allow unknown values for ``method``
           argument?
        :arg bool validate_cert: For HTTPS requests, validate the server's
           certificate?
        :arg string ca_certs: filename of CA certificates in PEM format,
           or None to use defaults.  Note that in ``curl_httpclient``, if
           any request uses a custom ``ca_certs`` file, they all must (they
           don't have to all use the same ``ca_certs``, but it's not possible
           to mix requests with ``ca_certs`` and requests that use the defaults.
        :arg bool allow_ipv6: Use IPv6 when available?  Default is false in
           ``simple_httpclient`` and true in ``curl_httpclient``
        :arg string client_key: Filename for client SSL key, if any
        :arg string client_cert: Filename for client SSL certificate, if any
        """
        if headers is None:
            headers = httputil.HTTPHeaders()
        if if_modified_since:
            headers["If-Modified-Since"] = httputil.format_timestamp(
                if_modified_since)
        self.proxy_host = proxy_host
        self.proxy_port = proxy_port
        self.proxy_username = proxy_username
        self.proxy_password = proxy_password
        self.url = url
        self.method = method
        self.headers = headers
        self.body = utf8(body)
        self.auth_username = auth_username
        self.auth_password = auth_password
        self.auth_mode = auth_mode
        self.connect_timeout = connect_timeout
        self.request_timeout = request_timeout
        self.follow_redirects = follow_redirects
        self.max_redirects = max_redirects
        self.user_agent = user_agent
        self.use_gzip = use_gzip
        self.network_interface = network_interface
        self.streaming_callback = stack_context.wrap(streaming_callback)
        self.header_callback = stack_context.wrap(header_callback)
        self.prepare_curl_callback = stack_context.wrap(prepare_curl_callback)
        self.allow_nonstandard_methods = allow_nonstandard_methods
        self.validate_cert = validate_cert
        self.ca_certs = ca_certs
        self.allow_ipv6 = allow_ipv6
        self.client_key = client_key
        self.client_cert = client_cert
        self.start_time = time.time()
Ejemplo n.º 30
0
 def test_if_modified_since(self):
     http_date = datetime.datetime.utcnow()
     request = HTTPRequest('http://example.com', if_modified_since=http_date)
     self.assertEqual(request.headers,
                      {'If-Modified-Since': format_timestamp(http_date)})
Ejemplo n.º 31
0
 def set_secure_cookie(self, key, value, expires_days=30):
     if self.request is not None:
         expires = datetime.datetime.utcnow() + datetime.timedelta(days=expires_days)
         self.request.addCookie(key, value, expires=format_timestamp(expires), path="/")
Ejemplo n.º 32
0
 def check(self, value):
     self.assertEqual(format_timestamp(value), self.EXPECTED)
Ejemplo n.º 33
0
 def set_default_headers(self):
   self._headers = httputil.HTTPHeaders({
     "Date": httputil.format_timestamp(time.time())
   })
Ejemplo n.º 34
0
    def __init__(self, url, method="GET", headers=None, body=None,
                 auth_username=None, auth_password=None, auth_mode=None,
                 connect_timeout=None, request_timeout=None,
                 if_modified_since=None, follow_redirects=None,
                 max_redirects=None, user_agent=None, use_gzip=None,
                 network_interface=None, streaming_callback=None,
                 header_callback=None, prepare_curl_callback=None,
                 proxy_host=None, proxy_port=None, proxy_username=None,
                 proxy_password=None, allow_nonstandard_methods=None,
                 validate_cert=None, ca_certs=None,
                 allow_ipv6=None,
                 client_key=None, client_cert=None, body_producer=None,
                 expect_100_continue=False):
        r"""All parameters except ``url`` are optional.

        :arg string url: URL to fetch
        :arg string method: HTTP method, e.g. "GET" or "POST"
        :arg headers: Additional HTTP headers to pass on the request
        :type headers: `~tornado.httputil.HTTPHeaders` or `dict`
        :arg body: HTTP request body as a string (byte or unicode; if unicode
           the utf-8 encoding will be used)
        :arg body_producer: Callable used for lazy/asynchronous request bodies.
           It is called with one argument, a ``write`` function, and should
           return a `.Future`.  It should call the write function with new
           data as it becomes available.  The write function returns a
           `.Future` which can be used for flow control.
           Only one of ``body`` and ``body_producer`` may
           be specified.  ``body_producer`` is not supported on
           ``curl_httpclient``.  When using ``body_producer`` it is recommended
           to pass a ``Content-Length`` in the headers as otherwise chunked
           encoding will be used, and many servers do not support chunked
           encoding on requests.  New in Tornado 4.0
        :arg string auth_username: Username for HTTP authentication
        :arg string auth_password: Password for HTTP authentication
        :arg string auth_mode: Authentication mode; default is "basic".
           Allowed values are implementation-defined; ``curl_httpclient``
           supports "basic" and "digest"; ``simple_httpclient`` only supports
           "basic"
        :arg float connect_timeout: Timeout for initial connection in seconds
        :arg float request_timeout: Timeout for entire request in seconds
        :arg if_modified_since: Timestamp for ``If-Modified-Since`` header
        :type if_modified_since: `datetime` or `float`
        :arg bool follow_redirects: Should redirects be followed automatically
           or return the 3xx response?
        :arg int max_redirects: Limit for ``follow_redirects``
        :arg string user_agent: String to send as ``User-Agent`` header
        :arg bool use_gzip: Request gzip encoding from the server
        :arg string network_interface: Network interface to use for request.
           ``curl_httpclient`` only; see note below.
        :arg callable streaming_callback: If set, ``streaming_callback`` will
           be run with each chunk of data as it is received, and
           ``HTTPResponse.body`` and ``HTTPResponse.buffer`` will be empty in
           the final response.
        :arg callable header_callback: If set, ``header_callback`` will
           be run with each header line as it is received (including the
           first line, e.g. ``HTTP/1.0 200 OK\r\n``, and a final line
           containing only ``\r\n``.  All lines include the trailing newline
           characters).  ``HTTPResponse.headers`` will be empty in the final
           response.  This is most useful in conjunction with
           ``streaming_callback``, because it's the only way to get access to
           header data while the request is in progress.
        :arg callable prepare_curl_callback: If set, will be called with
           a ``pycurl.Curl`` object to allow the application to make additional
           ``setopt`` calls.
        :arg string proxy_host: HTTP proxy hostname.  To use proxies,
           ``proxy_host`` and ``proxy_port`` must be set; ``proxy_username`` and
           ``proxy_pass`` are optional.  Proxies are currently only supported
           with ``curl_httpclient``.
        :arg int proxy_port: HTTP proxy port
        :arg string proxy_username: HTTP proxy username
        :arg string proxy_password: HTTP proxy password
        :arg bool allow_nonstandard_methods: Allow unknown values for ``method``
           argument?
        :arg bool validate_cert: For HTTPS requests, validate the server's
           certificate?
        :arg string ca_certs: filename of CA certificates in PEM format,
           or None to use defaults.  See note below when used with
           ``curl_httpclient``.
        :arg bool allow_ipv6: Use IPv6 when available?  Default is false in
           ``simple_httpclient`` and true in ``curl_httpclient``
        :arg string client_key: Filename for client SSL key, if any.  See
           note below when used with ``curl_httpclient``.
        :arg string client_cert: Filename for client SSL certificate, if any.
           See note below when used with ``curl_httpclient``.
        :arg bool expect_100_continue: If true, send the
           ``Expect: 100-continue`` header and wait for a continue response
           before sending the request body.  Only supported with
           simple_httpclient.


        .. note::

            When using ``curl_httpclient`` certain options may be
            inherited by subsequent fetches because ``pycurl`` does
            not allow them to be cleanly reset.  This applies to the
            ``ca_certs``, ``client_key``, ``client_cert``, and
            ``network_interface`` arguments.  If you use these
            options, you should pass them on every request (you don't
            have to always use the same values, but it's not possible
            to mix requests that specify these options with ones that
            use the defaults).

        .. versionadded:: 3.1
           The ``auth_mode`` argument.

        .. versionadded:: 4.0
           The ``body_producer`` and ``expect_100_continue`` arguments.
        """
        # Note that some of these attributes go through property setters
        # defined below.
        self.headers = headers
        if if_modified_since:
            self.headers["If-Modified-Since"] = httputil.format_timestamp(
                if_modified_since)
        self.proxy_host = proxy_host
        self.proxy_port = proxy_port
        self.proxy_username = proxy_username
        self.proxy_password = proxy_password
        self.url = url
        self.method = method
        self.body = body
        self.body_producer = body_producer
        self.auth_username = auth_username
        self.auth_password = auth_password
        self.auth_mode = auth_mode
        self.connect_timeout = connect_timeout
        self.request_timeout = request_timeout
        self.follow_redirects = follow_redirects
        self.max_redirects = max_redirects
        self.user_agent = user_agent
        self.use_gzip = use_gzip
        self.network_interface = network_interface
        self.streaming_callback = streaming_callback
        self.header_callback = header_callback
        self.prepare_curl_callback = prepare_curl_callback
        self.allow_nonstandard_methods = allow_nonstandard_methods
        self.validate_cert = validate_cert
        self.ca_certs = ca_certs
        self.allow_ipv6 = allow_ipv6
        self.client_key = client_key
        self.client_cert = client_cert
        self.expect_100_continue = expect_100_continue
        self.start_time = time.time()
Ejemplo n.º 35
0
    def fetch(self, target, refresh=False, cache=True, delay=None,
              follow=True, extract=None, **kwargs):
        """Fetch a URL from the wild, but first check the Cache.

        Args:
            target (str or HTTPRequest): to be fetched.
            refresh (bool, optional): should the CacheClient ask the remote
                source to refresh cached files?  Defaults to False.
            cache (bool, optional): should results be cached? Defaults to True.
            delay (int, optional): a period, in seconds, for which the client
                should delay before sending the next request after a successful
                fetch.
            follow (bool, optional): should redirects be followed? If False,
                the Response object will only contain a string to the redirect
                url target. Defaults to True.
            extract (str, optional): if supplied, the Client will try to
                extract a filename of `extract` from any resulting compressed
                file. 
            **kwargs (misc., optional): any additional keyword arguments that
                should be passed when a new HTTPRequest is initialized. 

        Returns (/ Raises):
            response (cache.Response or None): a named tuple containing values:
                - `url` (string): the url of the fetch/cache load.
                - `buffer` (BytesIO): the body of the fetch result.
                - `fresh` (bool): True if the Response object is the result of
                    a fresh response from the target server.
                or None if an error occurred (which is logged).
        """
        request = self._cached_http_request(target, follow_redirects=follow,
                                            **kwargs)
        self._log.debug("Fetching file @ {}".format(request.url))
        if not refresh and IF_MODIFIED_SINCE in request.headers:
            self._log.debug("Have cached file, not asking for a refresh.")
            response = self.cache.load(request.url)
            raise gen.Return(response)
        elif IF_MODIFIED_SINCE in request.headers:
            last_mod = request.headers[IF_MODIFIED_SINCE]
            age = datetime.datetime.now() - last_mod
            if age.seconds < REFRESH_COOLDOWN:
                self._log.debug("Have recent cached file, not refreshing.")
                raise gen.Return(self.cache.load(request.url))
            else:
                request.headers[IF_MODIFIED_SINCE] = format_timestamp(last_mod)
        try:
            response = yield self._client.fetch(request)
        except HTTPError as err:
            if err.code == FILE_UNCHANGED:
                self._log.debug("File unchanged, using cached version.")
                raise gen.Return(self.cache.load(request.url))

            # If we get a 302, and we're expecting it, return the location and
            # fresh to indicate that the destination is a new one (since we
            # had to reach out to the server.
            elif err.code == SOFT_REDIRECT and not follow:
                loc = err.response.headers[LOCATION_HEADER]
                self._log.debug('Redirected to {}, not following'.format(loc))
                response = Response(BytesIO(loc), request.url, True)
                raise gen.Return(response)
            else:
                self._log.error(
                    "{0} ({1}) fetching {2}".format(err, err.code, request.url))
                raise gen.Return(None)

        except Exception as excp:
            self._log.exception(excp)
            raise gen.Return(None)
        else:
            self._log.debug("Got fresh file @ {0}".format(request.url))
            if extract:
                response.buffer = decompress_response(response.buffer, extract)

            if cache:
                self._log.debug("Caching {0}".format(request.url))
                self.cache_response(response, overwrite=True)
            response = Response(response.buffer, request.url, True)
            raise gen.Return(response)
        finally:
            if delay:
                self._log.debug("Pausing @ {0} for {1} sec(s)".format(
                    self.ioloop.time(), delay))
                yield gen.sleep(delay)
Ejemplo n.º 36
0
 def test_if_modified_since(self):
     http_date = datetime.datetime.utcnow()
     request = HTTPRequest('http://example.com', if_modified_since=http_date)
     self.assertEqual(request.headers,
                      {'If-Modified-Since': format_timestamp(http_date)})
Ejemplo n.º 37
0
    def __init__(self, url, method="GET", headers=None, body=None,
                 auth_username=None, auth_password=None, auth_mode=None,
                 connect_timeout=None, request_timeout=None,
                 if_modified_since=None, follow_redirects=None,
                 max_redirects=None, user_agent=None, use_gzip=None,
                 network_interface=None, streaming_callback=None,
                 header_callback=None, prepare_curl_callback=None,
                 proxy_host=None, proxy_port=None, proxy_username=None,
                 proxy_password=None, allow_nonstandard_methods=None,
                 validate_cert=None, ca_certs=None,
                 allow_ipv6=None,
                 client_key=None, client_cert=None,
                 parent_trace=None, endpoint=None):
        r"""All parameters except ``url`` are optional.

        :arg string url: URL to fetch
        :arg string method: HTTP method, e.g. "GET" or "POST"
        :arg headers: Additional HTTP headers to pass on the request
        :arg body: HTTP body to pass on the request
        :type headers: `~tornado.httputil.HTTPHeaders` or `dict`
        :arg string auth_username: Username for HTTP authentication
        :arg string auth_password: Password for HTTP authentication
        :arg string auth_mode: Authentication mode; default is "basic".
           Allowed values are implementation-defined; ``curl_httpclient``
           supports "basic" and "digest"; ``simple_httpclient`` only supports
           "basic"
        :arg float connect_timeout: Timeout for initial connection in seconds
        :arg float request_timeout: Timeout for entire request in seconds
        :arg if_modified_since: Timestamp for ``If-Modified-Since`` header
        :type if_modified_since: `datetime` or `float`
        :arg bool follow_redirects: Should redirects be followed automatically
           or return the 3xx response?
        :arg int max_redirects: Limit for ``follow_redirects``
        :arg string user_agent: String to send as ``User-Agent`` header
        :arg bool use_gzip: Request gzip encoding from the server
        :arg string network_interface: Network interface to use for request.
           ``curl_httpclient`` only; see note below.
        :arg callable streaming_callback: If set, ``streaming_callback`` will
           be run with each chunk of data as it is received, and
           ``HTTPResponse.body`` and ``HTTPResponse.buffer`` will be empty in
           the final response.
        :arg callable header_callback: If set, ``header_callback`` will
           be run with each header line as it is received (including the
           first line, e.g. ``HTTP/1.0 200 OK\r\n``, and a final line
           containing only ``\r\n``.  All lines include the trailing newline
           characters).  ``HTTPResponse.headers`` will be empty in the final
           response.  This is most useful in conjunction with
           ``streaming_callback``, because it's the only way to get access to
           header data while the request is in progress.
        :arg callable prepare_curl_callback: If set, will be called with
           a ``pycurl.Curl`` object to allow the application to make additional
           ``setopt`` calls.
        :arg string proxy_host: HTTP proxy hostname.  To use proxies,
           ``proxy_host`` and ``proxy_port`` must be set; ``proxy_username`` and
           ``proxy_pass`` are optional.  Proxies are currently only supported
           with ``curl_httpclient``.
        :arg int proxy_port: HTTP proxy port
        :arg string proxy_username: HTTP proxy username
        :arg string proxy_password: HTTP proxy password
        :arg bool allow_nonstandard_methods: Allow unknown values for ``method``
           argument?
        :arg bool validate_cert: For HTTPS requests, validate the server's
           certificate?
        :arg string ca_certs: filename of CA certificates in PEM format,
           or None to use defaults.  See note below when used with
           ``curl_httpclient``.
        :arg bool allow_ipv6: Use IPv6 when available?  Default is false in
           ``simple_httpclient`` and true in ``curl_httpclient``
        :arg string client_key: Filename for client SSL key, if any.  See
           note below when used with ``curl_httpclient``.
        :arg string client_cert: Filename for client SSL certificate, if any.
           See note below when used with ``curl_httpclient``.
        :arg string parent_trace: parent trace id.
        :arg string endpoint: request endpoint.

        .. note::

            When using ``curl_httpclient`` certain options may be
            inherited by subsequent fetches because ``pycurl`` does
            not allow them to be cleanly reset.  This applies to the
            ``ca_certs``, ``client_key``, ``client_cert``, and
            ``network_interface`` arguments.  If you use these
            options, you should pass them on every request (you don't
            have to always use the same values, but it's not possible
            to mix requests that specify these options with ones that
            use the defaults).

        .. versionadded:: 3.1
           The ``auth_mode`` argument.
        """
        # Note that some of these attributes go through property setters
        # defined below.
        self.headers = headers
        if if_modified_since:
            self.headers["If-Modified-Since"] = httputil.format_timestamp(
                if_modified_since)
        self.proxy_host = proxy_host
        self.proxy_port = proxy_port
        self.proxy_username = proxy_username
        self.proxy_password = proxy_password
        self.url = url
        self.method = method
        self.body = body
        self.auth_username = auth_username
        self.auth_password = auth_password
        self.auth_mode = auth_mode
        self.connect_timeout = connect_timeout
        self.request_timeout = request_timeout
        self.follow_redirects = follow_redirects
        self.max_redirects = max_redirects
        self.user_agent = user_agent
        self.use_gzip = use_gzip
        self.network_interface = network_interface
        self.streaming_callback = streaming_callback
        self.header_callback = header_callback
        self.prepare_curl_callback = prepare_curl_callback
        self.allow_nonstandard_methods = allow_nonstandard_methods
        self.validate_cert = validate_cert
        self.ca_certs = ca_certs
        self.allow_ipv6 = allow_ipv6
        self.client_key = client_key
        self.client_cert = client_cert
        self.start_time = time.time()
        self._parent_trace = parent_trace
        self._endpoint = endpoint
        self.trace = None
        
        if options.client_trace:
            if self._parent_trace is None:
                self.trace = Trace(method)
            else:
                self.trace = self._parent_trace.child(method)
            if self._endpoint is not None:
                self.trace.set_endpoint(self._endpoint)
            else:
                self._endpoint = Endpoint(ipv4=socket.gethostbyname(socket.gethostname()), port=0, service_name=service_name)
                self.trace.set_endpoint(self._endpoint)
            
            self.headers.set('X-B3-TraceId', [hex_str(self.trace.trace_id)])
            self.headers.set('X-B3-SpanId', [hex_str(self.trace.span_id)])
            if trace.parent_span_id is not None:
                self.headers.set('X-B3-ParentSpanId', [hex_str(self.trace.parent_span_id)])
            
            self.trace.record(Annotation.string('HTTPClient REQ', self.url))
Ejemplo n.º 38
0
    def set_cookie(self,
                   name,
                   value,
                   expires_days=30,
                   version=None,
                   domain=None,
                   expires=None,
                   path="/",
                   **kwargs):
        """ Sets the given cookie name/value with the given options. Set value
        to None to clear. The cookie value is secured using
        `flexx.config.cookie_secret`; don't forget to set that config
        value in your server. Additional keyword arguments are set on
        the Cookie.Morsel directly.
        """
        # This code is taken (in modified form) from the Tornado project
        # Copyright 2009 Facebook
        # Licensed under the Apache License, Version 2.0

        # Assume tornado is available ...
        from tornado.escape import native_str
        from tornado.httputil import format_timestamp
        from tornado.web import create_signed_value

        # Clear cookie?
        if value is None:
            value = ""
            expires = datetime.datetime.utcnow() - datetime.timedelta(days=365)
        else:
            secret = config.cookie_secret
            value = create_signed_value(secret,
                                        name,
                                        value,
                                        version=version,
                                        key_version=None)

        # The cookie library only accepts type str, in both python 2 and 3
        name = native_str(name)
        value = native_str(value)
        if re.search(r"[\x00-\x20]", name + value):
            # Don't let us accidentally inject bad stuff
            raise ValueError("Invalid cookie %r: %r" % (name, value))
        if name in self._cookies:
            del self._cookies[name]
        self._cookies[name] = value
        morsel = self._cookies[name]
        if domain:
            morsel["domain"] = domain
        if expires_days is not None and not expires:
            expires = datetime.datetime.utcnow() + datetime.timedelta(
                days=expires_days)
        if expires:
            morsel["expires"] = format_timestamp(expires)
        if path:
            morsel["path"] = path
        for k, v in kwargs.items():
            if k == 'max_age':
                k = 'max-age'
            # skip falsy values for httponly and secure flags because
            # SimpleCookie sets them regardless
            if k in ['httponly', 'secure'] and not v:
                continue
            morsel[k] = v

        self.send_command(
            'EXEC', 'document.cookie = "%s";' %
            morsel.OutputString().replace('"', '\\"'))
Ejemplo n.º 39
0
    def __init__(self,
                 url,
                 method="GET",
                 headers=None,
                 body=None,
                 auth_username=None,
                 auth_password=None,
                 auth_mode=None,
                 connect_timeout=None,
                 request_timeout=None,
                 if_modified_since=None,
                 follow_redirects=None,
                 max_redirects=None,
                 user_agent=None,
                 use_gzip=None,
                 network_interface=None,
                 streaming_callback=None,
                 header_callback=None,
                 prepare_curl_callback=None,
                 proxy_host=None,
                 proxy_port=None,
                 proxy_username=None,
                 proxy_password=None,
                 allow_nonstandard_methods=None,
                 validate_cert=None,
                 ca_certs=None,
                 allow_ipv6=None,
                 client_key=None,
                 client_cert=None,
                 body_producer=None,
                 expect_100_continue=False,
                 decompress_response=None,
                 ssl_options=None):
        r"""除了 ``url`` 以外所有参数都是可选的.

        :arg string url: fetch 的 URL
        :arg string method: HTTP 方法, e.g. "GET" or "POST"
        :arg headers: 额外的 HTTP 请求头
        :type headers: `~tornado.httputil.HTTPHeaders` 或 `dict`
        :arg body: HTTP 请求体字符串 (byte 或 unicode; 如果是 unicode
           则使用 utf-8 编码)
        :arg body_producer: 可以被用于延迟/异步请求体调用.
           它可以被调用, 带有一个参数, 一个 ``write`` 函数, 并应该
           返回一个 `.Future` 对象.  它应该在新的数据可用时调用 write 函数.
           write 函数返回一个可用于流程控制的 `.Future` 对象.
           只能指定 ``body`` 和 ``body_producer`` 其中之一.
           ``body_producer`` 不被 ``curl_httpclient`` 支持.
           当使用 ``body_producer`` 时, 建议传递一个
           ``Content-Length`` 头, 否则将使用其他的分块编码,
           并且很多服务断不支持请求的分块编码.  Tornado 4.0 新增
        :arg string auth_username: HTTP 认证的用户名
        :arg string auth_password: HTTP 认证的密码
        :arg string auth_mode: 认证模式; 默认是 "basic".
           所允许的值是根据实现方式定义的; ``curl_httpclient``
           支持 "basic" 和 "digest"; ``simple_httpclient`` 只支持 "basic"
        :arg float connect_timeout: 初始化连接的超时时间
        :arg float request_timeout: 整个请求的超时时间
        :arg if_modified_since: ``If-Modified-Since`` 头的时间戳
        :type if_modified_since: `datetime` 或 `float`
        :arg bool follow_redirects: 是否应该自动跟随重定向还是返回 3xx 响应?
        :arg int max_redirects: ``follow_redirects`` 的最大次数限制
        :arg string user_agent: ``User-Agent`` 头
        :arg bool decompress_response: 从服务器请求一个压缩过的响应, 在下载
           后对其解压缩.  默认是 True.
           Tornado 4.0 新增.
        :arg bool use_gzip: ``decompress_response`` 的别名从 Tornado 4.0 已弃用.
        :arg string network_interface: 请求所使用的网络接口.
           只有 ``curl_httpclient`` ; 请看下面的备注.
        :arg callable streaming_callback: 如果设置了, ``streaming_callback`` 将
           用它接收到的数据块执行, 并且
           ``HTTPResponse.body`` 和 ``HTTPResponse.buffer`` 在最后的响应中将为空.
        :arg callable header_callback: 如果设置了, ``header_callback`` 将
           在接收到每行头信息时运行(包括第一行, e.g. ``HTTP/1.0 200 OK\r\n``,
           最后一行只包含 ``\r\n``.  所有行都包含结尾的换行符).
           ``HTTPResponse.headers`` 在最终响应中将为空.  这与
           ``streaming_callback`` 结合是最有用的, 因为它是在请求正在进行时
           访问头信息唯一的方法.
        :arg callable prepare_curl_callback: 如果设置, 将使用
           ``pycurl.Curl`` 对象调用, 以允许应用程序进行额外的
           ``setopt`` 调用.
        :arg string proxy_host: HTTP 代理主机名.  如果想要使用代理,
           ``proxy_host`` 和 ``proxy_port`` 必须设置; ``proxy_username`` 和
           ``proxy_pass`` 是可选项.  目前只有 ``curl_httpclient`` 支持代理.
        :arg int proxy_port: HTTP 代理端口
        :arg string proxy_username: HTTP 代理用户名
        :arg string proxy_password: HTTP 代理密码
        :arg bool allow_nonstandard_methods: 允许 ``method`` 参数使用未知值?
        :arg bool validate_cert: 对于 HTTPS 请求, 是否验证服务器的证书?
        :arg string ca_certs: PEM 格式的 CA 证书的文件名, 或者默认为 None.
           当与 ``curl_httpclient`` 一起使用时参阅下面的注释.
        :arg string client_key: 客户端 SSL key 文件名(如果有).
           当与 ``curl_httpclient`` 一起使用时参阅下面的注释.
        :arg string client_cert: 客户端 SSL 证书的文件名(如果有).
           当与 ``curl_httpclient`` 一起使用时参阅下面的注释.
        :arg ssl.SSLContext ssl_options: 用在
           ``simple_httpclient`` (``curl_httpclient`` 不支持) 的
           `ssl.SSLContext` 对象.
           覆写 ``validate_cert``, ``ca_certs``, ``client_key``,
           和 ``client_cert``.
        :arg bool allow_ipv6: 当 IPv6 可用时是否使用?  默认是 true.
        :arg bool expect_100_continue: 如果为 true, 发送
           ``Expect: 100-continue`` 头并在发送请求体前等待继续响应.
           只被 simple_httpclient 支持.

        .. 注意::

            当使用 ``curl_httpclient`` 时, 某些选项可能会被后续获取
            的继承, 因为 ``pycurl`` 不允许它们被彻底重置.  这适用于
            ``ca_certs``, ``client_key``, ``client_cert``, 和
            ``network_interface`` 参数. 如果你使用这些参数, 你应该在
            每次请求中都传递它们(你不必总使用相同的值, 但不能混合
            指定了这些参数和使用默认参数的请求).

        .. versionadded:: 3.1
           ``auth_mode`` 参数.

        .. versionadded:: 4.0
           ``body_producer`` 和 ``expect_100_continue`` 参数.

        .. versionadded:: 4.2
           ``ssl_options`` 参数.
        """
        # Note that some of these attributes go through property setters
        # defined below.
        self.headers = headers
        if if_modified_since:
            self.headers["If-Modified-Since"] = httputil.format_timestamp(
                if_modified_since)
        self.proxy_host = proxy_host
        self.proxy_port = proxy_port
        self.proxy_username = proxy_username
        self.proxy_password = proxy_password
        self.url = url
        self.method = method
        self.body = body
        self.body_producer = body_producer
        self.auth_username = auth_username
        self.auth_password = auth_password
        self.auth_mode = auth_mode
        self.connect_timeout = connect_timeout
        self.request_timeout = request_timeout
        self.follow_redirects = follow_redirects
        self.max_redirects = max_redirects
        self.user_agent = user_agent
        if decompress_response is not None:
            self.decompress_response = decompress_response
        else:
            self.decompress_response = use_gzip
        self.network_interface = network_interface
        self.streaming_callback = streaming_callback
        self.header_callback = header_callback
        self.prepare_curl_callback = prepare_curl_callback
        self.allow_nonstandard_methods = allow_nonstandard_methods
        self.validate_cert = validate_cert
        self.ca_certs = ca_certs
        self.allow_ipv6 = allow_ipv6
        self.client_key = client_key
        self.client_cert = client_cert
        self.ssl_options = ssl_options
        self.expect_100_continue = expect_100_continue
        self.start_time = time.time()