~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to __init__.py

  • Committer: John Arbash Meinel
  • Date: 2011-02-10 02:33:15 UTC
  • mto: This revision was merged to the branch mainline in revision 441.
  • Revision ID: john@arbash-meinel.com-20110210023315-515pkynlfpfs3cvm
Fix bug #716201 by suppressing body content when getting a HEAD request.

This adds some WSGI middleware that suppresses returning body content if a HEAD request
is received.

Note that we don't yet pass GET down to the lower levels, so they could still
decide whether they can do less work or not. We may want to make the standard BranchWSGIApp
do less work under those circumstances.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
starts a web server to browse the contents of a branch.
31
31
"""
32
32
 
33
 
import sys
34
 
 
35
33
from info import (
36
34
    bzr_plugin_version as version_info,
37
35
    bzr_compatible_versions,
40
38
if __name__ == 'bzrlib.plugins.loggerhead':
41
39
    import bzrlib
42
40
    from bzrlib.api import require_any_api
43
 
    from bzrlib import commands
44
41
 
45
42
    require_any_api(bzrlib, bzr_compatible_versions)
46
43
 
47
 
    from bzrlib.transport import transport_server_registry
 
44
    # NB: Normally plugins should lazily load almost everything, but this
 
45
    # seems reasonable to have in-line here: bzrlib.commands and options are
 
46
    # normally loaded, and the rest of loggerhead won't be loaded until serve
 
47
    # --http is run.
 
48
 
 
49
    # transport_server_registry was added in bzr 1.16. When we drop support for
 
50
    # older releases, we can remove the code to override cmd_serve.
 
51
 
 
52
    try:
 
53
        from bzrlib.transport import transport_server_registry
 
54
    except ImportError:
 
55
        transport_server_registry = None
48
56
 
49
57
    DEFAULT_HOST = '0.0.0.0'
50
58
    DEFAULT_PORT = 8080
51
59
    HELP = ('Loggerhead, a web-based code viewer and server. (default port: %d)' %
52
60
            (DEFAULT_PORT,))
53
61
 
 
62
    def setup_logging(config):
 
63
        import logging
 
64
        import sys
 
65
 
 
66
        logger = logging.getLogger('loggerhead')
 
67
        handler = logging.StreamHandler(sys.stderr)
 
68
        handler.setLevel(logging.DEBUG)
 
69
        logger.addHandler(handler)
 
70
        logging.getLogger('simpleTAL').addHandler(handler)
 
71
        logging.getLogger('simpleTALES').addHandler(handler)
 
72
 
 
73
 
54
74
    def _ensure_loggerhead_path():
55
75
        """Ensure that you can 'import loggerhead' and get the root."""
56
76
        # loggerhead internal code will try to 'import loggerhead', so
74
94
        from loggerhead.apps.http_head import HeadMiddleware
75
95
        from loggerhead.apps.transport import BranchesFromTransportRoot
76
96
        from loggerhead.config import LoggerheadConfig
77
 
        from loggerhead.main import setup_logging
78
97
 
79
98
        if host is None:
80
99
            host = DEFAULT_HOST
84
103
        if not transport.is_readonly():
85
104
            argv.insert(0, '--allow-writes')
86
105
        config = LoggerheadConfig(argv)
87
 
        setup_logging(config, init_logging=False, log_file=sys.stderr)
 
106
        setup_logging(config)
88
107
        app = BranchesFromTransportRoot(transport.base, config)
89
 
        # Bug #758618, HeadMiddleware seems to break HTTPExceptionHandler from
90
 
        # actually sending appropriate return codes to the client. Since nobody
91
 
        # desperately needs HeadMiddleware right now, just ignoring it.
92
 
        # app = HeadMiddleware(app)
 
108
        app = HeadMiddleware(app)
93
109
        app = HTTPExceptionHandler(app)
94
110
        serve(app, host=host, port=port)
95
111
 
96
 
    transport_server_registry.register('http', serve_http, help=HELP)
97
 
 
98
 
    class cmd_load_test_loggerhead(commands.Command):
99
 
        """Run a load test against a live loggerhead instance.
100
 
 
101
 
        Pass in the name of a script file to run. See loggerhead/load_test.py
102
 
        for a description of the file format.
103
 
        """
104
 
 
105
 
        takes_args = ["filename"]
106
 
 
107
 
        def run(self, filename):
108
 
            from bzrlib.plugins.loggerhead.loggerhead import load_test
109
 
            script = load_test.run_script(filename)
110
 
            for thread_id in sorted(script._threads):
111
 
                worker = script._threads[thread_id][0]
112
 
                for url, success, time in worker.stats:
113
 
                    self.outf.write(' %5.3fs %s %s\n'
114
 
                                    % (time, str(success)[0], url))
115
 
 
116
 
    commands.register_command(cmd_load_test_loggerhead)
 
112
    if transport_server_registry is not None:
 
113
        transport_server_registry.register('http', serve_http, help=HELP)
 
114
    else:
 
115
        import bzrlib.builtins
 
116
        from bzrlib.commands import get_cmd_object, register_command
 
117
        from bzrlib.option import Option
 
118
 
 
119
        _original_command = get_cmd_object('serve')
 
120
 
 
121
        class cmd_serve(bzrlib.builtins.cmd_serve):
 
122
            __doc__ = _original_command.__doc__
 
123
 
 
124
            takes_options = _original_command.takes_options + [
 
125
                Option('http', help=HELP)]
 
126
 
 
127
            def run(self, *args, **kw):
 
128
                if 'http' in kw:
 
129
                    from bzrlib.transport import get_transport
 
130
                    allow_writes = kw.get('allow_writes', False)
 
131
                    path = kw.get('directory', '.')
 
132
                    port = kw.get('port', DEFAULT_PORT)
 
133
                    # port might be an int already...
 
134
                    if isinstance(port, basestring) and ':' in port:
 
135
                        host, port = port.split(':')
 
136
                    else:
 
137
                        host = DEFAULT_HOST
 
138
                    if allow_writes:
 
139
                        transport = get_transport(path)
 
140
                    else:
 
141
                        transport = get_transport('readonly+' + path)
 
142
                    serve_http(transport, host, port)
 
143
                else:
 
144
                    super(cmd_serve, self).run(*args, **kw)
 
145
 
 
146
        register_command(cmd_serve)
117
147
 
118
148
    def load_tests(standard_tests, module, loader):
119
149
        _ensure_loggerhead_path()