Ejemplo n.º 1
0
def proxy(request):
    """Pass an HTTP request on to another server."""

    # TODO: don't hardcode http
    uri = "http://" + HOST + request.META['PATH_INFO']
    if request.META['QUERY_STRING']:
        uri += '?' + request.META['QUERY_STRING']

    headers = {}
    for name, val in six.iteritems(request.environ):
        if name.startswith('HTTP_'):
            name = header_name(name)
            headers[name] = val

    # TODO: try/except
    http = Http()
    http.follow_redirects = False
    logger.debug("GET for: %s" % uri)
    info, content = http.request(uri, 'GET', headers=headers)
    response = HttpResponse(content, status=info.pop('status'))

    for name, val in info.items():
        if not is_hop_by_hop(name):
            response[name] = val
    logger.info("PROXY to: %s" % uri)
    return response
Ejemplo n.º 2
0
def proxy(request, path, plname=None, headers=None):
    """ handle revproxy """
    headers = headers or {}
    for key, value in request.META.iteritems():
        if key.startswith('HTTP_'):
            key = header_name(key)
            
        elif key in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
            key = key.replace('_', '-')
            if not value: continue
        else:
            continue
        
        # rewrite location
        if key.lower() == "host":
            continue
        if is_hop_by_hop(key):
            continue
        else:
            headers[key] = value
    
    headers["X-Forwarded-For"] = request.META.get("REMOTE_ADDR")
    headers["X-Forwarded-Host"] = request.get_host()
    headers["PATH-INFO"] = request.get_full_path()
    if hasattr(request, 'user') and request.user.is_authenticated():
            headers.update({
                'X-AIMPL-User': request.user.username,
                'X-AIMPL-Priv': is_priv(request, plname),
                'X-AIMPL-User-PL': ','.join([p.name for p in privileges(request)]),
                'X-AIMPL-Groups': ','.join(str(g) \
                            for g in request.user.groups.all() \
                            if has_group(request, str(g), plname) \
                            or str(g) == "Chief Editor"),
                'X-AIMPL-Token': hmac.new(settings.SECRET_KEY, 
                            request.user.username, hashlib.sha1).hexdigest()
            })
    
    uri = "http://%s:%s%s" % (settings.WEB_PROXY_DOMAIN, 
                            settings.WEB_PROXY_PORT, path)
                            
   
    # Django's internal mechanism doesn't pick up
    # PUT request, so we trick it a little here.
    if request.method.upper() == "PUT":
        coerce_put_post(request)
    try:
        resp = connection.request(uri, method=request.method, 
                            body=request.raw_post_data,
                            headers=headers)
        body = resp.body_file
    except restkit.RequestFailed, e:
        msg = getattr(e, 'msg', '')
        
        if e.status_int >= 100:
            resp = e.response
            body = msg
        else:
            return http.HttpResponseBadRequest(msg)
Ejemplo n.º 3
0
    def process_request(self, request):
        """This is called every time a new request arrives in Django, but *before* the url resolution is
        made. 
        If this returns an HttpResponse -> nothing else is made by django and the HttpResponse is sent to client
        If this returns None -> the request is passed along to the url resolver for "normal" handling by Django """

        if request.META['QUERY_STRING']:
            querystring = request.META['PATH_INFO'] + '?' + request.META[
                'QUERY_STRING']
        else:
            querystring = request.META['PATH_INFO']
        server_protocol = request.META['SERVER_PROTOCOL']

        outgoing_headers = {}
        data = []
        data.append(' '.join([request.method, querystring,
                              server_protocol]))  #
        for a, b in request.environ.iteritems():
            if a.startswith('HTTP_'):
                a = header_name(a)
                outgoing_headers[a] = b
                data.append('%s %s' % (a, b))
        data = '\r\n'.join(data) + '\r\n\r\n'

        # Instead of using sockets I now use urllib2, so that DNS "beautifying" is properly done.

        requ = urllib2.Request(querystring, None, outgoing_headers)

        remote = urllib2.urlopen(requ)

        status_code = remote.getcode()
        headers = remote.headers  # This is a dict
        content = remote.read()

        # We should have all we need now.
        # I cleaned up the part with the sockets - it's much cleaner now.

        response = HttpResponse(content, status=int(status_code))
        for header in headers.keys():
            # We need to check if the header we forward is allowed (if it's not a hop by hop header)
            if not basehttp.is_hop_by_hop(header):
                response[header] = headers[header]

        return response
Ejemplo n.º 4
0
    def process_request(self, request):
        """This is called every time a new request arrives in Django, but *before* the url resolution is
        made. 
        If this returns an HttpResponse -> nothing else is made by django and the HttpResponse is sent to client
        If this returns None -> the request is passed along to the url resolver for "normal" handling by Django """
        
        if request.META['QUERY_STRING']:
            querystring = request.META['PATH_INFO'] + '?' + request.META['QUERY_STRING']
        else:
            querystring = request.META['PATH_INFO']
        server_protocol = request.META['SERVER_PROTOCOL']
    
        outgoing_headers = {}
        data = []
        data.append(' '.join([request.method, querystring, server_protocol]))#
        for a, b in request.environ.iteritems():
            if a.startswith('HTTP_'):
                a = header_name(a)
                outgoing_headers[a] = b
                data.append('%s %s' % (a, b))
        data = '\r\n'.join(data) + '\r\n\r\n'
    
        # Instead of using sockets I now use urllib2, so that DNS "beautifying" is properly done.
        
        requ = urllib2.Request(querystring, None, outgoing_headers)
        
        remote = urllib2.urlopen(requ)
        
        status_code = remote.getcode()
        headers = remote.headers # This is a dict
        content = remote.read()
        
        # We should have all we need now.
        # I cleaned up the part with the sockets - it's much cleaner now.

        response = HttpResponse(content, status=int(status_code))
        for header in headers.keys():
            # We need to check if the header we forward is allowed (if it's not a hop by hop header)
            if not basehttp.is_hop_by_hop(header):
                response[header] = headers[header]

        return response
Ejemplo n.º 5
0
def proxy(request):

    # TODO: don't hardcode http
    uri = "http://" + HOST + request.META['PATH_INFO']
    if request.META['QUERY_STRING']:
        uri += '?' + request.META['QUERY_STRING']

    headers = {}
    for name, val in request.environ.iteritems():
        if name.startswith('HTTP_'):
            name = header_name(name)
            headers[name] = val

    # TODO: try/except
    http = Http()
    http.follow_redirects = False
    info, content = http.request(uri, 'GET', headers=headers)
    response = HttpResponse(content, status=info.pop('status'))

    for name, val in info.items():
        if not is_hop_by_hop(name):
            response[name] = val

    return response
Ejemplo n.º 6
0
def forward_header(k):
    return k.upper() not in ['HOST', 'CONTENT_LENGTH'] and \
        not is_hop_by_hop(k) and not '.' in k
Ejemplo n.º 7
0
def proxy_request(request, **kwargs):
    """ generic view to proxy a request.

    Args:

        destination: string, the proxied url
        prefix: string, the prrefix behind we proxy the path
        headers: dict, custom HTTP headers
        no_redirect: boolean, False by default, do not redirect to "/" 
            if no path is given
        decompress: boolean, False by default. If true the proxy will
            decompress the source body if it's gzip encoded.
        filters: list of revproxy.Filter instance

    Return:

        HttpResponse instance
    """

    # proxy sid
    try:
        cookie_name = settings.REVPROXY_COOKIE
    except AttributeError:
        cookie_name = kwargs.get("cookie", "PROXY_SID")

    sid = request.COOKIES.get(cookie_name)

    # create a proxy session id only if it's needed so someone using
    # a cookie based authentification can just reuse this session id.
    # It can also be the session id from the session middleware.
    if not sid:
        sid = uuid.uuid4().hex
    kwargs['proxy_sid'] = sid

    # install request filters
    filters_classes = kwargs.get('filters')
    if not filters_classes:
        filters = None
    else:
        filters = []
        for fclass in filters_classes:
            # add filter instance
            fobj = fclass(request, **kwargs)
            filters.append(fobj)

            # eventually rewrite request and kwargs
            if hasattr(fobj, 'setup'):
                ret = fobj.setup()
                if ret is not None:
                    try:
                        request, extra_kwargs = ret
                    except ValueError:
                        extra_kwargs = ret

                    if extra_kwargs is not None:
                        kwargs.update(extra_kwargs)

    destination = kwargs.get('destination')
    prefix = kwargs.get('prefix')
    headers = kwargs.get('headers')
    no_redirect = kwargs.get('no_redirect', False)
    decompress = kwargs.get("decompress", False)
    path = kwargs.get("path")
    proxy_sid = kwargs.get('proxy_sid')

    if path is None:
        path = request.path
        if prefix is not None and prefix:
            path = path.split(prefix, 1)[1]
    else:
        if not path and not request.path.endswith("/"):
            if not no_redirect:
                qs = request.META["QUERY_STRING"]
                redirect_url = "%s/" % request.path
                if qs:
                    redirect_url = "%s?%s" % (redirect_url, qs)
                return HttpResponsePermanentRedirect(redirect_url)

        if path:
            prefix = request.path.rsplit(path, 1)[0]

    if not path.startswith("/"):
        path = "/%s" % path

    base_url = absolute_uri(request, destination)
    proxied_url = ""
    if not path:
        proxied_url = "%s/" % base_url
    else:
        proxied_url = "%s%s" % (base_url, path)

    qs = request.META.get("QUERY_STRING")
    if qs is not None and qs:
        proxied_url = "%s?%s" % (proxied_url, qs)

    # fix headers@
    headers = headers or {}
    for key, value in request.META.iteritems():
        if key.startswith('HTTP_'):
            key = header_name(key)

        elif key in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
            key = key.replace('_', '-')
            if not value: continue
        else:
            continue

        # rewrite location
        if key.lower() != "host" and not is_hop_by_hop(key):
            headers[key] = value

    # we forward for
    headers["X-Forwarded-For"] = request.get_host()

    # django doesn't understand PUT sadly
    method = request.method.upper()
    if method == "PUT":
        coerce_put_post(request)

    # do the request
    try:
        resp = restkit.request(proxied_url,
                               method=method,
                               body=request.raw_post_data,
                               headers=headers,
                               follow_redirect=True,
                               decompress=decompress,
                               filters=filters)
    except restkit.RequestFailed, e:
        msg = getattr(e, 'msg', '')

        if e.status_int >= 100:
            resp = e.response
            body = msg
        else:
            return http.HttpResponseBadRequest(msg)
Ejemplo n.º 8
0
    except restkit.RequestFailed, e:
        msg = getattr(e, 'msg', '')

        if e.status_int >= 100:
            resp = e.response
            body = msg
        else:
            return http.HttpResponseBadRequest(msg)

    body = resp.tee()
    response = HttpResponse(body, status=resp.status_int)

    # fix response headers
    for k, v in resp.headers.items():
        kl = k.lower()
        if is_hop_by_hop(kl):
            continue
        if kl == "location":
            response[k] = rewrite_location(request, prefix, v)
        elif kl == "content-encoding":
            if not decompress:
                response[k] = v
        else:
            response[k] = v

    # save the session
    response.set_cookie(cookie_name,
                        sid,
                        max_age=None,
                        expires=None,
                        domain=settings.SESSION_COOKIE_DOMAIN,
Ejemplo n.º 9
0
def proxy_request(request, destination=None, prefix=None, headers=None,
        no_redirect=False, decompress=False, **kwargs):
    """ generic view to proxy a request.

    Args:

        destination: string, the proxied url
        prefix: string, the prrefix behind we proxy the path
        headers: dict, custom HTTP headers
        no_redirect: boolean, False by default, do not redirect to "/" 
            if no path is given
        decompress: boolean, False by default. If true the proxy will
            decompress the source body if it's gzip encoded.

    Return:

        HttpResponse instance
    """

    path = kwargs.get("path")

    if path is None:
        path = request.path
        if prefix is not None and prefix:
            path = path.split(prefix, 1)[1]
    else:
        if not path and not request.path.endswith("/"):
            if not no_redirect:
                qs = request.META["QUERY_STRING"]
                redirect_url = "%s/" % request.path
                if qs:
                    redirect_url = "%s?%s" % (redirect_url, qs)
                return HttpResponsePermanentRedirect(redirect_url)

        if path:
            prefix = request.path.rsplit(path, 1)[0]

    if not path.startswith("/"):
        path = "/%s" % path 

    base_url = absolute_uri(request, destination)
    proxied_url = ""
    if not path:
        proxied_url = "%s/" % base_url
    else:
        proxied_url = "%s%s" % (base_url, path)

    qs = request.META.get("QUERY_STRING")
    if qs is not None and qs:
        proxied_url = "%s?%s" % (proxied_url, qs)

    # fix headers
    headers = headers or {}
    for key, value in request.META.iteritems():
        if key.startswith('HTTP_'):
            key = header_name(key)
            
        elif key in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
            key = key.replace('_', '-')
            if not value: continue
        else:
            continue
    
        # rewrite location
        if key.lower() != "host" and not is_hop_by_hop(key):
            headers[key] = value

    # we forward for
    headers["X-Forwarded-For"] = request.get_host()

    # used in request session store.
    headers["X-Restkit-Reqid"] = uuid.uuid4().hex

    # django doesn't understand PUT sadly
    method = request.method.upper()
    if method == "PUT":
        coerce_put_post(request)

    # do the request


    try:
        resp = restkit.request(proxied_url, method=method,
                body=request.raw_post_data, headers=headers,
                follow_redirect=True,
                decompress=decompress,
                conn_manager=get_conn_manager())
    except restkit.RequestFailed, e:
        msg = getattr(e, 'msg', '')
    
        if e.status_int >= 100:
            resp = e.response
            body = msg
        else:
            return http.HttpResponseBadRequest(msg)
Ejemplo n.º 10
0
    except restkit.RequestFailed, e:
        msg = getattr(e, 'msg', '')
    
        if e.status_int >= 100:
            resp = e.response
            body = msg
        else:
            return http.HttpResponseBadRequest(msg)

    with resp.body_stream() as body:
        response = HttpResponse(BodyWrapper(body), status=resp.status_int)

        # fix response headers
        for k, v in resp.headers.items():
            kl = k.lower()
            if is_hop_by_hop(kl):
                continue
            if kl  == "location":
                response[k] = rewrite_location(request, prefix, v)
                print v
                print response[k]
            else:
                response[k] = v
        return response


class ProxyTarget(object):

    def __init__(self, prefix, url, kwargs=None):
        if not prefix or not url:
            raise ValueError("REVPROXY_SETTINGS is invalid")
Ejemplo n.º 11
0
def forward_header(k):
    return k.upper() not in ["HOST", "CONTENT_LENGTH", "CONTENT_TYPE"] and not is_hop_by_hop(k) and not "." in k
Ejemplo n.º 12
0
    try:
        resp = connection.request(uri, method=request.method, 
                            body=request.raw_post_data,
                            headers=headers)
        body = resp.body_file
    except restkit.RequestFailed, e:
        msg = getattr(e, 'msg', '')
        
        if e.status_int >= 100:
            resp = e.response
            body = msg
        else:
            return http.HttpResponseBadRequest(msg)
             
    response = HttpResponse(body, status=resp.status_int)
    for k, v in resp.headers.items():
        if is_hop_by_hop(k):
            continue
        else:
            response[k] = v
    return response

def header_name(name):
    """Convert header name like HTTP_XXXX_XXX to Xxxx-Xxx:"""
    words = name[5:].split('_')
    for i in range(len(words)):
        words[i] = words[i][0].upper() + words[i][1:].lower()
        
    result = '-'.join(words)
    return result
Ejemplo n.º 13
0
 def send_header(self, header, value):
     if not is_hop_by_hop(header):
         self._response[header] = value