cc07b9191f1b5530a3d53f5aa513938f03385625
[WebKit-https.git] / WebDriverTests / imported / w3c / tools / webdriver / webdriver / transport.py
1 import httplib
2 import json
3 import urlparse
4
5 import error
6
7 class Response(object):
8     """Describes an HTTP response received from a remote en"Describes an HTTP
9     response received from a remote end whose body has been read and parsed as
10     appropriate."""
11     def __init__(self, status, body):
12         self.status = status
13         self.body = body
14
15     def __repr__(self):
16         return "wdclient.Response(status=%d, body=%s)" % (self.status, self.body)
17
18     @classmethod
19     def from_http_response(cls, http_response):
20         status = http_response.status
21         body = http_response.read()
22
23         # SpecID: dfn-send-a-response
24         #
25         # > 3. Set the response's header with name and value with the following
26         # >    values:
27         # >
28         # >    "Content-Type"
29         # >       "application/json; charset=utf-8"
30         # >    "cache-control"
31         # >       "no-cache"
32
33         if body:
34             try:
35                 body = json.loads(body)
36             except:
37                 raise error.UnknownErrorException("Failed to decode body as json:\n%s" % body)
38
39         return cls(status, body)
40
41
42 class ToJsonEncoder(json.JSONEncoder):
43     def default(self, obj):
44         return getattr(obj.__class__, "json", json.JSONEncoder().default)(obj)
45
46
47 class HTTPWireProtocol(object):
48     """Transports messages (commands and responses) over the WebDriver
49     wire protocol.
50     """
51
52     def __init__(self, host, port, url_prefix="/", timeout=None):
53         """Construct interface for communicating with the remote server.
54
55         :param url: URL of remote WebDriver server.
56         :param wait: Duration to wait for remote to appear.
57         """
58
59         self.host = host
60         self.port = port
61         self.url_prefix = url_prefix
62
63         self._timeout = timeout
64
65     def url(self, suffix):
66         return urlparse.urljoin(self.url_prefix, suffix)
67
68     def send(self, method, uri, body=None, headers=None):
69         """Send a command to the remote.
70
71         :param method: `GET`, `POST`, or `DELETE`.
72         :param uri: Relative endpoint of the requests URL path.
73         :param body: Body of the request.  Defaults to an empty
74             dictionary if ``method`` is `POST`.
75         :param headers: Additional headers to include in the request.
76
77         :return: Instance of ``wdclient.Response`` describing the
78             HTTP response received from the remote end.
79
80         """
81         if body is None and method == "POST":
82             body = {}
83
84         if isinstance(body, dict):
85             body = json.dumps(body, cls=ToJsonEncoder)
86
87         if isinstance(body, unicode):
88             body = body.encode("utf-8")
89
90         if headers is None:
91             headers = {}
92
93         url = self.url(uri)
94
95         kwargs = {}
96         if self._timeout is not None:
97             kwargs["timeout"] = self._timeout
98
99         conn = httplib.HTTPConnection(
100             self.host, self.port, strict=True, **kwargs)
101         conn.request(method, url, body, headers)
102
103         try:
104             response = conn.getresponse()
105             return Response.from_http_response(response)
106         finally:
107             conn.close()