Example #1
0
File: render.py Project: Tefnet/eve
def _prepare_response(resource, dct, last_modified=None, etag=None, status=200):
    """ Prepares the response object according to the client request and
    available renderers, making sure that all accessory directives (caching,
    etag, last-modified) are present.

    :param resource: the resource involved.
    :param dct: the dict that should be sent back as a response.
    :param last_modified: Last-Modified header value.
    :param etag: ETag header value.
    :param status: response status.

    .. versionchanged:: 0.0.5
       Support for Cross-Origin Resource Sharing (CORS).

    .. versionadded:: 0.0.4
    """
    if request.method == "OPTIONS":
        resp = app.make_default_options_response()
    else:
        # obtain the best match between client's request and available mime
        # types, along with the corresponding render function.
        mime, renderer = _best_mime()

        # invoke the render function and obtain the corresponding rendered item
        rendered = globals()[renderer](**dct)

        # build the main wsgi rensponse object
        resp = make_response(rendered, status)
        resp.mimetype = mime

    # cache directives
    if request.method == "GET":
        if resource:
            cache_control = config.DOMAIN[resource]["cache_control"]
            expires = config.DOMAIN[resource]["cache_expires"]
        else:
            cache_control = config.CACHE_CONTROL
            expires = config.CACHE_EXPIRES
        if cache_control:
            resp.headers.add("Cache-Control", cache_control)
        if expires:
            resp.expires = time.time() + expires

    # etag and last-modified
    if etag:
        resp.headers.add("ETag", etag)
    if last_modified:
        resp.headers.add("Last-Modified", date_to_str(last_modified))

    if "Origin" in request.headers and config.X_DOMAINS is not None:
        if isinstance(config.X_DOMAINS, basestring):
            domains = [config.X_DOMAINS]
        else:
            domains = config.X_DOMAINS
        methods = app.make_default_options_response().headers["allow"]
        resp.headers.add("Access-Control-Allow-Origin", ", ".join(domains))
        resp.headers.add("Access-Control-Allow-Methods", methods)
        resp.headers.add("Access-Control-Allow-Max-Age", 21600)

    return resp
Example #2
0
        def wrapped_function(*args, **kwargs):
            if automatic_options and request.method == 'OPTIONS':
                resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))
            if not attach_to_all and request.method != 'OPTIONS':
                return resp

            h = resp.headers

            # http://www.w3.org/TR/cors/#access-control-allow-origin-response-header
            # If origin header from client is in list of domains allowed,
            # return back to client in Access-Control-Allow-Origin header in
            # response.
            origin_allowed = None
            if request.headers.get('Origin') is None:
                abort(400)
            if origin is None and any(request.headers.get('Origin') in o for o in current_app.config['ORIGINS_ALLOWED']):
                origin_allowed = request.headers.get('Origin')
            elif origin is not None and any(request.headers.get('Origin') in o for o in (current_app.config['ORIGINS_ALLOWED'] + origin)):
                origin_allowed = request.headers.get('Origin')
            else:
                current_app.logger.warn('The remote IP [%s] requested a forbidden resource=[%s]. Returning 403.' % (request.remote_addr, request.url))
                abort(403)

            h['Access-Control-Allow-Credentials'] = 'true'
            h['Access-Control-Allow-Origin'] = origin_allowed
            h['Access-Control-Allow-Methods'] = get_methods()
            h['Access-Control-Max-Age'] = str(max_age)
            if headers is not None:
                h['Access-Control-Allow-Headers'] = headers
            return resp
Example #3
0
    def get_methods():
        """Get methods."""
        if methods is not None:
            return methods

        options_resp = current_app.make_default_options_response()
        return options_resp.headers['allow']
Example #4
0
 def app_before_request():
     # cors response
     if request.method == "OPTIONS":
         resp = current_app.make_default_options_response()
         cors_headers = make_cors_headers()
         resp.headers.extend(cors_headers)
         return resp
Example #5
0
        def wrapped_function(*args, **kwargs):
            # Determine origins when in the context of a request
            origins = _origins or current_app.config.get('CORS_ORIGINS', '*')
            origins_str = str(origins)
            wildcard = origins_str == '*'

            if(not isinstance(origins, string_types)
                    and isinstance(origins, collections.Iterable)):
                origins_str = ', '.join(origins)

            # Determine headers when in the context of the request
            headers = _headers or current_app.config.get('CORS_HEADERS')

            if (not isinstance(headers, string_types)
                    and isinstance(headers, collections.Iterable)):
                headers = ', '.join(x for x in headers)

            # If the Origin header is not present terminate this set of steps.
            # The request is outside the scope of this specification.
            request_origin = request.headers.get('Origin', '')

            if 'Origin' not in request.headers and not always_send:
                return make_response(f(*args, **kwargs))

            # If the value of the Origin header is not a case-sensitive match
            # for any of the values in list of origins, do not set any
            # additional headers and terminate this set of steps.
            elif(not wildcard and not always_send and
                    request_origin not in origins):
                return make_response(f(*args, **kwargs))

            if automatic_options and request.method == 'OPTIONS':
                resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))

            # Add a single Access-Control-Allow-Origin header, with either
            # the value of the Origin header or the string "*" as value.
            if wildcard:
                # If the `origins` param is '*', either send the request's
                # origin, or `*`
                if send_wildcard:
                    resp.headers[ACL_ORIGIN] = origins
                else:
                    req_origin = request.headers.get('Origin', '*')
                    resp.headers[ACL_ORIGIN] = req_origin

            # If not 'wildcard', send the string-joined-form of the
            # origins header
            else:
                resp.headers[ACL_ORIGIN] = origins_str

            resp.headers[ACL_METHODS] = methods
            if max_age:
                resp.headers[ACL_MAX_AGE] = str(max_age)
            if headers is not None:
                resp.headers[ACL_HEADERS] = headers
            if supports_credentials:
                resp.headers[ACL_CREDENTIALS] = 'true'
            return resp
    def wrapped_function(*args, **kwargs):
        if request.method == 'OPTIONS':
            resp = current_app.make_default_options_response()
            resp.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
            resp.headers['Access-Control-Allow-Headers'] = request.environ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
        else:
            if request.data:
                input = json.loads(request.data)
            else:
                input = json.loads('{}')

            print 'Recieved:', input
            result_d = {"error" : False}
            try:
                f(input, result_d)
            except Exception as e:
                print ">> Error >>", e
                result_d["error"] = True
            result = str(json.dumps(result_d))
            print 'Returning:', result
            resp = make_response(result)

        resp.headers['Access-Control-Allow-Origin'] = request.environ.get('HTTP_ORIGIN','*')
        resp.headers['Access-Control-Allow-Cedentials'] = 'true'
        resp.headers['Access-Control-Allow-Max-Age'] = '86400'

        #print resp.response
        #print resp.headers
        return resp
    def get_methods():
        if methods is not None:
            print('got here3')
            return methods

        options_resp = current_app.make_default_options_response()
        return options_resp.headers['allow']
Example #8
0
    def get_methods():
        if methods is not None:
        	return methods

        options_resp = current_app.make_default_options_response()
        options = ', '.join({options_resp.headers['allow'], 'OPTIONS'})
        return options
Example #9
0
        def wrapper(*args, **kwargs):
            default_options_response = current_app.make_default_options_response()

            if not methods:
                # NOTE: default_options_response might not have 'allow' header
                # for example, when there is an error handler on the application level (not on blueprint).
                allowed_methods = default_options_response.headers['allow'].split(', ')
            else:
                allowed_methods = ', '.join(sorted(method.upper() for method in methods))

            if not headers:
                allowed_headers = 'Accept, Accept-Language, Content-Language, Content-Type'
            else:
                allowed_headers = ', '.join(headers)

            crossdomain_headers = {
                'Access-Control-Allow-Origin': origin,
                'Access-Control-Allow-Methods': allowed_methods,
                'Access-Control-Allow-Headers': allowed_headers
            }

            if request.method == 'OPTIONS':
                default_options_response.headers.extend(crossdomain_headers)
                return default_options_response

            # NOTE: func might raise an exception (i.e BadRequest), currently this error is not catched so
            # execution stops here before headers are set for CORS.
            crossdomain_response = func(*args, **kwargs)
            crossdomain_response.headers.extend(crossdomain_headers)

            return crossdomain_response
Example #10
0
        def wrapped_function(*args, **kwargs):
            # Get a hold of the request origin
            origin = request.environ.get('HTTP_ORIGIN')
            if automatic_options and request.method == 'OPTIONS':
                resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))
            if not attach_to_all and request.method != 'OPTIONS':
                return resp

            h = resp.headers

            # if the origin matches any of our allowed origins set the
            # access control header appropriately
            allow_origin = (origin if origin is not None and
                                      allowed_origins is not None and
                                      origin in allowed_origins else None)
            h['Access-Control-Allow-Origin'] = allow_origin
            h['Access-Control-Allow-Methods'] = get_methods()
            h['Access-Control-Max-Age'] = str(max_age)
            if credentials:
                h['Access-Control-Allow-Credentials'] = 'true'
            if headers is not None:
                h['Access-Control-Allow-Headers'] = headers
            return resp
Example #11
0
        def wrapped_function(*args, **kwargs):
            if not 'Origin' in request.headers and not always_send:
                return make_response(f(*args, **kwargs))

            elif not wildcard and not always_send and not request.headers.get('Origin', '') in origins:
                return make_response(f(*args, **kwargs))

            if request.method == 'OPTIONS':
                resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))

            h = resp.headers

            if wildcard:
                if send_wildcard:
                    h[AccessControlAllowOrigin] = origins
                else:
                    h[AccessControlAllowOrigin] = request.headers.get('Origin', '*')
            else:
                h[AccessControlAllowOrigin] = request.headers.get('Origin')


            h['Access-Control-Allow-Methods'] = methods
            if max_age:
                h['Access-Control-Max-Age'] = str(max_age)
            if headers is not None:
                h['Access-Control-Allow-Headers'] = headers
            return resp
Example #12
0
 def inner(*args, **kwargs):
     if request.method=='OPTIONS':
         resp=current_app.make_default_options_response()
     else:
         resp=fn(*args,**kwargs)
         resp=make_response(resp)
     return add_cors_headers(resp)
Example #13
0
    def get_methods():
        if methods is not None:
            return methods

        # if not provided, make the default response options, which will allow all methods that are implemented.
        options_resp = current_app.make_default_options_response()
        return options_resp.headers['allow']
Example #14
0
File: pyco.py Project: Soopro/pyco
def app_before_request():
    # cors response
    if request.method == 'OPTIONS':
        resp = current_app.make_default_options_response()
        cors_headers = make_cors_headers()
        resp.headers.extend(cors_headers)
        return resp
    elif request.path.strip('/') in SYS_ICON_LIST:
        return make_response('', 204)  # for browser default icons

    if request.endpoint == 'uploads.get_uploads':
        return

    base_url = current_app.config.get('BASE_URL')
    uploads_url = current_app.config.get('UPLOADS_URL')

    if app.debug or not MEM['loaded']:
        MEM['curr_app'] = load_curr_app(current_app)
        MEM['files'] = load_all_files(current_app, MEM['curr_app'])
        MEM['loaded'] = True

    g.curr_app = MEM['curr_app']
    g.files = MEM['files']

    g.request_remote_addr = get_remote_addr()
    g.request_path = request.path

    g.curr_base_url = base_url
    g.uploads_url = uploads_url
    g.request_url = get_request_url(g.curr_base_url, g.request_path)

    g.query_map = {}
Example #15
0
    def decorated(*args, **kwargs):
        if request.method == 'OPTIONS':
            resp = app.make_default_options_response()
        else:
            resp = make_response(f(*args, **kwargs))

        # CORS
        domains = app.config.get('X_DOMAINS')
        headers = app.config.get('X_HEADERS')
        max_age = app.config.get('X_MAX_AGE')
        allow_credentials = app.config.get('X_ALLOW_CREDENTIALS')
        expose_headers = app.config.get('X_EXPOSE_HEADERS')
        origin = request.headers.get('Origin')
        if origin and domains:
            if isinstance(domains, str):
                domains = [domains]

            if headers is None:
                headers = []
            elif isinstance(headers, str):
                headers = [headers]

            if expose_headers is None:
                expose_headers = []
            elif isinstance(expose_headers, str):
                expose_headers = [expose_headers]

            allow_credentials = allow_credentials is True
            methods = app.make_default_options_response().headers.get(
                'allow', '')

            h = resp.headers
            if '*' in domains:
                h['Access-Control-Allow-Origin'] = origin
                h['Vary'] = 'Origin'
            elif any(re.match(re.escape(domain), origin)
                     for domain in domains):
                h['Access-Control-Allow-Origin'] = origin
            else:
                h['Access-Control-Allow-Origin'] = ''

            h['Access-Control-Allow-Headers'] = ', '.join(headers)
            h['Access-Control-Expose-Headers'] = ', '.join(expose_headers)
            h['Access-Control-Allow-Methods'] = methods
            h['Access-Control-Max-Age'] = str(max_age)

        return resp
Example #16
0
def crossdomain(origin=None,
                methods=None,
                headers=None,
                max_age=21600,
                attach_to_all=True,
                automatic_options=True):
    """

    :param origin: '*' to allow all origins, otherwise a string with a URL
            or a list of URLs that might access the resource.
    :param methods: Optionally a list of methods that are allowed for this
            view. If not provided it will allow all methods that are implemented
    :param headers: Optionally a list of headers that are allowed for this request.
    :param max_age: The number of seconds as integer or timedelta object
            for which the preflighted request is valid.
    :param attach_to_all: True if the decorator should add the access control
            headers to all HTTP methods or False if it should only add them to
            OPTIONS responses.
    :param automatic_options: If enabled the decorator will use the default
            Flask OPTIONS response and attach the headers there,
            otherwise the view
    :return:

    http://flask.pocoo.org/snippets/56/
    """
    if methods is not None:
        methods = ', '.join(sorted(x.upper() for x in methods))
    else:
        options_resp = current_app.make_default_options_response()
        methods = options_resp.headers['allow']

    if headers is not None and not isinstance(headers, basestring):
        headers = ', '.join(x.upper() for x in headers)
    if not isinstance(origin, basestring):
        origin = ', '.join(origin)
    if isinstance(max_age, timedelta):
        max_age = max_age.total_seconds()

    def decorator(f):
        def wrapped_function(*args, **kwargs):
            if automatic_options and request.method == 'OPTIONS':
                resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))
            if not attach_to_all and request.method != 'OPTIONS':
                return resp

            h = resp.headers

            h['Access-Control-Allow-Origin'] = origin
            h['Access-Control-Allow-Methods'] = methods
            h['Access-Control-Max-Age'] = str(max_age)
            if headers is not None:
                h['Access-Control-Allow-Headers'] = headers
            return resp

        f.provide_automatic_options = False
        return update_wrapper(wrapped_function, f)
    return decorator
Example #17
0
File: cd.py Project: kennyce/app
		def wrapped_function(*args, **kwargs):
			if automatic_options and request.method == 'OPTIONS':
				resp = current_app.make_default_options_response()
			else:
				resp = make_response(f(*args, **kwargs))
				
			if not attach_to_all and request.method != 'OPTIONS':
				return resp
    def get_methods():
        """ Determines which methods are allowed
        """
        if methods is not None:
            return methods

        options_resp = current_app.make_default_options_response()
        return options_resp.headers['allow']
Example #19
0
    def get_methods():
        '''
         utils method for obtaining methods
        '''
        if methods is not None:
            return methods

        options_resp = current_app.make_default_options_response()
        return options_resp.headers['allow']
Example #20
0
	def get_methods():

		# if we have specified methods, return the list
		if methods is not None:
			return methods

		# return default OPTIONS response
		options_resp = current_app.make_default_options_response()
		return options_resp.headers['allow']
Example #21
0
def summarize():
	print 'printed'
	resp = current_app.make_default_options_response()
	h = resp.headers
	h['Access-Control-Allow-Origin'] = '*'
	#print request.form['aDoc']
	#myValues = request.get_json(force=True)
	#print myValues
	resp.data= theLSA.sumDoc(request.form['aDoc'])
	return resp
Example #22
0
File: flask.py Project: 20c/vodka
 def wrapped_function(*args, **kwargs):
     if request.method == 'OPTIONS':
         resp = current_app.make_default_options_response()
     else:
         resp = make_response(f(*args, **kwargs))
     h = resp.headers
     h['Access-Control-Allow-Origin'] = origin
     h['Access-Control-Allow-Methods'] = get_methods()
     if headers is not None:
         h['Access-Control-Allow-Headers'] = headers
     return resp
Example #23
0
def before_request():
    if request.method == 'OPTIONS':
        resp = current_app.make_default_options_response()
        h = resp.headers
        if 'ACCESS_CONTROL_REQUEST_HEADERS' in request.headers:
            h['Access-Control-Allow-Headers'] = request.headers['ACCESS_CONTROL_REQUEST_HEADERS']

        h['Access-Control-Allow-Origin'] = "*"
        h['Access-Control-Allow-Methods'] = request.headers['Access-Control-Request-Method']

        return resp
Example #24
0
 def app_before_request():
     if request.method == "OPTIONS":
         resp = current_app.make_default_options_response()
         cors_headers = {
             "Access-Control-Allow-Headers": "Origin, Accept, Content-Type, Authorization",
             "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS, HEAD",
             "Access-Control-Allow-Origin": "*"
         }
         resp.headers.extend(cors_headers)
         return resp
     return
	def decorated_function(*args, **kwargs):
		if True and request.method == 'OPTIONS':
			resp = current_app.make_default_options_response()
		else:
			resp = make_response(f(*args, **kwargs))
		if not True and request.method != 'OPTIONS':
			return resp

		h = resp.headers
		h['Content-Type'] = "application/json"
		return resp
Example #26
0
  def allowALLTheThings(response):
    this = current_app.make_default_options_response()
    allowed = this.headers['allow']
    headers = request.headers.get('Access-Control-Request-Headers', '*')

    response.headers.add('Access-Control-Allow-Origin', '*')
    response.headers.add('Access-Control-Allow-Headers', headers)
    response.headers.add('Access-Control-Allow-Methods', allowed)
    response.headers.add('Access-Control-Allow-Credentials', 'true')

    return response
Example #27
0
    def get_methods():
        if methods is not None:
            return methods

        options_resp = current_app.make_default_options_response()

        try:
            return options_resp.headers["Allow"]
        except:
            # This might not be present on all requests. Let is 404 instead of 500.
            pass
Example #28
0
        def wrapped_function(*args, **kwargs):
            # Handle setting of Flask-Cors parameters
            options = get_cors_options(current_app, _options)

            if options.get('automatic_options') and request.method == 'OPTIONS':
                resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))

            set_cors_headers(resp, options)
            setattr(resp, FLASK_CORS_EVALUATED, True)
            return resp
Example #29
0
 def wrapped_function(*args, **kwargs):
     if automatic_options and request.method == 'OPTIONS':
         resp = current_app.make_default_options_response()
     else:
         resp = make_response( f( *args, **kwargs ) )
     if not attach_to_all and request.method != 'OPTIONS':
         return resp
     h = resp.headers
     h['Access-Control-Allow-Origin'] = origin
     h['Access-Control-Allow-Methods'] = get_methods()
     h['Access-Control-Max-Age'] = str( max_age )
     if headers is not None:
         h['Access-Control-Allow-Headers'] = headers
     return resp
Example #30
0
        def wrapped_function(*args, **kwargs):
            if automatic_options and request.method == 'OPTIONS':
                resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))
            if not attach_to_all and request.method != 'OPTIONS':
                return resp

            h = resp.headers
            h['Access-Control-Allow-Origin'] = origin
            h['Access-Control-Allow-Methods'] = get_methods()
            h['Access-Control-Max-Age'] = str(max_age)
            h['Access-Control-Allow-Headers'] = "Origin, X-Requested-With, Content-Type, Accept, Authorization "
            h['Access-Control-Allow-Credentials'] = 'true'
            return resp
    def get_methods():
        if methods is not None:
            return ', '.join(sorted(x.upper() for x in methods))

        options_resp = current_app.make_default_options_response()
        return options_resp.headers['allow']
Example #32
0
 def options(self):
     """ Allow CORS for specific origins
     """
     resp = current_app.make_default_options_response()
     return add_cors_headers(response)
Example #33
0
def make_decision_options():
    """ Handles the OPTIONS requests to the /decision endpoint. """
    resp = current_app.make_default_options_response()
    return insert_headers(resp)
Example #34
0
 def get_methods():
     if methods is not None:
         return methods
     options_resp = current_app.make_default_options_response()
     return options_resp.headers['allow']
Example #35
0
 def before_request():
     if request.method == 'OPTIONS':
         response = current_app.make_default_options_response()
         response = prepare_headers(response)
         response.headers['Access-Control-Allow-Headers'] = 'content-type, authorization, if-match'
         return response
Example #36
0
def _prepare_response(resource, dct, last_modified=None, etag=None,
                      status=200):
    """ Prepares the response object according to the client request and
    available renderers, making sure that all accessory directives (caching,
    etag, last-modified) are present.

    :param resource: the resource involved.
    :param dct: the dict that should be sent back as a response.
    :param last_modified: Last-Modified header value.
    :param etag: ETag header value.
    :param status: response status.

    .. versionchanged:: 0.0.9
       Support for Python 3.3.

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.6
       Support for HEAD requests.

    .. versionchanged:: 0.0.5
       Support for Cross-Origin Resource Sharing (CORS).

    .. versionadded:: 0.0.4
    """
    if request.method == 'OPTIONS':
        resp = app.make_default_options_response()
    else:
        # obtain the best match between client's request and available mime
        # types, along with the corresponding render function.
        mime, renderer = _best_mime()

        # invoke the render function and obtain the corresponding rendered item
        rendered = globals()[renderer](**dct)

        # build the main wsgi rensponse object
        resp = make_response(rendered, status)
        resp.mimetype = mime

    # cache directives
    if request.method in ('GET', 'HEAD'):
        if resource:
            cache_control = config.DOMAIN[resource]['cache_control']
            expires = config.DOMAIN[resource]['cache_expires']
        else:
            cache_control = config.CACHE_CONTROL
            expires = config.CACHE_EXPIRES
        if cache_control:
            resp.headers.add('Cache-Control', cache_control)
        if expires:
            resp.expires = time.time() + expires

    # etag and last-modified
    if etag:
        resp.headers.add('ETag', etag)
    if last_modified:
        resp.headers.add('Last-Modified', date_to_str(last_modified))

    # CORS
    if 'Origin' in request.headers and config.X_DOMAINS is not None:
        if isinstance(config.X_DOMAINS, str):
            domains = [config.X_DOMAINS]
        else:
            domains = config.X_DOMAINS

        if config.X_HEADERS is None:
            headers = []
        elif isinstance(config.X_HEADERS, str):
            headers = [config.X_HEADERS]
        else:
            headers = config.X_HEADERS

        methods = app.make_default_options_response().headers['allow']
        resp.headers.add('Access-Control-Allow-Origin', ', '.join(domains))
        resp.headers.add('Access-Control-Allow-Headers', ', '.join(headers))
        resp.headers.add('Access-Control-Allow-Methods', methods)
        resp.headers.add('Access-Control-Allow-Max-Age', 21600)

    # Rate-Limiting
    limit = get_rate_limit()
    if limit and limit.send_x_headers:
        resp.headers.add('X-RateLimit-Remaining', str(limit.remaining))
        resp.headers.add('X-RateLimit-Limit', str(limit.limit))
        resp.headers.add('X-RateLimit-Reset', str(limit.reset))

    return resp
Example #37
0
def options_response():
    if request.method == 'OPTIONS':
        logger.debug('responding to OPTIONS request')
        resp = current_app.make_default_options_response()
        return resp
Example #38
0
def upload_options():
    print "OPTIONS CALL"
    return current_app.make_default_options_response()
Example #39
0
def _prepare_response(resource,
                      dct,
                      last_modified=None,
                      etag=None,
                      status=200,
                      headers=None):
    """ Prepares the response object according to the client request and
    available renderers, making sure that all accessory directives (caching,
    etag, last-modified) are present.

    :param resource: the resource involved.
    :param dct: the dict that should be sent back as a response.
    :param last_modified: Last-Modified header value.
    :param etag: ETag header value.
    :param status: response status.

    .. versionchanged:: 0.7
       Add support for regexes in X_DOMAINS values. Closes #660.
       ETag value now surrounded by double quotes. Closes #794.

    .. versionchanged:: 0.6
       JSONP Support.

    .. versionchanged:: 0.4
       Support for optional extra headers.
       Fix #381. 500 instead of 404 if CORS is enabled.

    .. versionchanged:: 0.3
       Support for X_MAX_AGE.

    .. versionchanged:: 0.1.0
       Support for optional HATEOAS.

    .. versionchanged:: 0.0.9
       Support for Python 3.3.

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.6
       Support for HEAD requests.

    .. versionchanged:: 0.0.5
       Support for Cross-Origin Resource Sharing (CORS).

    .. versionadded:: 0.0.4
    """
    if request.method == 'OPTIONS':
        resp = app.make_default_options_response()
    else:
        # obtain the best match between client's request and available mime
        # types, along with the corresponding render function.
        mime, renderer = _best_mime()

        # invoke the render function and obtain the corresponding rendered item
        rendered = globals()[renderer](dct)

        # JSONP
        if config.JSONP_ARGUMENT:
            jsonp_arg = config.JSONP_ARGUMENT
            if jsonp_arg in request.args and 'json' in mime:
                callback = request.args.get(jsonp_arg)
                rendered = "%s(%s)" % (callback, rendered)

        # build the main wsgi rensponse object
        resp = make_response(rendered, status)
        resp.mimetype = mime

    # extra headers
    if headers:
        for header, value in headers:
            if header != 'Content-Type':
                resp.headers.add(header, value)

    # cache directives
    if request.method in ('GET', 'HEAD'):
        if resource:
            cache_control = config.DOMAIN[resource]['cache_control']
            expires = config.DOMAIN[resource]['cache_expires']
        else:
            cache_control = config.CACHE_CONTROL
            expires = config.CACHE_EXPIRES
        if cache_control:
            resp.headers.add('Cache-Control', cache_control)
        if expires:
            resp.expires = time.time() + expires

    # etag and last-modified
    if etag:
        resp.headers.add('ETag', '"' + etag + '"')
    if last_modified:
        resp.headers.add('Last-Modified', date_to_rfc1123(last_modified))

    # CORS
    origin = request.headers.get('Origin')
    if origin and config.X_DOMAINS:
        if isinstance(config.X_DOMAINS, str):
            domains = [config.X_DOMAINS]
        else:
            domains = config.X_DOMAINS

        if config.X_HEADERS is None:
            headers = []
        elif isinstance(config.X_HEADERS, str):
            headers = [config.X_HEADERS]
        else:
            headers = config.X_HEADERS

        if config.X_EXPOSE_HEADERS is None:
            expose_headers = []
        elif isinstance(config.X_EXPOSE_HEADERS, str):
            expose_headers = [config.X_EXPOSE_HEADERS]
        else:
            expose_headers = config.X_EXPOSE_HEADERS

        # The only accepted value for Access-Control-Allow-Credentials header
        # is "true"
        allow_credentials = config.X_ALLOW_CREDENTIALS is True

        methods = app.make_default_options_response().headers.get('allow', '')

        if '*' in domains:
            resp.headers.add('Access-Control-Allow-Origin', origin)
            resp.headers.add('Vary', 'Origin')
        elif any(re.match(re.escape(domain), origin) for domain in domains):
            resp.headers.add('Access-Control-Allow-Origin', origin)
        else:
            resp.headers.add('Access-Control-Allow-Origin', '')
        resp.headers.add('Access-Control-Allow-Headers', ', '.join(headers))
        resp.headers.add('Access-Control-Expose-Headers',
                         ', '.join(expose_headers))
        resp.headers.add('Access-Control-Allow-Methods', methods)
        resp.headers.add('Access-Control-Max-Age', config.X_MAX_AGE)
        if allow_credentials:
            resp.headers.add('Access-Control-Allow-Credentials', "true")

    # Rate-Limiting
    limit = get_rate_limit()
    if limit and limit.send_x_headers:
        resp.headers.add('X-RateLimit-Remaining', str(limit.remaining))
        resp.headers.add('X-RateLimit-Limit', str(limit.limit))
        resp.headers.add('X-RateLimit-Reset', str(limit.reset))

    return resp
Example #40
0
 def get_methods():
     resp = current_app.make_default_options_response()
     return resp.headers["allow"]
Example #41
0
 def options(self, *args, **kwargs):
     '''
     Restangular, and angular.js need an OPTIONS method
     '''
     resp = current_app.make_default_options_response()
     return {}, resp.status, resp.headers
Example #42
0
def _prepare_response(resource,
                      dct,
                      last_modified=None,
                      etag=None,
                      status=200,
                      headers=None):
    """ Prepares the response object according to the client request and
    available renderers, making sure that all accessory directives (caching,
    etag, last-modified) are present.

    :param resource: the resource involved.
    :param dct: the dict that should be sent back as a response.
    :param last_modified: Last-Modified header value.
    :param etag: ETag header value.
    :param status: response status.

    .. versionchanged:: 0.7
       Add support for regexes in X_DOMAINS_RE. Closes #660, #974.
       ETag value now surrounded by double quotes. Closes #794.

    .. versionchanged:: 0.6
       JSONP Support.

    .. versionchanged:: 0.4
       Support for optional extra headers.
       Fix #381. 500 instead of 404 if CORS is enabled.

    .. versionchanged:: 0.3
       Support for X_MAX_AGE.

    .. versionchanged:: 0.1.0
       Support for optional HATEOAS.

    .. versionchanged:: 0.0.9
       Support for Python 3.3.

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.6
       Support for HEAD requests.

    .. versionchanged:: 0.0.5
       Support for Cross-Origin Resource Sharing (CORS).

    .. versionadded:: 0.0.4
    """
    if request.method == "OPTIONS":
        resp = app.make_default_options_response()
    else:
        # obtain the best match between client's request and available mime
        # types, along with the corresponding render function.
        mime, renderer_cls = _best_mime()

        # invoke the render function and obtain the corresponding rendered item
        rendered = renderer_cls().render(dct)

        # JSONP
        if config.JSONP_ARGUMENT:
            jsonp_arg = config.JSONP_ARGUMENT
            if jsonp_arg in request.args and "json" in mime:
                callback = request.args.get(jsonp_arg)
                rendered = "%s(%s)" % (callback, rendered)

        # build the main wsgi response object
        resp = make_response(rendered, status)
        resp.mimetype = mime

    # extra headers
    if headers:
        for header, value in headers:
            if header != "Content-Type":
                resp.headers.add(header, value)

    # cache directives
    if request.method in ("GET", "HEAD"):
        if resource:
            cache_control = config.DOMAIN[resource]["cache_control"]
            expires = config.DOMAIN[resource]["cache_expires"]
        else:
            cache_control = config.CACHE_CONTROL
            expires = config.CACHE_EXPIRES
        if cache_control:
            resp.headers.add("Cache-Control", cache_control)
        if expires:
            resp.expires = time.time() + expires

    # etag and last-modified
    if etag:
        resp.headers.add("ETag", '"' + etag + '"')
    if last_modified:
        resp.headers.add("Last-Modified", date_to_rfc1123(last_modified))

    # CORS
    origin = request.headers.get("Origin")
    if origin and (config.X_DOMAINS or config.X_DOMAINS_RE):
        if config.X_DOMAINS is None:
            domains = []
        elif isinstance(config.X_DOMAINS, str):
            domains = [config.X_DOMAINS]
        else:
            domains = config.X_DOMAINS

        if config.X_DOMAINS_RE is None:
            domains_re = []
        elif isinstance(config.X_DOMAINS_RE, str):
            domains_re = [config.X_DOMAINS_RE]
        else:
            domains_re = config.X_DOMAINS_RE

        # precompile regexes and ignore invalids
        domains_re_compiled = []
        for domain_re in domains_re:
            try:
                domains_re_compiled.append(re.compile(domain_re))
            except re.error:
                continue

        if config.X_HEADERS is None:
            headers = []
        elif isinstance(config.X_HEADERS, str):
            headers = [config.X_HEADERS]
        else:
            headers = config.X_HEADERS

        if config.X_EXPOSE_HEADERS is None:
            expose_headers = []
        elif isinstance(config.X_EXPOSE_HEADERS, str):
            expose_headers = [config.X_EXPOSE_HEADERS]
        else:
            expose_headers = config.X_EXPOSE_HEADERS

        # The only accepted value for Access-Control-Allow-Credentials header
        # is "true"
        allow_credentials = config.X_ALLOW_CREDENTIALS is True

        methods = app.make_default_options_response().headers.get("allow", "")

        if "*" in domains:
            resp.headers.add("Access-Control-Allow-Origin", origin)
            resp.headers.add("Vary", "Origin")
        elif any(origin == domain for domain in domains):
            resp.headers.add("Access-Control-Allow-Origin", origin)
        elif any(domain.match(origin) for domain in domains_re_compiled):
            resp.headers.add("Access-Control-Allow-Origin", origin)
        else:
            resp.headers.add("Access-Control-Allow-Origin", "")
        resp.headers.add("Access-Control-Allow-Headers", ", ".join(headers))
        resp.headers.add("Access-Control-Expose-Headers",
                         ", ".join(expose_headers))
        resp.headers.add("Access-Control-Allow-Methods", methods)
        resp.headers.add("Access-Control-Max-Age", config.X_MAX_AGE)
        if allow_credentials:
            resp.headers.add("Access-Control-Allow-Credentials", "true")

    # Rate-Limiting
    limit = get_rate_limit()
    if limit and limit.send_x_headers:
        resp.headers.add("X-RateLimit-Remaining", str(limit.remaining))
        resp.headers.add("X-RateLimit-Limit", str(limit.limit))
        resp.headers.add("X-RateLimit-Reset", str(limit.reset))

    return resp
Example #43
0
def handle_preflight():
    return current_app.make_default_options_response()