Changeset - a8ea3ce3cdc4
[Not reviewed]
default
2 1 3
Marcin Kuzminski - 15 years ago 2010-05-23 00:54:22
marcin@python-works.com
Created middleware package. Crated special middleware to handle https requests redirections.
5 files changed with 25 insertions and 29 deletions:
0 comments (0 inline, 0 general)
pylons_app/config/middleware.py
Show inline comments
 
"""Pylons middleware initialization"""
 
from beaker.middleware import SessionMiddleware
 
from paste.cascade import Cascade
 
from paste.registry import RegistryManager
 
from paste.urlparser import StaticURLParser
 
from paste.deploy.converters import asbool
 
from pylons.middleware import ErrorHandler, StatusCodeRedirect
 
from pylons.wsgiapp import PylonsApp
 
from routes.middleware import RoutesMiddleware
 
from pylons_app.lib.simplehg import SimpleHg
 
from pylons_app.lib.middleware.simplehg import SimpleHg
 
from pylons_app.lib.middleware.https_fixup import HttpsFixup
 
from pylons_app.config.environment import load_environment
 

	
 
def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
 
    """Create a Pylons WSGI application and return it
 

	
 
    ``global_conf``
 
        The inherited configuration for this application. Normally from
 
        the [DEFAULT] section of the Paste ini file.
 

	
 
    ``full_stack``
 
        Whether or not this application provides a full WSGI stack (by
 
        default, meaning it handles its own exceptions and errors).
 
        Disable full_stack when this application is "managed" by
 
        another WSGI middleware.
 

	
 
    ``app_conf``
 
        The application's local configuration. Normally specified in
 
        the [app:<name>] section of the Paste ini file (where <name>
 
        defaults to main).
 

	
 
    """
 
    # Configure the Pylons environment
 
    config = load_environment(global_conf, app_conf)
 

	
 

	
 
    # The Pylons WSGI app
 
    app = PylonsApp(config=config)
 

	
 
    
 
    # Routing/Session/Cache Middleware
 
    app = RoutesMiddleware(app, config['routes.map'])
 
    app = SessionMiddleware(app, config)
 
    
 
    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)    
 
    #set the https based on HTTP_X_URL_SCHEME
 
    app = HttpsFixup(app)
 
    app = SimpleHg(app, config)
 
    
 
    if asbool(full_stack):
 
        # Handle Python exceptions
 
        app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
 

	
 
        # Display error documents for 401, 403, 404 status codes (and
 
        # 500 when debug is disabled)
 
        if asbool(config['debug']):
 
            app = StatusCodeRedirect(app)
 
        else:
 
            app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
 
    
 
    # Establish the Registry for this application
 
    app = RegistryManager(app)
 

	
 
    if asbool(static_files):
 
        # Serve static files
 
        static_app = StaticURLParser(config['pylons.paths']['static_files'])
 
        app = Cascade([static_app, app])
 
    
 
        app.config = config
 

	
 
    return app
pylons_app/lib/hgapp.py
Show inline comments
 
deleted file
pylons_app/lib/middleware/__init__.py
Show inline comments
 
new file 100644
pylons_app/lib/middleware/https_fixup.py
Show inline comments
 
new file 100644
 
class HttpsFixup(object):
 
    def __init__(self, app):
 
        self.application = app
 
    
 
    def __call__(self, environ, start_response):
 
        self.__fixup(environ)
 
        return self.application(environ, start_response)
 
    
 
    
 
    def __fixup(self, environ):
 
        """Function to fixup the environ as needed. In order to use this
 
        middleware you should set this header inside your 
 
        proxy ie. nginx, apache etc.
 
        """
 
        proto = environ.get('HTTP_X_URL_SCHEME')
 
            
 
        if proto == 'https':
 
            environ['wsgi.url_scheme'] = proto
 
        else:
 
            environ['wsgi.url_scheme'] = 'http'
 
        return None
pylons_app/lib/middleware/simplehg.py
Show inline comments
 
file renamed from pylons_app/lib/simplehg.py to pylons_app/lib/middleware/simplehg.py
 
@@ -13,50 +13,48 @@ It's implemented with basic auth functio
 
from datetime import datetime
 
from mercurial.hgweb import hgweb
 
from mercurial.hgweb.request import wsgiapplication
 
from paste.auth.basic import AuthBasicAuthenticator
 
from paste.httpheaders import REMOTE_USER, AUTH_TYPE
 
from pylons_app.lib.auth import authfunc
 
from pylons_app.lib.utils import is_mercurial, make_ui, invalidate_cache
 
from pylons_app.model import meta
 
from pylons_app.model.db import UserLogs, Users
 
from webob.exc import HTTPNotFound
 
import logging
 
import os
 
log = logging.getLogger(__name__)
 

	
 
class SimpleHg(object):
 

	
 
    def __init__(self, application, config):
 
        self.application = application
 
        self.config = config
 
        #authenticate this mercurial request using 
 
        realm = '%s %s' % (config['hg_app_name'], 'mercurial repository')
 
        self.authenticate = AuthBasicAuthenticator(realm, authfunc)
 
        
 
    def __call__(self, environ, start_response):
 
        #dirty fix for https
 
        environ['wsgi.url_scheme'] = 'https'
 
        if not is_mercurial(environ):
 
            return self.application(environ, start_response)
 
        else:
 
            #===================================================================
 
            # AUTHENTICATE THIS MERCURIAL REQUEST
 
            #===================================================================
 
            username = REMOTE_USER(environ)
 
            if not username:
 
                result = self.authenticate(environ)
 
                if isinstance(result, str):
 
                    AUTH_TYPE.update(environ, 'basic')
 
                    REMOTE_USER.update(environ, result)
 
                else:
 
                    return result.wsgi_application(environ, start_response)
 
            
 
            try:
 
                repo_name = environ['PATH_INFO'].split('/')[1]
 
            except:
 
                return HTTPNotFound()(environ, start_response)
 
            
 
            #since we wrap into hgweb, just reset the path
 
            environ['PATH_INFO'] = '/'
 
            self.baseui = make_ui()
 
            self.basepath = self.baseui.configitems('paths')[0][1]\
0 comments (0 inline, 0 general)