[long] bzr with wsgi and gunicorn vs Pylons (paste)

John Arbash Meinel john at arbash-meinel.com
Tue Oct 19 14:58:58 BST 2010


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 10/19/2010 8:12 AM, Adrien Saladin wrote:
> Hi,
> 
> I'm playing a little bit with smart bazaar wsgi servers and I'm
> currently trying to integrate the bzr+http protocol in some Pylons
> application.
> 
> I have read the smart server documentation found here:
> http://doc.bazaar.canonical.com/latest/en/user-guide/http_smart_server.html
> First I had to adapt a little bit the wsgi example to be served with
> gunicorn instead of apache, so I put is there for comments and
> eventually to help other wsgi newbies like me:
> 
> 
> ###     server.py              ###
> from bzrlib.transport.http import wsgi
> 
> def application(environ, start_response):
> +    environ['REQUEST_URI']=environ['PATH_INFO']
> 
>     app = wsgi.make_app(
>         root="/home/adrien/bzr/",      #<-- where I put bazaar branches
>         prefix="/bzr/",                      # <-- first part of the URL
>         readonly=True,
>         enable_logging=True)
> 
>     ret =  app(environ, start_response)
>     return ret
> #####################
> # To run the server type:
> # $ gunicorn server  -b localhost:9000
> 
> 
> The only change here is that the environment variable REQUEST_URI is
> not set by gunicorn (neither by Pylons/paste).
> 
> Now I can work with my foo branch with commands like:
> $ bzr branch bzr+http://localhost:9000/bzr/foo
> 
> note that using http instead of bzr+http results in a 404 error.
> 
> Have I done things correctly up to now ?

If you use "bzr command http://..." we will detect if there is a smart
server running, and issue smart requests via POST. However, if we are
just reading the content of a file, we issue a regular GET request. (so
to read .bzr/branch-format we do a simple GET request for the file, to
stream recorded data we issue a POST to .bzr/smart.)

If you use bzr+http:// then we issue a POST to .bzr/smart for the plain
file content as well.



> 
> Now comes my problem, when I try to interface this server in a Pylons
> application.
> First I created a new controller called "bazaar". Then I replaced the
> code for this controller by this:
> 
> ##########  (extract of) controllers/bazaar.py
> def BazaarController(environ, start_response):
>     environ['REQUEST_URI']= environ['PATH_INFO']
> 
>     app = wsgi.make_app(
>             root="/home/adrien/bzr/",
>             prefix="/bazaar/",             #<-- now using /bazaar/ as
> the root URL
>             readonly=True,
>             enable_logging=False)
> 
>     ret = app(environ, start_response)
>     print "@@@returns@@@: ",ret
> 
>     return ret
> 	
> #################

^- Is it valid to have "print ..." in the code? I don't know wsgi/pylons
but I know a lot of web-appy stuff returns stdout back to the user.

> 
> I also modified the config/routing.py for the special URLs from
> bzr+http protocol:
> 
> + map.connect("/bazaar", controller="bazaar")
> + map.connect("/bazaar/{branchname:.*?}", controller="bazaar")
> 
> 
> Now when I test this new setup, I have the following error from bzr (client):
> $ bzr branch bzr+http://localhost:5000/bazaar/foo
> bzr: ERROR: Invalid range access in
> http://localhost:5000/bazaar/foo/.bzr/smart at 0: Can't read 28 bytes
> across range (0, 25)
> 

^- This seems extra strange. This sounds like we are issuing a "GET"
with a range header to .bzr/smart, which we shouldn't ever be doing. Did
you try "bzr+http://..." with the same requests?

> And from the server:
> 14:45:32,078 DEBUG [worker 4] [routes.middleware] Matched POST
> /bazaar/foo/.bzr/smart
> 14:45:32,078 DEBUG [worker 4] [routes.middleware] Route path:
> '/bazaar/{branchname:.*?}', defaults: {'action': u'index',
> 'controller': u'bazaar'}
> 14:45:32,078 DEBUG [worker 4] [routes.middleware] Match dict:
> {'action': u'index', 'controller': u'bazaar', 'branchname':
> u'foo/.bzr/smart'}
> @@@returns@@@:  ['error\x01incomplete request\n']
> 14:45:32,087 DEBUG [worker 5] [routes.middleware] Matched POST
> /bazaar/foo/.bzr/smart
> 14:45:32,088 DEBUG [worker 5] [routes.middleware] Route path:
> '/bazaar/{branchname:.*?}', defaults: {'action': u'index',
> 'controller': u'bazaar'}
> 14:45:32,088 DEBUG [worker 5] [routes.middleware] Match dict:
> {'action': u'index', 'controller': u'bazaar', 'branchname':
> u'foo/.bzr/smart'}
> @@@returns@@@:  ['error\x01incomplete request\n']
> 
> So if I correctly understand, the bzrlib wsgi application returns
> "error\x01incomplete request". However I don't see what to do next to
> understand what happens.
> This looks more or less Pylons specific but maybe bzr or wsgi experts
> here can help me understand what makes bzrlib.transport.http.wsgi
> unhappy.
> 
> Thanks,
> Adrien

error\x01incomplete request\n is the smart servers way of saying there
was a problem. The client code should be handling that and raising an
appropriate error internally.

So the question is why is pylons + whatever not returning the content,
and instead erroring?

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAky9pCIACgkQJdeBCYSNAAMBGwCgqL5O5GYk7NT42PpIZGhuCwkj
3JQAn2SIEIz5ZxfmRftZueuHoqwEwLCb
=YbjQ
-----END PGP SIGNATURE-----



More information about the bazaar mailing list