~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/http.py

[merge] James Henstridge: Set Agent string in http headers, add tests for it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
    url = urlparse.urlunsplit((scheme, netloc, path, query, fragment))
62
62
    return url
63
63
 
64
 
    
65
 
def get_url(url):
 
64
 
 
65
class Request(urllib2.Request):
 
66
    """Request object for urllib2 that allows the method to be overridden."""
 
67
 
 
68
    method = None
 
69
 
 
70
    def get_method(self):
 
71
        if self.method is not None:
 
72
            return self.method
 
73
        else:
 
74
            return urllib2.Request.get_method(self)
 
75
 
 
76
 
 
77
def get_url(url, method=None):
66
78
    import urllib2
67
79
    mutter("get_url %s", url)
68
80
    manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
70
82
    auth_handler = urllib2.HTTPBasicAuthHandler(manager)
71
83
    opener = urllib2.build_opener(auth_handler)
72
84
 
73
 
    request = urllib2.Request(url)
 
85
    request = Request(url)
 
86
    request.method = method
74
87
    request.add_header('User-Agent', 'bzr/%s' % bzrlib.__version__)
75
88
    response = opener.open(request)
76
89
    return response
77
90
 
 
91
 
78
92
class HttpTransport(Transport):
79
93
    """This is the transport agent for http:// access.
80
94
    
150
164
    def has(self, relpath):
151
165
        """Does the target location exist?
152
166
 
153
 
        TODO: HttpTransport.has() should use a HEAD request,
154
 
        not a full GET request.
155
 
 
156
167
        TODO: This should be changed so that we don't use
157
168
        urllib2 and get an exception, the code path would be
158
169
        cleaner if we just do an http HEAD request, and parse
161
172
        path = relpath
162
173
        try:
163
174
            path = self.abspath(relpath)
164
 
            f = get_url(path)
 
175
            f = get_url(path, method='HEAD')
165
176
            # Without the read and then close()
166
177
            # we tend to have busy sockets.
167
178
            f.read()
305
316
class TestingHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
306
317
 
307
318
    def log_message(self, format, *args):
308
 
        self.server.test_case.log("webserver - %s - - [%s] %s",
 
319
        self.server.test_case.log('webserver - %s - - [%s] %s "%s" "%s"',
309
320
                                  self.address_string(),
310
321
                                  self.log_date_time_string(),
311
 
                                  format%args)
 
322
                                  format % args,
 
323
                                  self.headers.get('referer', '-'),
 
324
                                  self.headers.get('user-agent', '-'))
312
325
 
313
326
    def handle_one_request(self):
314
327
        """Handle a single HTTP request.
344
357
        method = getattr(self, mname)
345
358
        method()
346
359
 
 
360
 
347
361
class TestingHTTPServer(BaseHTTPServer.HTTPServer):
348
362
    def __init__(self, server_address, RequestHandlerClass, test_case):
349
363
        BaseHTTPServer.HTTPServer.__init__(self, server_address,
354
368
class HttpServer(Server):
355
369
    """A test server for http transports."""
356
370
 
357
 
    _HTTP_PORTS = range(13000, 0x8000)
358
 
 
359
371
    def _http_start(self):
360
372
        httpd = None
361
 
        for port in self._HTTP_PORTS:
362
 
            try:
363
 
                httpd = TestingHTTPServer(('localhost', port),
364
 
                                          TestingHTTPRequestHandler,
365
 
                                          self)
366
 
            except socket.error, e:
367
 
                if e.args[0] == errno.EADDRINUSE:
368
 
                    continue
369
 
                print >>sys.stderr, "Cannot run webserver :-("
370
 
                raise
371
 
            else:
372
 
                break
373
 
 
374
 
        if httpd is None:
375
 
            raise WebserverNotAvailable("Cannot run webserver :-( "
376
 
                                        "no free ports in range %s..%s" %
377
 
                                        (_HTTP_PORTS[0], _HTTP_PORTS[-1]))
378
 
 
 
373
        httpd = TestingHTTPServer(('localhost', 0),
 
374
                                  TestingHTTPRequestHandler,
 
375
                                  self)
 
376
        host, port = httpd.socket.getsockname()
379
377
        self._http_base_url = 'http://localhost:%s/' % port
380
378
        self._http_starting.release()
381
379
        httpd.socket.settimeout(0.1)
400
398
        self._http_starting.release()
401
399
        return self._http_base_url + remote_path
402
400
 
403
 
    def log(self, *args, **kwargs):
 
401
    def log(self, format, *args):
404
402
        """Capture Server log output."""
405
 
        self.logs.append(args[3])
 
403
        self.logs.append(format % args)
406
404
 
407
405
    def setUp(self):
408
406
        """See bzrlib.transport.Server.setUp."""