~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/http/wsgi.py

Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
from cStringIO import StringIO
24
24
 
25
 
from bzrlib.transport import chroot, get_transport, smart
 
25
from bzrlib.smart import protocol
 
26
from bzrlib.transport import chroot, get_transport
26
27
from bzrlib.urlutils import local_path_to_url
27
28
    
28
29
 
94
95
        # accidentally let people access locations they shouldn't.
95
96
        # e.g. consider a smart server request for "get /etc/passwd" or
96
97
        # something.
97
 
        self.backing_transport = chroot.ChrootTransportDecorator(
98
 
            'chroot+' + backing_transport.base, _decorated=backing_transport)
 
98
        self.chroot_server = chroot.ChrootServer(backing_transport)
 
99
        self.chroot_server.setUp()
 
100
        self.backing_transport = get_transport(self.chroot_server.get_url())
 
101
        # While the chroot server can technically be torn down at this point,
 
102
        # as all it does is remove the scheme registration from transport's 
 
103
        # protocol dictionary, we don't *just in case* there are parts of 
 
104
        # bzrlib that will invoke 'get_transport' on urls rather than cloning
 
105
        # around the existing transport.
 
106
        #self.chroot_server.tearDown()
99
107
 
100
108
    def __call__(self, environ, start_response):
101
109
        """WSGI application callable."""
106
114
        relpath = environ['bzrlib.relpath']
107
115
        transport = self.backing_transport.clone(relpath)
108
116
        out_buffer = StringIO()
109
 
        smart_protocol_request = self.make_request(transport, out_buffer.write)
110
117
        request_data_length = int(environ['CONTENT_LENGTH'])
111
118
        request_data_bytes = environ['wsgi.input'].read(request_data_length)
112
 
        smart_protocol_request.accept_bytes(request_data_bytes)
 
119
        smart_protocol_request = self.make_request(
 
120
            transport, out_buffer.write, request_data_bytes)
113
121
        if smart_protocol_request.next_read_size() != 0:
114
122
            # The request appears to be incomplete, or perhaps it's just a
115
123
            # newer version we don't understand.  Regardless, all we can do
123
131
        start_response('200 OK', headers)
124
132
        return [response_data]
125
133
 
126
 
    def make_request(self, transport, write_func):
127
 
        return smart.SmartServerRequestProtocolOne(transport, write_func)
 
134
    def make_request(self, transport, write_func, request_bytes):
 
135
        # XXX: This duplicates the logic in
 
136
        # SmartServerStreamMedium._build_protocol.
 
137
        if request_bytes.startswith(protocol.REQUEST_VERSION_TWO):
 
138
            protocol_class = protocol.SmartServerRequestProtocolTwo
 
139
            request_bytes = request_bytes[len(protocol.REQUEST_VERSION_TWO):]
 
140
        else:
 
141
            protocol_class = protocol.SmartServerRequestProtocolOne
 
142
        server_protocol = protocol_class(transport, write_func)
 
143
        server_protocol.accept_bytes(request_bytes)
 
144
        return server_protocol