Skip to content

Commit d816e90

Browse files
committed
Add HTTPS support
Thanks to Pasi Eronen for figuring out the hard part! Closes peritus#9 and closes peritus#7.
1 parent db975cf commit d816e90

14 files changed

+132
-29
lines changed

src/HttpLibrary/__init__.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,15 @@ class HTTP:
3434
ROBOT_LIBRARY_VERSION = "0.3.2"
3535

3636
class Context(object):
37-
def __init__(self, http, host=None):
37+
def __init__(self, http, host=None, scheme='http'):
3838
# daddy
3939
self._http = http
4040
self._host = host
41+
self._scheme = scheme
4142

4243
# the livetest app
4344
if host:
44-
self.app = livetest.TestApp(host)
45+
self.app = livetest.TestApp(host, scheme=scheme)
4546
else:
4647
self.app = None
4748

@@ -135,7 +136,7 @@ def _path_from_url_or_path(self, url_or_path):
135136

136137
elif url_or_path.startswith("http"):
137138
parsed_url = urlparse(url_or_path)
138-
self.set_http_host(parsed_url.netloc)
139+
self.create_http_context(parsed_url.netloc, parsed_url.scheme)
139140
return parsed_url.path
140141

141142
raise Exception('"%s" needs to be in form of "/path" or "http://host/path"'
@@ -149,17 +150,22 @@ def set_http_host(self, host):
149150
"""
150151
self.create_http_context(host)
151152

152-
def create_http_context(self, host=None):
153+
def create_http_context(self, host=None, scheme='http'):
153154
"""
154155
Sets the HTTP host to use for future requests. You must call this
155156
before issuing any HTTP requests.
156157
157158
`host` is the name of the host, optionally with port (e.g. 'google.com' or 'localhost:5984')
159+
`scheme` the protocol scheme to use. Valid values are 'http', 'https'
158160
"""
161+
162+
assert scheme in ('http', 'https'), "`scheme` parameter must be 'http' or 'https'"
163+
159164
if host == None:
160165
host = self.context.app.host
161166
logger.info("Host for next HTTP request set to '%s'" % host)
162-
self._contexts.append(HTTP.Context(self, host))
167+
logger.info("Scheme for next HTTP request set to '%s'" % scheme)
168+
self._contexts.append(HTTP.Context(self, host, scheme))
163169

164170
def restore_http_context(self):
165171
"""
@@ -180,7 +186,7 @@ def http_request(self, verb, url):
180186
path = self._path_from_url_or_path(url)
181187

182188
self.context.pre_process_request()
183-
logger.debug("Performing %s request on http://%s%s" % (verb, self.app.host, url,))
189+
logger.debug("Performing %s request on %s://%s%s" % (verb, self.context._scheme, self.app.host, path,))
184190
self.context.post_process_request(
185191
self.context.app.request(path, {}, self.context.request_headers,
186192
method=verb.upper(),)
@@ -194,7 +200,7 @@ def HEAD(self, url):
194200
"""
195201
path = self._path_from_url_or_path(url)
196202
self.context.pre_process_request()
197-
logger.debug("Performing HEAD request on http://%s%s" % (self.app.host, url,))
203+
logger.debug("Performing HEAD request on %s://%s%s" % (self.context._scheme, self.app.host, path,))
198204
self.context.post_process_request(
199205
self.app.head(path, self.context.request_headers)
200206
)
@@ -207,7 +213,7 @@ def GET(self, url):
207213
"""
208214
path = self._path_from_url_or_path(url)
209215
self.context.pre_process_request()
210-
logger.debug("Performing GET request on http://%s%s" % (self.app.host, url))
216+
logger.debug("Performing GET request on %s://%s%s" % (self.context._scheme, self.app.host, path))
211217
self.context.post_process_request(
212218
self.app.get(path, {}, self.context.request_headers)
213219
)
@@ -222,7 +228,7 @@ def POST(self, url):
222228
kwargs = {}
223229
if 'Content-Type' in self.context.request_headers:
224230
kwargs['content_type'] = self.context.request_headers['Content-Type']
225-
logger.debug("Performing POST request on http://%s%s" % (self.app.host, url))
231+
logger.debug("Performing POST request on %s://%s%s" % (self.context._scheme, self.app.host, url))
226232
self.context.pre_process_request()
227233
self.context.post_process_request(
228234
self.app.post(path, self.context.request_body or {}, self.context.request_headers, **kwargs)
@@ -239,7 +245,7 @@ def PUT(self, url):
239245
if 'Content-Type' in self.context.request_headers:
240246
kwargs['content_type'] = self.context.request_headers['Content-Type']
241247
self.context.pre_process_request()
242-
logger.debug("Performing PUT request on http://%s%s" % (self.app.host, url))
248+
logger.debug("Performing PUT request on %s://%s%s" % (self.context._scheme, self.app.host, url))
243249
self.context.post_process_request(
244250
self.app.put(path, self.context.request_body or {}, self.context.request_headers, **kwargs)
245251
)
@@ -252,7 +258,7 @@ def DELETE(self, url):
252258
"""
253259
path = self._path_from_url_or_path(url)
254260
self.context.pre_process_request()
255-
logger.debug("Performing DELETE request on %s" % url)
261+
logger.debug("Performing DELETE request on %s://%s%s" % (self.context._scheme, self.app.host, url))
256262
self.context.post_process_request(
257263
self.app.delete(path, {}, self.context.request_headers)
258264
)

src/HttpLibrary/livetest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ def __init__(self, host, scheme='http', relative_to=None):
6060
self.relative_to = relative_to
6161
self.conn = {}
6262
self._load_conn(scheme)
63-
self.extra_environ = {}
63+
self.extra_environ = {
64+
'wsgi.url_scheme': scheme,
65+
}
6466
self.reset()
6567

6668
def _do_httplib_request(self, req):

tests/http/__init__.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
Library HttpLibrary.HTTP
44
Library OperatingSystem
55

6-
Resource ../variables.txt
6+
Resource variables.txt
77

88
Suite Setup Start Mockserver
99
Suite Teardown Stop Mockserver
1010

1111
*** Keywords ***
1212

1313
Start Mockserver
14-
Start Process tests/http/mockserver.py
15-
Sleep 0.2
14+
Start Process tests/http/mockserver.py ${PORT}
15+
Sleep 1
1616

1717
Stop Mockserver
18-
Create HTTP Context ${HOST}
19-
POST /kill
18+
POST http://${HOST}/kill
19+
Sleep 1
2020

tests/http/mockserver.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#!/usr/bin/env python
22

33
import BaseHTTPServer
4-
from sys import exit
4+
import sys
5+
import os
6+
import ssl
57

68
class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
79

@@ -96,13 +98,28 @@ def do_POST(self, *args, **kwargs):
9698
global server
9799
self.send_response(201, "Killing myself")
98100
server.socket.close()
99-
exit(0)
101+
sys.exit(0)
100102
else:
101103
self.send_error(500)
102104

103105
do_PUT = do_POST
104106

105-
print 'Starting server on http://localhost:36503/'
107+
PORT = int(sys.argv[1])
108+
server = BaseHTTPServer.HTTPServer(('localhost', PORT), WebRequestHandler)
109+
scheme = 'http'
110+
111+
if '--ssl' in sys.argv:
112+
scheme = 'https'
113+
114+
cert = os.path.abspath(os.path.join(os.path.dirname(__file__), 'rfhttplibmockserver.pem'))
115+
116+
server.socket = ssl.wrap_socket(
117+
server.socket,
118+
certfile=cert,
119+
keyfile=cert,
120+
server_side=True,
121+
)
122+
123+
print 'Starting server on %s://localhost:%d/' % (scheme, PORT)
106124

107-
server = BaseHTTPServer.HTTPServer(('localhost', 36503), WebRequestHandler)
108125
server.serve_forever()

tests/http/rfhttplibmockserver.pem

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIICXAIBAAKBgQDiTHYDS4NP84Dn6EeU0s7xqnRtO+JTyW/xV485B5KaEFfeheLD
3+
v6MAr1T0fg4aLo3R0PzLx0IMLsFuWIdm5+J5IaMcW8rbvWsLM8Ayh9TT7FR0aNiQ
4+
kGs6A0oDmYUa5FSC2j61Q2mVfoUokQcaWpmEEZMq2uBR3/P1jsEMU16erQIDAQAB
5+
AoGAWPdgafk0/aiopAOQqLScASxXK16govoNlV8sAmq0uvbz5JrURMrBZZKInro0
6+
Bx0ISlWUHPUQRUPYbe5GBTHiuak3vneTytTW7pvWw7E/fZrc+5UF/AHPAgIBdaK/
7+
Gwtafn63c2V/T0GFcI9ZUtMCmvCaBL0OWeIuQVjBSNEB7S0CQQDz9OB2CbUVLIiW
8+
MHMRIZsBfdLF/N6QtHuDwUL+51NxYSsNumcyI5j4xAsCBplWwOFNs91x/7LEHh6h
9+
wNpSTlLbAkEA7Xhsh+MMZm5ElmnyPH5Ql1nDAtBl14C77LSz4kbrx7+lzdQy6bsu
10+
+p08ZFkZ6ABcOkoZwwaHHjfzsLaIzUKXFwJAKRSnZ7kiwToKlh/6gHwEOjAR+j0m
11+
zX9W/UziF0KlDoaqVVl6XzsXW2zH3cN2tuEsD4WmWLgSRmw8BEkReqKt2QJAE882
12+
5oMHNsg+CnoeDfPPj0CapvJxfG+tvYo5c0fNRWV0VF4+PQczXQ6eyhQwuAzHpMkn
13+
qwAxZ1DtkDE56j2C0wJBANJ9sX6bB0q5zBrnJdn9t7ymnjvMoFijyWwjJ7B14CYS
14+
+kM1yw959G7/TVwC2PZ1PDes8lRTFgVx8644JZaLyxA=
15+
-----END RSA PRIVATE KEY-----
16+
-----BEGIN CERTIFICATE-----
17+
MIIC7zCCAligAwIBAgIJAMt0Xej2hG00MA0GCSqGSIb3DQEBBQUAMFkxCzAJBgNV
18+
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
19+
aWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xMjEwMTQwODM0
20+
MDVaFw0yMjEwMTIwODM0MDVaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21l
21+
LVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNV
22+
BAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4kx2A0uD
23+
T/OA5+hHlNLO8ap0bTviU8lv8VePOQeSmhBX3oXiw7+jAK9U9H4OGi6N0dD8y8dC
24+
DC7BbliHZufieSGjHFvK271rCzPAMofU0+xUdGjYkJBrOgNKA5mFGuRUgto+tUNp
25+
lX6FKJEHGlqZhBGTKtrgUd/z9Y7BDFNenq0CAwEAAaOBvjCBuzAdBgNVHQ4EFgQU
26+
WG/vc+TsT7+l/IWVfRFK6m7jw3MwgYsGA1UdIwSBgzCBgIAUWG/vc+TsT7+l/IWV
27+
fRFK6m7jw3OhXaRbMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRl
28+
MSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxv
29+
Y2FsaG9zdIIJAMt0Xej2hG00MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
30+
gYEAS6Hon/dpLAFJDjOFZQQGQ7YC28XbS0p1q1Gz/utlnZ3xP9AXdyyLfltKo/rk
31+
OGTvCEbY1mWYI6XgldZZvS1Zo2m/oI8Gp5yYaLeaIQMgGXJ3GX6HDIKmZHUgPCVB
32+
Bihfc7mq9I+bCu8u6fHf67bunayIpK9ZijdEHFqJiZX39vo=
33+
-----END CERTIFICATE-----

tests/http/scoping/keyword_new_context.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*** Settings ***
22

3-
Resource ../../variables.txt
3+
Resource ../variables.txt
44
Library HttpLibrary.HTTP
55

66
*** Keywords ***

tests/http/scoping/simplescope.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*** Settings ***
22

3-
Resource ../../variables.txt
3+
Resource ../variables.txt
44
Library HttpLibrary.HTTP
55
Suite Setup Create HTTP Context ${HOST}
66

tests/http/scoping/suite_setup.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*** Settings ***
22

3-
Resource ../../variables.txt
3+
Resource ../variables.txt
44
Library HttpLibrary.HTTP
55
Suite Setup Create HTTP Context ${HOST}
66

tests/http/simple.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*** Settings ***
22

3-
Resource ../variables.txt
3+
Resource variables.txt
44
Library HttpLibrary.HTTP
55
Test Setup Create HTTP Context ${HOST}
66

tests/http/variables.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*** Variables ***
2+
3+
${PORT} 36503
4+
${HOST} localhost:${PORT}

tests/https/__init__.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
*** Settings ***
2+
3+
Library HttpLibrary.HTTP
4+
Library OperatingSystem
5+
6+
Resource variables.txt
7+
8+
Suite Setup Start Secure Mockserver
9+
Suite Teardown Stop Secure Mockserver
10+
11+
*** Keywords ***
12+
13+
Start Secure Mockserver
14+
Start Process tests/http/mockserver.py ${PORT} --ssl
15+
Sleep 1
16+
17+
Stop Secure Mockserver
18+
POST https://${HOST}/kill
19+
Sleep 1
20+

tests/https/simple.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
*** Settings ***
2+
3+
Resource variables.txt
4+
Library HttpLibrary.HTTP
5+
Test Setup Create HTTP Context ${HOST} https
6+
7+
*** Test Cases ***
8+
9+
Simple GET on self-signed Mockserver
10+
GET /200
11+
12+
Full-URL GET with full url on self-signed mock server
13+
GET https://${HOST}/200
14+
15+
Full-URL GET to https://encrypted.google.com/
16+
GET https://encrypted.google.com/
17+
18+
Simple GET to https://encrypted.google.com/
19+
Create HTTP Context encrypted.google.com https
20+
GET /
21+

tests/https/variables.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*** Variables ***
2+
3+
${PORT} 36504
4+
${HOST} localhost:${PORT}

tests/variables.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +0,0 @@
1-
*** Variables ***
2-
3-
${HOST} localhost:36503
4-

0 commit comments

Comments
 (0)