~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to doc/http_smart_server.txt

  • Committer: Aaron Bentley
  • Date: 2007-06-11 14:59:52 UTC
  • mto: (2520.5.2 bzr.mpbundle)
  • mto: This revision was merged to the branch mainline in revision 2631.
  • Revision ID: abentley@panoramicfeedback.com-20070611145952-cwt4480gphdhen6l
Get installation started

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Serving Bazaar with Apache
2
 
==========================
 
1
===========================
 
2
Serving Bazaar with FastCGI
 
3
===========================
 
4
 
 
5
**This feature is EXPERIMENTAL and is NOT SECURE.  It will allow access to
 
6
arbitrary files on your server.**
3
7
 
4
8
This document describes one way to set up a Bazaar HTTP smart server,
5
 
using Apache 2.0 and FastCGI or mod_python or mod_wsgi.
6
 
 
7
 
For more information on the smart server, and other ways to configure it
8
 
see the main `smart server documentation <server.html>`_.
 
9
using Apache 2.0 and FastCGI or mod_python.
9
10
 
10
11
Example
11
 
-------
 
12
=======
12
13
 
13
14
You have a webserver already publishing `/srv/example.com/www/code` as
14
15
`http://example.com/code/...` with plain HTTP.  It contains bzr branches and
28
29
 
29
30
    LoadModule fastcgi_module /usr/lib/apache2/modules/mod_fastcgi.so
30
31
    FastCgiIpcDir /var/lib/apache2/fastcgi
31
 
 
 
32
    
32
33
In our example, we're already serving `/srv/example.com/www/code` at
33
34
`http://example.com/code`, so our existing Apache configuration would look
34
35
like::
44
45
 
45
46
    Alias /code /srv/example.com/www/code
46
47
    <Directory /srv/example.com/www/code>
47
 
        Options Indexes FollowSymLinks
 
48
        Options Indexes, FollowSymLinks
48
49
        RewriteEngine On
49
50
        RewriteBase /code
50
 
        RewriteRule ^(.*/)?\.bzr/smart$ /srv/example.com/scripts/bzr-smart.fcgi
 
51
        RewriteRule ^(.*/|)\.bzr/smart$ /srv/example.com/scripts/bzr-smart.fcgi
51
52
    </Directory>
52
 
 
 
53
    
53
54
    # bzr-smart.fcgi isn't under the DocumentRoot, so Alias it into the URL
54
55
    # namespace so it can be executed.
55
56
    Alias /srv/example.com/scripts/bzr-smart.fcgi /srv/example.com/scripts/bzr-smart.fcgi
59
60
            SetHandler fastcgi-script
60
61
        </Files>
61
62
    </Directory>
62
 
 
 
63
    
63
64
This instructs Apache to hand requests for any URL ending with `/.bzr/smart`
64
65
inside `/code` to a Bazaar smart server via FastCGI.
65
66
 
80
81
Define the rewrite rules with mod_rewrite the same way as for FastCGI, except
81
82
change::
82
83
 
83
 
    RewriteRule ^(.*/)?\.bzr/smart$ /srv/example.com/scripts/bzr-smart.fcgi
 
84
    RewriteRule ^(.*/|)\.bzr/smart$ /srv/example.com/scripts/bzr-smart.fcgi
84
85
 
85
86
to::
86
87
 
87
 
    RewriteRule ^(.*/)?\.bzr/smart$ /srv/example.com/scripts/bzr-smart.py
 
88
    RewriteRule ^(.*/|)\.bzr/smart$ /srv/example.com/scripts/bzr-smart.py
88
89
 
89
90
Like with mod_fastcgi, we also define how our script is to be handled::
90
91
 
100
101
This instructs Apache to hand requests for any URL ending with `/.bzr/smart`
101
102
inside `/code` to a Bazaar smart server via mod_python.
102
103
 
103
 
NOTE: If you don't have bzrlib in your PATH, you will be need to change the
104
 
following line::
105
 
 
106
 
            PythonPath "sys.path+['/srv/example.com/scripts']"
107
 
 
108
 
To::
109
 
 
110
 
            PythonPath "['/path/to/bzr']+sys.path+['/srv/example.com/scripts']"
111
 
 
112
 
 
113
104
Refer to the mod_python_ documentation for further information.
114
105
 
115
106
.. _mod_python: http://www.modpython.org/
116
107
 
117
108
 
118
 
mod_wsgi
119
 
~~~~~~~~
120
 
 
121
 
First, configure mod_wsgi, e.g. enabling the mod with a2enmod wsgi.
122
 
We need to change it to handle all requests for URLs ending in `.bzr/smart`.  It
123
 
will look like::
124
 
 
125
 
    WSGIScriptAliasMatch ^/code/.*/\.bzr/smart$ /srv/example.com/scripts/bzr.wsgi
126
 
 
127
 
    #The three next lines allow regular GETs to work too
128
 
    RewriteEngine On
129
 
    RewriteCond %{REQUEST_URI} !^/code/.*/\.bzr/smart$
130
 
    RewriteRule ^/code/(.*/\.bzr/.*)$ /srv/example.com/www/code/$1 [L]
131
 
 
132
 
    <Directory /srv/example.com/www/code>
133
 
        WSGIApplicationGroup %{GLOBAL}
134
 
    </Directory>
135
 
 
136
 
This instructs Apache to hand requests for any URL ending with `/.bzr/smart`
137
 
inside `/code` to a Bazaar smart server via WSGI, and any other URL inside
138
 
`/code` to be served directly by Apache.
139
 
 
140
 
Refer to the mod_wsgi_ documentation for further information.
141
 
 
142
 
.. _mod_wsgi: http://code.google.com/p/modwsgi/
143
 
 
144
109
Configuring Bazaar
145
110
------------------
146
111
 
156
121
    from bzrlib.transport.http import wsgi
157
122
 
158
123
    smart_server_app = wsgi.make_app(
159
 
        root='/srv/example.com/www/code',
 
124
        root='/srv/example.com/code',
160
125
        prefix='/code/',
161
126
        path_var='REQUEST_URI',
162
 
        readonly=True,
163
 
        load_plugins=True,
164
 
        enable_logging=True)
 
127
        readonly=True)
165
128
 
166
129
    fcgi.WSGIServer(smart_server_app).run()
167
 
 
 
130
        
168
131
The `fcgi` module can be found at http://svn.saddi.com/py-lib/trunk/fcgi.py.  It
169
132
is part of flup_.
170
133
 
182
145
    from bzrlib.transport.http import wsgi
183
146
 
184
147
    smart_server_app = wsgi.make_app(
185
 
        root='/srv/example.com/www/code',
 
148
        root='/srv/example.com/code',
186
149
        prefix='/code/',
187
150
        path_var='REQUEST_URI',
188
 
        readonly=True,
189
 
        load_plugins=True,
190
 
        enable_logging=True)
 
151
        readonly=True)
191
152
 
192
153
    def handler(request):
193
154
        """Handle a single request."""
194
155
        wsgi_server = modpywsgi.WSGIServer(smart_server_app)
195
156
        return wsgi_server.run(request)
196
 
 
197
 
The `modpywsgi` module can be found at
198
 
http://ice.usq.edu.au/svn/ice/trunk/apps/ice-server/modpywsgi.py. It was
199
 
part of pocoo_. You sould make sure you place modpywsgi.py in the same
200
 
directory as bzr-smart.py (ie. /srv/example.com/scripts/).
201
 
 
202
 
.. _pocoo: http://dev.pocoo.org/projects/pocoo/
203
 
 
204
 
 
205
 
mod_wsgi
206
 
~~~~~~~~
207
 
 
208
 
We've configured Apache to run the smart server at
209
 
`/srv/example.com/scripts/bzr.wsgi`.  This is just a simple script we need
210
 
to write to configure a smart server, and glue it to the WSGI gateway.
211
 
Here's what it looks like::
212
 
 
213
 
    from bzrlib.transport.http import wsgi
214
 
 
215
 
    def application(environ, start_response):
216
 
        app = wsgi.make_app(
217
 
            root="/srv/example.com/www/code/",
218
 
            prefix="/code",
219
 
            readonly=True,
220
 
            enable_logging=False)
221
 
        return app(environ, start_response)
 
157
        
 
158
The `modpywsgi` module can be found at http://trac.pocoo.org/wiki/ModPyWsgi.  It
 
159
is part of pocoo_.
 
160
 
 
161
.. _pocoo: http://trac.pocoo.org/wiki/
222
162
 
223
163
Clients
224
164
-------
225
165
 
226
 
Now you can use `bzr+http://` URLs or just `http://` URLs, e.g.::
 
166
Now you can use `bzr+http://` URLs, e.g.::
227
167
 
228
168
    bzr log bzr+http://example.com/code/my-branch
229
169
 
231
171
 
232
172
    bzr log http://example.com/code/my-branch
233
173
 
 
174
 
234
175
Advanced configuration
235
 
----------------------
 
176
======================
236
177
 
237
178
Because the Bazaar HTTP smart server is a WSGI application, it can be used with
238
179
any 3rd-party WSGI middleware or server that conforms the WSGI standard.  The
258
199
.. _WSGI standard: http://www.python.org/dev/peps/pep-0333/
259
200
 
260
201
 
261
 
Pushing over the HTTP smart server
262
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
202
Pushing over ``bzr+http://``
 
203
----------------------------
263
204
 
264
 
It is possible to allow pushing data over the HTTP smart server. The
 
205
It is possible to allow pushing data over the http smart server. The
265
206
easiest way to do this, is to just supply ``readonly=False`` to the
266
207
``wsgi.make_app()`` call. But be careful, because the smart protocol does
267
208
not contain any Authentication. So if you enable write support, you will
268
209
want to restrict access to ``.bzr/smart`` URLs to restrict who can
269
 
actually write data on your system, e.g. in apache it looks like::
270
 
 
271
 
    <Location /code>
272
 
        AuthType Basic
273
 
        AuthName "example"
274
 
        AuthUserFile /srv/example.com/conf/auth.passwd
275
 
        <LimitExcept GET>
276
 
            Require valid-user
277
 
        </LimitExcept>
278
 
    </Location>
279
 
 
280
 
At this time, it is not possible to allow some people to have read-only
281
 
access and others to have read-write access to the same URLs. Because at
282
 
the HTTP layer (which is doing the Authenticating), everything is just a
283
 
POST request.  However, it would certainly be possible to have HTTPS
284
 
require authentication and use a writable server, and plain HTTP allow
285
 
read-only access.
286
 
 
287
 
If bzr gives an error like this when accessing your HTTPS site::
288
 
 
289
 
  bzr: ERROR: Connection error: curl connection error (server certificate verification failed.
290
 
  CAfile:/etc/ssl/certs/ca-certificates.crt CRLfile: none)
291
 
 
292
 
You can workaround it by using ``https+urllib`` rather than ``http`` in your
293
 
URL, or by uninstalling pycurl.  See `bug 82086`_ for more details.
294
 
 
295
 
.. _bug 82086: https://bugs.launchpad.net/bzr/+bug/82086
296
 
 
297
 
..
 
210
actually write data on your system.  At this time, it is not possible to
 
211
allow some people to have read-only access and others to have read-write
 
212
access to the same urls. Because at the HTTP layer (which is doing the
 
213
Authenticating), everything is just a POST request.  However, it would
 
214
certainly be possible to have HTTPS require authentication and use a
 
215
writable server, and plain HTTP allow read-only access.
 
216
 
 
217
 
 
218
.. 
298
219
   vim: ft=rst tw=74 et