~bzr-pqm/bzr/bzr.dev

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
===========================
Serving Bazaar with FastCGI
===========================

**This feature is EXPERIMENTAL and is NOT SECURE.  It will allow access to
arbitrary files on your server.**

This document describes one way to setup a Bazaar HTTP smart server, using
Apache 2.0 and FastCGI.

Example
=======

You have a webserver already publishing `/srv/example.com/www/code` as
`http://example.com/code/...` with plain HTTP.  It contains bzr branches and
directories like `/srv/example.com/www/code/branch-one` and
`/srv/example.com/www/code/my-repo/branch-two`.  You want to provide read-only
smart server access to these directories in addition to the existing HTTP
access.

Configuring Apache 2.0
----------------------

First, configure mod_fastcgi, e.g. by adding lines like these to your
httpd.conf::

    LoadModule fastcgi_module /usr/lib/apache2/modules/mod_fastcgi.so
    FastCgiIpcDir /var/lib/apache2/fastcgi
    
In our example, we're already serving `/srv/example.com/www/code` at
`http://example.com/code`, so our existing Apache configuration would look
like::

    Alias /code /srv/example.com/www/code
    <Directory /srv/example.com/www/code>
        Options Indexes
        # ...
    </Directory>

We need to change it to handle all requests for URLs ending in `.bzr/smart`.  It
will look like::

    Alias /code /srv/example.com/www/code
    <Directory /srv/example.com/www/code>
        Options Indexes, FollowSymLinks
        RewriteEngine On
        RewriteBase /code
        RewriteRule ^(.*)/\.bzr/smart$ /srv/example.com/scripts/bzr-smart.fcgi
    </Directory>
    
    # bzr-smart.fcgi isn't under the DocumentRoot, so Alias it into the URL
    # namespace so it can be executed.
    Alias /srv/example.com/scripts/bzr-smart.fcgi /srv/example.com/scripts/bzr-smart.fcgi
    <Directory /srv/example.com/scripts>
        Options ExecCGI
        <Files bzr-smart.fcgi>
            SetHandler fastcgi-script
        </Files>
    </Directory>
    
This instructs Apache to hand requests for any URL ending with `/.bzr/smart`
inside `/code` to a Bazaar smart server via FastCGI.

Refer to the mod_rewrite_ and mod_fastcgi_ documentation for further
information.

.. _mod_rewrite: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
.. _mod_fastcgi: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html

Configuring Bazaar
------------------

We've configured Apache to run the smart server at
`/srv/example.com/scripts/bzr-smart.fcgi`.  This is just a simple script we need
to write to configure a smart server, and glue it to the FastCGI gateway.
Here's what it looks like::

    import fcgi
    from bzrlib.transport.http import wsgi

    smart_server_app = wsgi.make_app(
        root='/srv/example.com/code',
        prefix='/code/',
        path_var='REQUEST_URI')

    fcgi.WSGIServer(smart_server_app).run()
        
The `fcgi` module can be found at http://svn.saddi.com/py-lib/trunk/fcgi.py.  It
is part of flup_.

.. _flup: http://www.saddi.com/software/flup/

Clients
-------

Now you can use `bzr+http://` URLs, e.g.::

    bzr log bzr+http://example.com/code/my-branch

Plain HTTP access should continue to work::

    bzr log http://example.com/code/my-branch


Advanced configuration
======================

Because the Bazaar HTTP smart server is a WSGI application, it can be used with
any 3rd-party WSGI middleware or server that conforms the WSGI standard.  The
only requirements are:

  * to construct a `SmartWSGIApp`, you need to specify a **root transport** that it
    will serve.
  * each request's `environ` dict must have a **'bzrlib.relpath'** variable set.

The `make_app` helper used in the example constructs a `SmartWSGIApp` with a
transport based on the `root` path given to it, and calculates the
'bzrlib.relpath` for each request based on the `prefix` and `path_var`
arguments.  In the example above, it will take the 'REQUEST_URI' (which is set
by Apache), strip the '/code/' prefix and the '/.bzr/smart' suffix, and set that
as the 'bzrlib.relpath', so that a request for '/code/foo/bar/.bzr/smart' will
result in a 'bzrlib.relpath' of 'foo/bzr'.

It's possible to configure a smart server for a non-local transport, or that
does arbitrary path translations, etc, by constructing a `SmartWSGIApp`
directly.  Refer to the docstrings of `bzrlib.transport.http.wsgi` and the `WSGI
standard`_ for further information.

.. _WSGI standard: http://www.python.org/dev/peps/pep-0333/