~launchpad/zope.testing/3.9.4-p4

« back to all changes in this revision

Viewing changes to src/zope/testing/server.py

  • Committer: Maris Fogels
  • Date: 2010-06-04 14:58:44 UTC
  • Revision ID: maris.fogels@canonical.com-20100604145844-mb48c1ig9gty2kao
Initial import of zope.testing's 3.9.4 SVN tag

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
##############################################################################
 
2
#
 
3
# Copyright (c) 2007 Zope Foundation and Contributors.
 
4
# All Rights Reserved.
 
5
#
 
6
# This software is subject to the provisions of the Zope Public License,
 
7
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
 
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
 
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 
11
# FOR A PARTICULAR PURPOSE.
 
12
#
 
13
##############################################################################
 
14
"""Functional test server to interactively inspect the state of the application.
 
15
 
 
16
You can run it in a functional test by adding a line like this:
 
17
 
 
18
  startServer(http, url, "username", "password")
 
19
 
 
20
http is an instance of HTTPCaller, url is the url that will be opened
 
21
in the browser, the username and password are optional. When you're
 
22
done with inspecting the application press Ctrl+C to continue with the
 
23
functional test.
 
24
 
 
25
$Id: server.py 110538 2010-04-06 03:02:54Z tseaver $
 
26
"""
 
27
import urllib2
 
28
import webbrowser
 
29
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
 
30
import sys
 
31
 
 
32
 
 
33
def makeRequestHandler(http, user=None, password=None):
 
34
    class FunctionalTestRequestHandler(BaseHTTPRequestHandler):
 
35
 
 
36
        def do_GET(self):
 
37
            request = self.raw_requestline
 
38
            if user and password:
 
39
                # Authentication is built in, as there is no fluent
 
40
                # way of transferring session from functional test to
 
41
                # the real browser
 
42
                request += "Authorization: Basic %s:%s\r\n" % (user, password)
 
43
 
 
44
            # Write headers to the request
 
45
            for header in self.headers.headers:
 
46
                request += header
 
47
            request += '\r\n'
 
48
 
 
49
            if self.headers.get('Content-Length'):
 
50
                data = self.rfile.read(int(self.headers.get('Content-Length')))
 
51
                request += data
 
52
            else:
 
53
                # if no content-length was set - read until the last
 
54
                # char, then finish
 
55
                self.request.setblocking(0)
 
56
                while True:
 
57
                    try:
 
58
                        char = self.rfile.read()
 
59
                    except:
 
60
                        break
 
61
                    request += char
 
62
 
 
63
            response = http(request)
 
64
            self.wfile.write(response)
 
65
 
 
66
        do_POST = do_GET
 
67
 
 
68
    return FunctionalTestRequestHandler
 
69
 
 
70
 
 
71
def addPortToURL(url, port):
 
72
    """Add a port number to the url.
 
73
 
 
74
        >>> addPortToURL('http://localhost/foo/bar/baz.html', 3000)
 
75
        'http://localhost:3000/foo/bar/baz.html'
 
76
        >>> addPortToURL('http://foo.bar.com/index.html?param=some-value', 555)
 
77
        'http://foo.bar.com:555/index.html?param=some-value'
 
78
 
 
79
        >>> addPortToURL('http://localhost:666/index.html', 555)
 
80
        'http://localhost:555/index.html'
 
81
 
 
82
    """
 
83
    (scheme, netloc, url, query, fragment) = urllib2.urlparse.urlsplit(url)
 
84
    netloc = netloc.split(':')[0]
 
85
    netloc = "%s:%s" % (netloc, port)
 
86
    url = urllib2.urlparse.urlunsplit((scheme, netloc, url, query, fragment))
 
87
    return url
 
88
 
 
89
 
 
90
def startServer(http, url, user=None, password=None, port=8000):
 
91
    try:
 
92
        server_address = ('', port)
 
93
        requestHandler = makeRequestHandler(http, user, password)
 
94
        url = addPortToURL(url, port)
 
95
        httpd = HTTPServer(server_address, requestHandler)
 
96
        # XXX we rely on browser being slower than our server
 
97
        webbrowser.open(url)
 
98
        print >> sys.stderr, 'Starting HTTP server...'
 
99
        httpd.serve_forever()
 
100
    except KeyboardInterrupt:
 
101
        print >> sys.stderr, 'Stopped HTTP server.'