Exemplo n.º 1
0
def redirect(location, code=302):
    """Return a response object (a WSGI application) that, if called,
    redirects the client to the target location.  Supported codes are 301,
    302, 303, 305, and 307.  300 is not supported because it's not a real
    redirect and 304 because it's the answer for a request with a request
    with defined If-Modified-Since headers.

    .. versionadded:: 0.6
       The location can now be a unicode string that is encoded using
       the :func:`iri_to_uri` function.

    :param location: the location the response should redirect to.
    :param code: the redirect status code. defaults to 302.
    """
    display_location = escape(location)
    if isinstance(location, str):
        location = iri_to_uri(location)
    response = Response(
        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
        '<title>Redirecting...</title>\n'
        '<h1>Redirecting...</h1>\n'
        '<p>You should be redirected automatically to target URL: '
        '<a href="%s">%s</a>.  If not click the link.' %
        (escape(location), display_location), code, mimetype="text/html")
    response.headers["Location"] = location
    return response
Exemplo n.º 2
0
def project_json(app, request, project_name):
    # fail early if callback is invalid
    callback = request.args.get("callback")
    if callback:
        if not is_valid_json_callback_name(callback):
            raise BadRequest("invalid JSONP callback name")

    # Get the real project name for this project
    project = app.db.packaging.get_project(project_name)

    if project is None:
        raise NotFound("{} does not exist".format(project_name))

    # we're looking for the latest version
    versions = app.db.packaging.get_project_versions(project)
    if not versions:
        raise NotFound("{} has no releases".format(project))
    version = versions[0]

    rpc = xmlrpc.Interface(app, request)

    d = dict(info=rpc.release_data(project, version), urls=rpc.release_urls(project, version))
    for url in d["urls"]:
        url["upload_time"] = url["upload_time"].strftime("%Y-%m-%dT%H:%M:%S")

    data = json.dumps(d, sort_keys=True)

    # write the JSONP extra crap if necessary
    if callback:
        data = "/**/ %s(%s);" % (callback, data)

    response = Response(data, mimetype="application/json")
    response.headers["Content-Disposition"] = "inline"
    return response
Exemplo n.º 3
0
def project_json(app, request, project_name, version=None):
    # fail early if callback is invalid
    callback = request.args.get('callback')
    if callback:
        if not is_valid_json_callback_name(callback):
            raise BadRequest('invalid JSONP callback name')

    # Get the real project name for this project
    project = app.db.packaging.get_project(project_name)

    if project is None:
        raise NotFound("{} does not exist".format(project_name))

    # we're looking for the latest version
    versions = app.db.packaging.get_project_versions(project['name'])
    if version is None:
        if not versions:
            raise NotFound("{} has no releases".format(project_name))
        version = versions[0]
    elif version not in versions:
        raise NotFound("{} has no release {}".format(project_name, version))

    rpc = xmlrpc.Interface(app, request)

    d = dict(
        info=rpc.release_data(project['name'], version),
        urls=rpc.release_urls(project['name'], version),
        releases=rpc.all_release_urls(project['name']),
    )
    time_format = '%Y-%m-%dT%H:%M:%S'
    for url in d['urls']:
        url['upload_time'] = url['upload_time'].strftime(time_format)
    for release, urls in d['releases'].items():
        for url in urls:
            url['upload_time'] = url['upload_time'].strftime(time_format)

    data = json.dumps(d, sort_keys=True)

    # write the JSONP extra crap if necessary
    if callback:
        data = '/**/ %s(%s);' % (callback, data)

    serial = app.db.packaging.get_last_serial()

    response = Response(data, mimetype="application/json")
    response.headers['Content-Disposition'] = 'inline'
    response.headers.add("X-PyPI-Last-Serial", serial)
    return response
Exemplo n.º 4
0
def test_response_surrogate_control():
    resp = Response()

    assert "Surrogate-Control" not in resp.headers

    resp.surrogate_control.public = True
    resp.surrogate_control.max_age = 120

    assert set(resp.headers["Surrogate-Control"].split(", ")) == {
        "max-age=120",
        "public",
    }
Exemplo n.º 5
0
def render_response(app, request, template, **variables):
    template = app.templates.get_template(template)

    context = {
        "config": app.config,
        "gravatar_url": helpers.gravatar_url,
        "static_url": functools.partial(helpers.static_url, app),
        "url_for": functools.partial(helpers.url_for, request),
    }
    context.update(variables)

    return Response(template.render(**context), mimetype="text/html")
Exemplo n.º 6
0
    def test_csrf_already_ensured(self):
        def fn(self, view, app, request, *args, **kwargs):
            return view(app, request, *args, **kwargs)

        view = lambda app, request: Response()
        view._csrf = True
        app = pretend.stub()
        request = pretend.stub(_session={"user.csrf": "1234"}, method="GET")

        handle_csrf(fn)(pretend.stub(), view, app, request)

        assert request._session == {"user.csrf": "1234"}
Exemplo n.º 7
0
    def test_existing_session_no_save(self):
        def fn(self, view, app, request, *args, **kwargs):
            return view(app, request, *args, **kwargs)

        view = lambda app, request: Response()
        app = pretend.stub(session_store=FakeSessionStore())
        request = pretend.stub(cookies={"session_id": "abcd"}, is_secure=False)

        response = handle_session(fn)(pretend.stub(), view, app, request)

        assert app.session_store.saved == []
        assert response.headers.getlist("Set-Cookie") == []
Exemplo n.º 8
0
    def test_csrf_disallows_unsafe(self, method):
        def fn(self, view, app, request, *args, **kwargs):
            return view(app, request, *args, **kwargs)

        view = lambda app, request: Response()
        app = pretend.stub()
        request = pretend.stub(_session={}, method=method)

        with pytest.raises(SecurityError) as excinfo:
            handle_csrf(fn)(pretend.stub(), view, app, request)

        assert (
            excinfo.value.description == "No CSRF protection applied to view")
Exemplo n.º 9
0
def handle_request(app, request):
    '''Wrap an invocation of the XML-RPC dispatcher.
    '''
    dispatcher = SimpleXMLRPCDispatcher()
    dispatcher.register_instance(Interface(app, request))

    # read in the XML-RPC request data, limiting to a sensible size
    if int(request.headers['Content-Length']) > 10 * 1024 * 1024:
        raise BadRequest('request data too large')
    xml_request = request.get_data(cache=False, as_text=True)

    # errors here are handled by _marshaled_dispatch
    response = dispatcher._marshaled_dispatch(xml_request)
    # legacy; remove non-printable ASCII control codes from the response
    response = re.sub('([\x00-\x08]|[\x0b-\x0c]|[\x0e-\x1f])+', '', response)

    return Response(response, mimetype="text/xml")
Exemplo n.º 10
0
    def test_csrf_checks_csrf_unsafe(self, method):
        def fn(self, view, app, request, *args, **kwargs):
            return view(app, request, *args, **kwargs)

        view = lambda app, request: Response()
        view._csrf = True
        app = pretend.stub()
        request = pretend.stub(_session={}, method=method)

        _verify_origin = pretend.call_recorder(lambda request: None)
        _verify_token = pretend.call_recorder(lambda request: None)

        handle_csrf(
            fn,
            _verify_origin=_verify_origin,
            _verify_token=_verify_token,
        )(pretend.stub(), view, app, request)

        assert _verify_token.calls == [pretend.call(request)]
        assert _verify_token.calls == [pretend.call(request)]
Exemplo n.º 11
0
def handler(app, request):
    '''Wrap an invocation of the XML-RPC dispatcher.
    '''
    # unicode strings will be encoded in utf-8 by xmlrpclib
    dispatcher = SimpleXMLRPCDispatcher()
    dispatcher.register_instance(Interface(app, request))

    # read in the XML-RPC request data, limiting to a sensible size
    if int(request.headers['Content-Length']) > 10 * 1024 * 1024:
        raise BadRequest('request data too large')
    xml_request = request.get_data(cache=False, as_text=True)

    # errors here are handled by _marshaled_dispatch
    response = dispatcher._marshaled_dispatch(xml_request)

    # legacy; remove non-printable ASCII control codes from the response
    # RJ: disabled this as it's a giant, unreliable hack that doesn't work and
    # I can't even remember why it's in here to start with
    # response = re.sub('([\x00-\x08]|[\x0b-\x0c]|[\x0e-\x1f])+', '', response)

    return Response(response, mimetype="text/xml; charset=utf-8")
Exemplo n.º 12
0
 def view(app, request):
     request._session["wat"] = "ok"
     return Response()
Exemplo n.º 13
0
def package(app, request, path):
    # Get our filename and filepath from the request path
    filename = os.path.basename(path)
    filepath = safe_join(
        os.path.abspath(app.config.paths.packages),
        path
    )

    # If we cannot safely join the requested path with our directory
    #   return a 404
    if filepath is None:
        raise NotFound("{} was not found".format(filename))

    # Open the file and attempt to wrap in the wsgi.file_wrapper if it's
    #   available, otherwise read it directly.
    try:
        fp = open(filepath, "rb")
        data = wrap_file(request.environ, fp)
    except IOError:
        raise NotFound("{} was not found".format(filename))

    # Get the project name and normalize it
    lookup_filename = filename[:-4] if filename.endswith(".asc") else filename
    project = app.db.packaging.get_project_for_filename(lookup_filename)
    normalized = normalize(project)

    # Get the MD5 hash of the file
    content_md5 = app.db.packaging.get_filename_md5(filename)

    headers = {}

    # Add in additional headers if we're using Fastly
    headers.update({
        "Surrogate-Key": " ".join([
            "package",
            "package~{}".format(normalized),
        ]),
    })

    # Look up the last serial for this file
    serial = app.db.packaging.get_last_serial(project)
    if serial is not None:
        headers["X-PyPI-Last-Serial"] = serial

    # Pass through the data directly to the response object
    resp = Response(
        data,
        headers=headers,
        mimetype=get_mimetype(filename),
        direct_passthrough=True,
    )

    # Setup the Last-Modified header
    resp.last_modified = os.path.getmtime(filepath)

    # Setup the Content-Length header
    resp.content_length = os.path.getsize(filepath)

    if content_md5:
        # Setup the Content-MD5 headers
        resp.content_md5 = content_md5

        # Setup Conditional Responses
        resp.set_etag(content_md5)
        resp.make_conditional(request)

    return resp
Exemplo n.º 14
0
def package(app, request, path):
    # Get our filename and filepath from the request path
    filename = os.path.basename(path)
    filepath = safe_join(os.path.abspath(app.config.paths.packages), path)

    # If we cannot safely join the requested path with our directory
    #   return a 404
    if filepath is None:
        raise NotFound("{} was not found".format(filename))

    # Open the file and attempt to wrap in the wsgi.file_wrapper if it's
    #   available, otherwise read it directly.
    try:
        fp = open(filepath, "rb")
        data = wrap_file(request.environ, fp)
    except IOError:
        raise NotFound("{} was not found".format(filename))

    # Get the project name and normalize it
    lookup_filename = filename[:-4] if filename.endswith(".asc") else filename
    project = app.models.packaging.get_project_for_filename(lookup_filename)
    normalized = normalize(project)

    # Get the MD5 hash of the file
    content_md5 = app.models.packaging.get_filename_md5(filename)

    headers = {}

    # Add in additional headers if we're using Fastly
    headers.update({
        "Surrogate-Key":
        " ".join([
            "package",
            "package~{}".format(normalized),
        ]),
    })

    # Look up the last serial for this file
    serial = app.models.packaging.get_last_serial(project)
    if serial is not None:
        headers["X-PyPI-Last-Serial"] = serial

    # Pass through the data directly to the response object
    resp = Response(
        data,
        headers=headers,
        mimetype=get_mimetype(filename),
        direct_passthrough=True,
    )

    # Setup the Last-Modified header
    resp.last_modified = os.path.getmtime(filepath)

    # Setup the Content-Length header
    resp.content_length = os.path.getsize(filepath)

    if content_md5:
        # Setup the Content-MD5 headers
        resp.content_md5 = content_md5

        # Setup Conditional Responses
        resp.set_etag(content_md5)
        resp.make_conditional(request)

    return resp
Exemplo n.º 15
0
def test_csrf_protect():
    view = lambda app, request: Response()
    view = csrf_protect(view)

    assert view._csrf
    assert "cookie" in view(pretend.stub(), pretend.stub()).vary.as_set()
Exemplo n.º 16
0
def test_csrf_exempt():
    view = lambda app, request: Response()
    view = csrf_exempt(view)

    assert not view._csrf
Exemplo n.º 17
0
 def view(app, request):
     request._session.delete()
     return Response()
Exemplo n.º 18
0
 def view(app, request):
     request._session.cycle()
     return Response()
Exemplo n.º 19
0
def daytime(app, request):
    response = time.strftime("%Y%m%dT%H:%M:%S\n", time.gmtime(time.time()))
    return Response(response, mimetype="text/plain")