<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Serving Bazaar with Apache — Bazaar v2.2.4 documentation</title> <link rel="stylesheet" href="../_static/default.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../', VERSION: '2.2.4', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../_static/jquery.js"></script> <script type="text/javascript" src="../_static/underscore.js"></script> <script type="text/javascript" src="../_static/doctools.js"></script> <link rel="shortcut icon" href="../_static/bzr.ico"/> <link rel="top" title="Bazaar v2.2.4 documentation" href="../index.html" /> <link rel="up" title="Bazaar User Guide" href="index.html" /> <link rel="next" title="Writing a plugin" href="writing_a_plugin.html" /> <link rel="prev" title="Configuring email" href="setting_up_email.html" /> </head> <body> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="writing_a_plugin.html" title="Writing a plugin" accesskey="N">next</a></li> <li class="right" > <a href="setting_up_email.html" title="Configuring email" accesskey="P">previous</a> |</li> <li><a href="http://bazaar.canonical.com/"> <img src="../_static/bzr icon 16.png" /> Home</a> | </li> <a href="http://doc.bazaar.canonical.com/en/">Documentation</a> | </li> <li><a href="../index.html">Table of Contents (2.2.4)</a> »</li> <li><a href="index.html" accesskey="U">Bazaar User Guide</a> »</li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="serving-bazaar-with-apache"> <h1>Serving Bazaar with Apache<a class="headerlink" href="#serving-bazaar-with-apache" title="Permalink to this headline">¶</a></h1> <p>This document describes one way to set up a Bazaar HTTP smart server, using Apache 2.0 and FastCGI or mod_python or mod_wsgi.</p> <p>For more information on the smart server, and other ways to configure it see the main <a class="reference external" href="#running-a-smart-server">smart server documentation</a>.</p> <div class="section" id="example"> <h2>Example<a class="headerlink" href="#example" title="Permalink to this headline">¶</a></h2> <p>You have a webserver already publishing <cite>/srv/example.com/www/code</cite> as <cite>http://example.com/code/...</cite> with plain HTTP. It contains bzr branches and directories like <cite>/srv/example.com/www/code/branch-one</cite> and <cite>/srv/example.com/www/code/my-repo/branch-two</cite>. You want to provide read-only smart server access to these directories in addition to the existing HTTP access.</p> </div> <div class="section" id="configuring-apache-2-0"> <h2>Configuring Apache 2.0<a class="headerlink" href="#configuring-apache-2-0" title="Permalink to this headline">¶</a></h2> <div class="section" id="fastcgi"> <h3>FastCGI<a class="headerlink" href="#fastcgi" title="Permalink to this headline">¶</a></h3> <p>First, configure mod_fastcgi, e.g. by adding lines like these to your httpd.conf:</p> <div class="highlight-python"><pre>LoadModule fastcgi_module /usr/lib/apache2/modules/mod_fastcgi.so FastCgiIpcDir /var/lib/apache2/fastcgi</pre> </div> <p>In our example, we’re already serving <cite>/srv/example.com/www/code</cite> at <cite>http://example.com/code</cite>, so our existing Apache configuration would look like:</p> <div class="highlight-python"><pre>Alias /code /srv/example.com/www/code <Directory /srv/example.com/www/code> Options Indexes # ... </Directory></pre> </div> <p>We need to change it to handle all requests for URLs ending in <cite>.bzr/smart</cite>. It will look like:</p> <div class="highlight-python"><pre>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></pre> </div> <p>This instructs Apache to hand requests for any URL ending with <cite>/.bzr/smart</cite> inside <cite>/code</cite> to a Bazaar smart server via FastCGI.</p> <p>Refer to the <a class="reference external" href="http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html">mod_rewrite</a> and <a class="reference external" href="http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html">mod_fastcgi</a> documentation for further information.</p> </div> <div class="section" id="mod-python"> <h3>mod_python<a class="headerlink" href="#mod-python" title="Permalink to this headline">¶</a></h3> <p>First, configure mod_python, e.g. by adding lines like these to your httpd.conf:</p> <div class="highlight-python"><pre>LoadModule python_module /usr/lib/apache2/modules/mod_python.so</pre> </div> <p>Define the rewrite rules with mod_rewrite the same way as for FastCGI, except change:</p> <div class="highlight-python"><pre>RewriteRule ^(.*/|)\.bzr/smart$ /srv/example.com/scripts/bzr-smart.fcgi</pre> </div> <p>to:</p> <div class="highlight-python"><pre>RewriteRule ^(.*/|)\.bzr/smart$ /srv/example.com/scripts/bzr-smart.py</pre> </div> <p>Like with mod_fastcgi, we also define how our script is to be handled:</p> <div class="highlight-python"><pre>Alias /srv/example.com/scripts/bzr-smart.py /srv/example.com/scripts/bzr-smart.py <Directory /srv/example.com/scripts> <Files bzr-smart.py> PythonPath "sys.path+['/srv/example.com/scripts']" AddHandler python-program .py PythonHandler bzr-smart::handler </Files> </Directory></pre> </div> <p>This instructs Apache to hand requests for any URL ending with <cite>/.bzr/smart</cite> inside <cite>/code</cite> to a Bazaar smart server via mod_python.</p> <p>NOTE: If you don’t have bzrlib in your PATH, you will be need to change the following line:</p> <div class="highlight-python"><pre>PythonPath "sys.path+['/srv/example.com/scripts']"</pre> </div> <p>To:</p> <div class="highlight-python"><pre>PythonPath "['/path/to/bzr']+sys.path+['/srv/example.com/scripts']"</pre> </div> <p>Refer to the <a class="reference external" href="http://www.modpython.org/">mod_python</a> documentation for further information.</p> </div> <div class="section" id="mod-wsgi"> <h3>mod_wsgi<a class="headerlink" href="#mod-wsgi" title="Permalink to this headline">¶</a></h3> <p>First, configure mod_wsgi, e.g. enabling the mod with a2enmod wsgi. We need to change it to handle all requests for URLs ending in <cite>.bzr/smart</cite>. It will look like:</p> <div class="highlight-python"><pre>WSGIScriptAliasMatch ^/code/.*/\.bzr/smart$ /srv/example.com/scripts/bzr.wsgi #The three next lines allow regular GETs to work too RewriteEngine On RewriteCond %{REQUEST_URI} !^/code/.*/\.bzr/smart$ RewriteRule ^/code/(.*/\.bzr/.*)$ /srv/example.com/www/code/$1 [L] <Directory /srv/example.com/www/code> WSGIApplicationGroup %{GLOBAL} </Directory></pre> </div> <p>This instructs Apache to hand requests for any URL ending with <cite>/.bzr/smart</cite> inside <cite>/code</cite> to a Bazaar smart server via WSGI, and any other URL inside <cite>/code</cite> to be served directly by Apache.</p> <p>Refer to the <a class="reference external" href="http://code.google.com/p/modwsgi/">mod_wsgi</a> documentation for further information.</p> </div> </div> <div class="section" id="configuring-bazaar"> <h2>Configuring Bazaar<a class="headerlink" href="#configuring-bazaar" title="Permalink to this headline">¶</a></h2> <div class="section" id="id3"> <h3>FastCGI<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3> <p>We’ve configured Apache to run the smart server at <cite>/srv/example.com/scripts/bzr-smart.fcgi</cite>. 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:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">fcgi</span> <span class="kn">from</span> <span class="nn">bzrlib.transport.http</span> <span class="kn">import</span> <span class="n">wsgi</span> <span class="n">smart_server_app</span> <span class="o">=</span> <span class="n">wsgi</span><span class="o">.</span><span class="n">make_app</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="s">'/srv/example.com/www/code'</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s">'/code/'</span><span class="p">,</span> <span class="n">path_var</span><span class="o">=</span><span class="s">'REQUEST_URI'</span><span class="p">,</span> <span class="n">readonly</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">load_plugins</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">enable_logging</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="n">fcgi</span><span class="o">.</span><span class="n">WSGIServer</span><span class="p">(</span><span class="n">smart_server_app</span><span class="p">)</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> </pre></div> </div> <p>The <cite>fcgi</cite> module can be found at <a class="reference external" href="http://svn.saddi.com/py-lib/trunk/fcgi.py">http://svn.saddi.com/py-lib/trunk/fcgi.py</a>. It is part of <a class="reference external" href="http://www.saddi.com/software/flup/">flup</a>.</p> </div> <div class="section" id="id4"> <h3>mod_python<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3> <p>We’ve configured Apache to run the smart server at <cite>/srv/example.com/scripts/bzr-smart.py</cite>. This is just a simple script we need to write to configure a smart server, and glue it to the mod_python gateway. Here’s what it looks like:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">modpywsgi</span> <span class="kn">from</span> <span class="nn">bzrlib.transport.http</span> <span class="kn">import</span> <span class="n">wsgi</span> <span class="n">smart_server_app</span> <span class="o">=</span> <span class="n">wsgi</span><span class="o">.</span><span class="n">make_app</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="s">'/srv/example.com/www/code'</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s">'/code/'</span><span class="p">,</span> <span class="n">path_var</span><span class="o">=</span><span class="s">'REQUEST_URI'</span><span class="p">,</span> <span class="n">readonly</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">load_plugins</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">enable_logging</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="k">def</span> <span class="nf">handler</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> <span class="sd">"""Handle a single request."""</span> <span class="n">wsgi_server</span> <span class="o">=</span> <span class="n">modpywsgi</span><span class="o">.</span><span class="n">WSGIServer</span><span class="p">(</span><span class="n">smart_server_app</span><span class="p">)</span> <span class="k">return</span> <span class="n">wsgi_server</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">request</span><span class="p">)</span> </pre></div> </div> <p>The <cite>modpywsgi</cite> module can be found at <a class="reference external" href="http://ice.usq.edu.au/svn/ice/trunk/apps/ice-server/modpywsgi.py">http://ice.usq.edu.au/svn/ice/trunk/apps/ice-server/modpywsgi.py</a>. It was part of <a class="reference external" href="http://dev.pocoo.org/projects/pocoo/">pocoo</a>. You sould make sure you place modpywsgi.py in the same directory as bzr-smart.py (ie. /srv/example.com/scripts/).</p> </div> <div class="section" id="id5"> <h3>mod_wsgi<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3> <p>We’ve configured Apache to run the smart server at <cite>/srv/example.com/scripts/bzr.wsgi</cite>. This is just a simple script we need to write to configure a smart server, and glue it to the WSGI gateway. Here’s what it looks like:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">bzrlib.transport.http</span> <span class="kn">import</span> <span class="n">wsgi</span> <span class="k">def</span> <span class="nf">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span> <span class="n">app</span> <span class="o">=</span> <span class="n">wsgi</span><span class="o">.</span><span class="n">make_app</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="s">"/srv/example.com/www/code/"</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s">"/code"</span><span class="p">,</span> <span class="n">readonly</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">enable_logging</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> <span class="k">return</span> <span class="n">app</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">)</span> </pre></div> </div> </div> </div> <div class="section" id="clients"> <h2>Clients<a class="headerlink" href="#clients" title="Permalink to this headline">¶</a></h2> <p>Now you can use <cite>bzr+http://</cite> URLs or just <cite>http://</cite> URLs, e.g.:</p> <div class="highlight-python"><pre>bzr log bzr+http://example.com/code/my-branch</pre> </div> <p>Plain HTTP access should continue to work:</p> <div class="highlight-python"><pre>bzr log http://example.com/code/my-branch</pre> </div> </div> <div class="section" id="advanced-configuration"> <h2>Advanced configuration<a class="headerlink" href="#advanced-configuration" title="Permalink to this headline">¶</a></h2> <p>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:</p> <blockquote> <div><ul class="simple"> <li>to construct a <cite>SmartWSGIApp</cite>, you need to specify a <strong>root transport</strong> that it will serve.</li> <li>each request’s <cite>environ</cite> dict must have a <strong>‘bzrlib.relpath’</strong> variable set.</li> </ul> </div></blockquote> <p>The <cite>make_app</cite> helper used in the example constructs a <cite>SmartWSGIApp</cite> with a transport based on the <cite>root</cite> path given to it, and calculates the ‘bzrlib.relpath` for each request based on the <cite>prefix</cite> and <cite>path_var</cite> 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’.</p> <p>It’s possible to configure a smart server for a non-local transport, or that does arbitrary path translations, etc, by constructing a <cite>SmartWSGIApp</cite> directly. Refer to the docstrings of <cite>bzrlib.transport.http.wsgi</cite> and the <a class="reference external" href="http://www.python.org/dev/peps/pep-0333/">WSGI standard</a> for further information.</p> <div class="section" id="pushing-over-the-http-smart-server"> <h3>Pushing over the http smart server<a class="headerlink" href="#pushing-over-the-http-smart-server" title="Permalink to this headline">¶</a></h3> <p>It is possible to allow pushing data over the http smart server. The easiest way to do this, is to just supply <tt class="docutils literal"><span class="pre">readonly=False</span></tt> to the <tt class="docutils literal"><span class="pre">wsgi.make_app()</span></tt> call. But be careful, because the smart protocol does not contain any Authentication. So if you enable write support, you will want to restrict access to <tt class="docutils literal"><span class="pre">.bzr/smart</span></tt> URLs to restrict who can actually write data on your system, e.g. in apache it looks like:</p> <div class="highlight-python"><pre><Location /code> AuthType Basic AuthName "example" AuthUserFile /srv/example.com/conf/auth.passwd <LimitExcept GET> Require valid-user </LimitExcept> </Location></pre> </div> <p>At this time, it is not possible to allow some people to have read-only access and others to have read-write access to the same urls. Because at the HTTP layer (which is doing the Authenticating), everything is just a POST request. However, it would certainly be possible to have HTTPS require authentication and use a writable server, and plain HTTP allow read-only access.</p> <p>If bzr gives an error like this when accessing your HTTPS site:</p> <div class="highlight-python"><pre>bzr: ERROR: Connection error: curl connection error (server certificate verification failed. CAfile:/etc/ssl/certs/ca-certificates.crt CRLfile: none)</pre> </div> <p>You can workaround it by using <tt class="docutils literal"><span class="pre">https+urllib</span></tt> rather than <tt class="docutils literal"><span class="pre">http</span></tt> in your URL, or by uninstalling pycurl. See <a class="reference external" href="https://bugs.launchpad.net/bzr/+bug/82086">bug 82086</a> for more details.</p> </div> </div> </div> </div> </div> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../index.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">Serving Bazaar with Apache</a><ul> <li><a class="reference internal" href="#example">Example</a></li> <li><a class="reference internal" href="#configuring-apache-2-0">Configuring Apache 2.0</a><ul> <li><a class="reference internal" href="#fastcgi">FastCGI</a></li> <li><a class="reference internal" href="#mod-python">mod_python</a></li> <li><a class="reference internal" href="#mod-wsgi">mod_wsgi</a></li> </ul> </li> <li><a class="reference internal" href="#configuring-bazaar">Configuring Bazaar</a><ul> <li><a class="reference internal" href="#id3">FastCGI</a></li> <li><a class="reference internal" href="#id4">mod_python</a></li> <li><a class="reference internal" href="#id5">mod_wsgi</a></li> </ul> </li> <li><a class="reference internal" href="#clients">Clients</a></li> <li><a class="reference internal" href="#advanced-configuration">Advanced configuration</a><ul> <li><a class="reference internal" href="#pushing-over-the-http-smart-server">Pushing over the http smart server</a></li> </ul> </li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="setting_up_email.html" title="previous chapter">Configuring email</a></p> <h4>Next topic</h4> <p class="topless"><a href="writing_a_plugin.html" title="next chapter">Writing a plugin</a></p> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../_sources/user-guide/http_smart_server.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../search.html" method="get"> <input type="text" name="q" size="18" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="writing_a_plugin.html" title="Writing a plugin" >next</a></li> <li class="right" > <a href="setting_up_email.html" title="Configuring email" >previous</a> |</li> <li><a href="http://bazaar.canonical.com/"> <img src="../_static/bzr icon 16.png" /> Home</a> | </li> <a href="http://doc.bazaar.canonical.com/en/">Documentation</a> | </li> <li><a href="../index.html">Table of Contents (2.2.4)</a> »</li> <li><a href="index.html" >Bazaar User Guide</a> »</li> </ul> </div> <div class="footer"> © Copyright 2009, Canonical Ltd. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7. </div> </body> </html>