Ejemplo n.º 1
0
 def _fixup_configured(self, environ):
     path_info = environ['PATH_INFO']
     script_name = environ['SCRIPT_NAME']
     if self.prefix is not None:
         environ['SCRIPT_NAME'] = self.prefix
     elif self.pop_prefix is not None:
         if self.pop_prefix == path_info:
             path_info = ''
             script_name = script_name + self.pop_prefix
         elif path_info.startswith(self.pop_prefix + '/'):
             path_info = path_info[len(self.pop_prefix):]
             script_name = script_name + self.pop_prefix
         else:
             exc = httpexceptions.HTTPBadRequest(
                 "It was expected that all requests would start with "
                 "the path %r, but I got a request with %r" %
                 (self.pop_prefix, path_info))
             raise exc
     if self.scheme is not None:
         environ['wsgi.url_scheme'] = self.scheme
     if self.host is not None:
         domain, port = self.host.split(':', 1)
         environ['HTTP_HOST'] = self.host
         environ['SERVER_NAME'] = domain
         environ['SERVER_PORT'] = port
     if self.port is not None:
         environ['SERVER_PORT'] = self.port
         if self.domain is None:
             host = environ['HTTP_HOST'].split(':', 1) + ':' + self.port
             environ['HTTP_HOST'] = host
     if self.domain is not None:
         host = self.domain + ':' + environ['SERVER_PORT']
         environ['HTTP_HOST'] = host
         environ['SERVER_NAME'] = self.domain
Ejemplo n.º 2
0
    def __call__(self, environ, start_response):
        if (self.allowed_request_methods and environ['REQUEST_METHOD'].lower()
                not in self.allowed_request_methods):
            return httpexceptions.HTTPBadRequest("Disallowed")(environ,
                                                               start_response)

        if self.scheme == 'http':
            ConnClass = httplib.HTTPConnection
        elif self.scheme == 'https':
            ConnClass = httplib.HTTPSConnection
        else:
            raise ValueError("Unknown scheme for %r: %r" %
                             (self.address, self.scheme))
        conn = ConnClass(self.host)
        headers = {}
        for key, value in environ.items():
            if key.startswith('HTTP_'):
                key = key[5:].lower().replace('_', '-')
                if key == 'host' or key in self.suppress_http_headers:
                    continue
                headers[key] = value
        headers['host'] = self.host
        if 'REMOTE_ADDR' in environ:
            headers['x-forwarded-for'] = environ['REMOTE_ADDR']
        if environ.get('CONTENT_TYPE'):
            headers['content-type'] = environ['CONTENT_TYPE']
        if environ.get('CONTENT_LENGTH'):
            headers['content-length'] = environ['CONTENT_LENGTH']
            length = int(environ['CONTENT_LENGTH'])
            body = environ['wsgi.input'].read(length)
        else:
            body = ''

        path_info = urllib.quote(environ['PATH_INFO'])
        if self.path:
            request_path = path_info
            if request_path[0] == '/':
                request_path = request_path[1:]

            path = urlparse.urljoin(self.path, request_path)
        else:
            path = path_info
        if environ.get('QUERY_STRING'):
            path += '?' + environ['QUERY_STRING']

        conn.request(environ['REQUEST_METHOD'], path, body, headers)
        res = conn.getresponse()
        headers_out = parse_headers(res.msg)

        status = '%s %s' % (res.status, res.reason)
        start_response(status, headers_out)
        # @@: Default?
        length = res.getheader('content-length')
        if length is not None:
            body = res.read(int(length))
        else:
            body = res.read()
        conn.close()
        return [body]
Ejemplo n.º 3
0
 def _fixup_environ(self, environ):
     # @@: Obviously better errors here:
     if 'HTTP_X_WSGIPROXY_VERSION' in environ:
         version = environ.pop('HTTP_X_WSGIPROXY_VERSION')
         assert version == protocol_version
     secure = False
     if self.secret_file is not None:
         secret = get_secret(self.secret_file)
         # @@: Should catch error:
         check_request(environ, secret)
         secure = True
     if self.trust_ips:
         ip = environ.get('REMOTE_ADDR')
         if ip in trust_ips:
             # @@: Should allow ranges and whatnot:
             secure = True
     if 'HTTP_X_FORWARDED_SERVER' in environ:
         environ['HTTP_HOST'] = environ.pop('HTTP_X_FORWARDED_SERVER')
     if 'HTTP_X_FORWARDED_SCHEME' in environ:
         environ['wsgi.url_scheme'] = environ.pop('HTTP_X_FORWARDED_SCHEME')
     if 'HTTP_X_FORWARDED_FOR' in environ:
         environ['REMOTE_ADDR'] = environ.pop('HTTP_X_FORWARDED_FOR')
     script_name = environ.get('SCRIPT_NAME', '')
     path_info = environ.get('PATH_INFO', '')
     if 'HTTP_X_TRAVERSAL_PATH' in environ:
         traversal_path = environ['HTTP_X_TRAVERSAL_PATH'].rstrip('/')
         if traversal_path == path_info:
             path_info = ''
         elif not path_info.startswith(traversal_path + '/'):
             exc = httpexceptions.HTTPBadRequest(
                 "The header X-Traversal-Path gives the value %r but "
                 "the path is %r (it should start with "
                 "X-Traversal-Path)" % (traversal_path, path_info))
             return exc(environ, start_response)
         else:
             path_info = path_info[len(traversal_path):]
     if 'HTTP_X_SCRIPT_NAME' in environ:
         add_script_name = environ.pop('HTTP_X_SCRIPT_NAME').rstrip('/')
         if not add_script_name.startswith('/'):
             exc = httpexceptions.HTTPBadRequest(
                 "The header X-Script-Name gives %r which does not "
                 "start with /" % add_script_name)
             return exc(environ, start_response)
         script_name = add_script_name + script_name
     environ['SCRIPT_NAME'] = script_name
     environ['PATH_INFO'] = path_info
     for header, key in [('HTTP_HOST', 'HTTP_HOST'),
                         ('SCRIPT_NAME', 'SCRIPT_NAME'),
                         ('PATH_INFO', 'PATH_INFO'),
                         ('QUERY_STRING', 'QUERY_STRING'),
                         ('WSGI_URL_SCHEME', 'wsgi.url_scheme')]:
         header = 'HTTP_X_WSGIPROXY_%s' % header
         if header in environ:
             environ[key] = environ.pop(header)
     for prefix, decoder, is_secure in [
         ('STR', self.str_decode, True),
         ('UNICODE', self.unicode_decode, True),
         ('JSON', self.json_decode, True),
         ('PICKLE', self.pickle_decode, False)
     ]:
         expect = 'HTTP_X_WSGIPROXY_%s' % prefix
         for key in environ:
             if key.startswith(expect):
                 if not is_secure and not secure:
                     # Better error again!
                     assert 0
                 key_name, value = environ[key].split(None, 1)
                 key_name = urllib.unquote(key_name)
                 value = decoder(value)
                 environ[key_name] = value
Ejemplo n.º 4
0
    def __call__(self, environ, start_response):
        if (self.allowed_request_methods and environ['REQUEST_METHOD'].lower()
                not in self.allowed_request_methods):
            return httpexceptions.HTTPBadRequest("Disallowed")(environ,
                                                               start_response)

        #if self.scheme == 'http':
        #    ConnClass = httplib.HTTPConnection
        #elif self.scheme == 'https':
        #    ConnClass = httplib.HTTPSConnection
        #else:
        #    raise ValueError(
        #        "Unknown scheme for %r: %r" % (self.address, self.scheme))
        #conn = ConnClass(self.host)

        headers = {}
        for key, value in environ.items():
            if key.startswith('HTTP_'):
                key = key[5:].lower().replace('_', '-')
                if key == 'host' or key in self.suppress_http_headers:
                    continue
                headers[key] = value
        headers['host'] = self.host
        if 'REMOTE_ADDR' in environ:
            headers['x-forwarded-for'] = environ['REMOTE_ADDR']
        if environ.get('CONTENT_TYPE'):
            headers['content-type'] = environ['CONTENT_TYPE']
        if environ.get('CONTENT_LENGTH'):
            if environ['CONTENT_LENGTH'] == '-1':
                # This is a special case, where the content length is basically undetermined
                body = environ['wsgi.input'].read(-1)
                headers['content-length'] = str(len(body))
            else:
                headers['content-length'] = environ['CONTENT_LENGTH']
                length = int(environ['CONTENT_LENGTH'])
                body = environ['wsgi.input'].read(length)
        else:
            body = ''

        # x-forward-scheme was breaking in the proxy when https://bisque-site/ was fetch engine_service/_service over http
        # The address was always coming back as https://bisque-engine/_services
        # This code removes any mention of the forwards which seems to be the correct thing/
        for k in headers.keys():
            if k.startswith('x-forwarded'):
                del headers[k]

        #log.debug('environ: %s', str(environ))
        path_info = urllib.quote(environ['PATH_INFO'])
        if self.path:
            request_path = path_info
            if request_path and request_path[0] == '/':
                request_path = request_path[1:]

            path = urlparse.urljoin(self.path, request_path)
        else:
            path = path_info
        if environ.get('QUERY_STRING'):
            path += '?' + environ['QUERY_STRING']

        url = "%s://%s%s" % (self.scheme, self.host, path)
        log.debug('method: %s, url: %s', environ['REQUEST_METHOD'], url)
        log.debug('headers: %s', headers)
        #log.debug('environ: %s', environ)
        #log.debug('body: %s', body)
        try:
            res = requests.request(method=environ['REQUEST_METHOD'],
                                   url=url,
                                   data=body,
                                   headers=headers,
                                   stream=False,
                                   verify=False,
                                   allow_redirects=True)

            log.debug("Proxy response: %s with: %s", str(res), res.headers)
            #log.debug ("Proxy response content: %s", res.content)
            #log.debug ("Proxy response text: %s", res.text)
            #log.debug ("Proxy response history: %s", res.history)
            #log.debug ("Proxy response request headers: %s", res.request.headers)

            status = '%s %s' % (res.status_code, res.reason)
            headers_out = dict(
                (k, res.headers[k]) for k in res.headers
                if k.lower() not in self.suppress_http_headers_out)
            start_response(status, list(headers_out.items()))
            return [res.content]
        except Exception:
            log.exception('Failed')
            start_response("502", [])
            return ['Bad Gateway']
Ejemplo n.º 5
0
    def __call__(self, environ, start_response):
        if (self.allowed_request_methods and 
            environ['REQUEST_METHOD'
                    ].lower() not in self.allowed_request_methods):
            disallowedRequest = httpexceptions.HTTPBadRequest("Disallowed")
            return disallowedRequest(environ, start_response)

        if not self.__environSessionKeyName:
            sslCtx = None
        else:
            session = environ.get(self.__environSessionKeyName)
            if session is None:
                msg = "No session in environ"
                http500Error = httpexceptions.HTTPInternalServerError(msg)
                return http500Error(environ, start_response)
            
            sslCtx = session[self.__ctxSessionKeyName]

        if self.scheme == 'http':
            conn = httplib.HTTPConnection(self.host)
        elif self.scheme == 'https':
            conn = HTTPSConnection(self.host, ssl_context=sslCtx)
        else:
            raise ValueError(
                "Unknown scheme for %r: %r" % (self.address, self.scheme))
        
        headers = {}
        for key, value in environ.items():
            if key.startswith('HTTP_'):
                key = key[5:].lower().replace('_', '-')
                if key == 'host' or key in self.suppress_http_headers:
                    continue
                headers[key] = value
        headers['host'] = self.host
        
        if 'REMOTE_ADDR' in environ:
            headers['x-forwarded-for'] = environ['REMOTE_ADDR']
            
        if environ.get('CONTENT_TYPE'):
            headers['content-type'] = environ['CONTENT_TYPE']
            
        if environ.get('CONTENT_LENGTH'):
            if environ['CONTENT_LENGTH'] != '-1':
                headers['content-length'] = environ['CONTENT_LENGTH'] 
            
        path_info = urllib.quote(environ['PATH_INFO'])
        if self.path:            
            request_path = path_info
            if request_path and request_path[0] == '/':
                request_path = request_path[1:]
                
            path = urljoin(self.path, request_path)
        else:
            path = path_info
            
        if environ.get('QUERY_STRING'):
            path += '?' + environ['QUERY_STRING']
            
        conn.request(environ['REQUEST_METHOD'],
                     path,
                     environ['wsgi.input'], 
                     headers)
        res = conn.getresponse()
        conn.close()
        
        # Handle a security redirect - if not handled it returns None and the
        # original response is returned
        redirectRes = self._handleSecuredRedirect(res, sslCtx)
        if redirectRes is None:
            _res = res
        else:
            _res = redirectRes
            
        headers_out = parse_headers(_res.msg)    
        
        status = '%s %s' % (_res.status, _res.reason)        
        start_response(status, headers_out)
        
        length = int(_res.getheader('content-length', '-1'))
        response = FileObjResponseIterator(_res.fp, file_size=length)

        return response