Permalink
Browse files

Merge pull request #4 from jeromegn/https

Added HTTPS support
  • Loading branch information...
2 parents b5a278c + b0f2dd0 commit 237bab921f247c9ec58430c238680155c4bc143b @assaf committed May 2, 2012
View
@@ -1,5 +1,6 @@
DNS = require("dns")
HTTP = require("http")
+HTTPS = require("https")
ProxyRequest = require("./proxy")
Replay = require("./replay")
@@ -20,6 +21,12 @@ HTTP.request = (options, callback)->
return request
+# Route HTTPS requests
+HTTPS.request = (options, callback)->
+ options.protocol = "https:"
+ return HTTP.request(options, callback)
+
+
# Redirect HTTP requests to 127.0.0.1 for all hosts defined as localhost
original_lookup = DNS.lookup
DNS.lookup = (domain, family, callback)->
@@ -1,7 +1,9 @@
HTTP = require("http")
+HTTPS = require("https")
# Capture original HTTP request. PassThrough proxy uses that.
-httpRequest = HTTP.request
+httpRequest = HTTP.request
+httpsRequest = HTTPS.request
passThrough = (allow)->
if arguments.length == 0
@@ -14,12 +16,17 @@ passThrough = (allow)->
return (request, callback)->
if allow(request)
options =
+ protocol: request.url.protocol
hostname: request.url.hostname
port: request.url.port
path: request.url.path
method: request.method
headers: request.headers
- http = httpRequest(options)
+
+ if request.url.protocol == "https:"
+ http = httpsRequest(options)
+ else
+ http = httpRequest(options)
http.on "error", (error)->
callback error
http.on "response", (response)->
View
@@ -34,7 +34,7 @@ class ProxyRequest extends HTTP.ClientRequest
constructor: (options = {}, @proxy)->
@method = (options.method || "GET").toUpperCase()
[host, port] = (options.host || options.hostname).split(":")
- @url = URL.parse("http://#{host || "localhost"}:#{options.port || port || 80}#{options.path || "/"}")
+ @url = URL.parse("#{options.protocol || "http:"}//#{host || "localhost"}:#{options.port || port || 80}#{options.path || "/"}")
@headers = {}
if options.headers
for n,v of options.headers
View
@@ -19,7 +19,8 @@
},
"devDependencies": {
"express": "~2.5.9",
- "mocha": "~1.0.2"
+ "mocha": "~1.0.2",
+ "async": "~0.1.18"
},
"repository": {
"type": "git",
@@ -0,0 +1 @@
+GET /minimal
View
@@ -2,11 +2,14 @@
# All requests using a hostname are routed to 127.0.0.1
# Port 3001 has a live server, see below for paths and responses
# Port 3002 has no server, connections will be refused
+# Port 3443 has a live https server
-DNS = require("dns")
+DNS = require("dns")
Express = require("express")
-Replay = require("../lib/replay")
+Replay = require("../lib/replay")
+File = require("fs")
+Async = require("async")
# Directory to load fixtures from.
@@ -21,6 +24,7 @@ DNS.lookup = (domain, callback)->
else
original_lookup domain, callback
+
# Serve pages from localhost.
server = Express.createServer()
server.use Express.bodyParser()
@@ -35,9 +39,32 @@ server.get "/500", (req, res)->
res.send 500, "Boom!"
+# SSL Server
+ssl_server = Express.createServer(
+ key: File.readFileSync("#{__dirname}/ssl/privatekey.pem")
+ cert: File.readFileSync("#{__dirname}/ssl/certificate.pem")
+)
+ssl_server.use Express.bodyParser()
+# Success page.
+ssl_server.get "/", (req, res)->
+ res.send "Success!"
+# Not found
+ssl_server.get "/404", (req, res)->
+ res.send 404, "Not found"
+# Internal error
+ssl_server.get "/500", (req, res)->
+ res.send 500, "Boom!"
+
+
# Setup environment for running tests.
setup = (callback)->
- server.listen 3001, callback
+ Async.parallel [
+ (done)->
+ server.listen 3001, done
+ (done)->
+ ssl_server.listen 3443, done
+ ], callback
+
return
if server._connected
@@ -53,4 +80,5 @@ setup = (callback)->
exports.assert = require("assert")
exports.setup = setup
exports.HTTP = require("http")
+exports.HTTPS = require("https")
exports.Replay = Replay
@@ -1,4 +1,4 @@
-{ assert, setup, HTTP, Replay } = require("./helpers")
+{ assert, setup, HTTP, HTTPS, Replay } = require("./helpers")
# First batch is testing requests that pass through to the server, no recording/replay.
@@ -63,6 +63,33 @@ describe "Pass through", ->
assert.deepEqual response.body, "Success!"
+ describe "ssl", ->
+ before ->
+ Replay.mode = "bloody"
+
+ response = null
+
+ before (done)->
+ request = HTTPS.get(hostname: "pass-through", port: 3443, (_)->
+ response = _
+ response.body = ""
+ response.on "data", (chunk)->
+ response.body += chunk
+ response.on "end", done
+ )
+ request.on "error", done
+
+ it "should return HTTP version", ->
+ assert.equal response.httpVersion, "1.1"
+ it "should return status code", ->
+ assert.equal response.statusCode, 200
+ it "should return response headers", ->
+ assert.equal response.headers["content-type"], "text/html; charset=utf-8"
+ it "should return response trailers", ->
+ assert.deepEqual response.trailers, { }
+ it "should return response body", ->
+ assert.deepEqual response.body, "Success!"
+
# Send request to the live server on port 3001, but this time network connection disabled.
describe "replay", ->
before ->
View
@@ -1,4 +1,4 @@
-{ assert, HTTP, Replay } = require("./helpers")
+{ assert, HTTP, HTTPS, Replay } = require("./helpers")
# Test replaying results from fixtures in spec/fixtures.
@@ -50,6 +50,24 @@ describe "Replay", ->
assert.deepEqual response.trailers, { }
+ describe "matching an https url", ->
+ response = null
+
+ before (done)->
+ Replay.mode = "replay"
+
+ request = HTTPS.get(hostname: "example.com", port: 3443, path: "/minimal")
+ request.on "response", (_)->
+ response = _
+ done()
+ request.on "error", done
+
+ it "should return HTTP version", ->
+ assert.equal response.httpVersion, "1.1"
+ it "should return status code", ->
+ assert.equal response.statusCode, 200
+
+
describe "matching a regexp", ->
body = null
View
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIICATCCAWoCCQDwtkmH/OpeXzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
+VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMB4XDTEyMDUwMjE2MzA0N1oXDTEyMDYwMTE2MzA0N1owRTELMAkG
+A1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0
+IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzrQa
++3uX+75buOq2zXl8vgOn8DYtZCK1jm6kC17Qak3iHIkzUXSfYRlEWAzJsECjDWaL
+6KCh5/B5XsdatIfpVb7SoeAK1Cs5ONTWNSvMTnDToJEJ3nY/cdcg3Nlrld2LkAt6
+W7Jh2NZC29e7+t1ro6w5Ok88dkYZul5Qn9Lc6isCAwEAATANBgkqhkiG9w0BAQUF
+AAOBgQC5cmtHh6M7rByX3Gm5cMrtM+Gbfg25VP9BOgCCj+DjwY4gStcuhtU4sxZX
+7IsoLMi22uiqP9/NSOReVB1gOkWMA5mkqACLerQqFmedXCjiCwgZ5F4G2UVpkXn7
+6QYThFtX1umpWcZwtb2n6NatmCcHMfPVAZFxmI/V5kl7lT6sNw==
+-----END CERTIFICATE-----
View
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDOtBr7e5f7vlu46rbNeXy+A6fwNi1kIrWObqQLXtBqTeIciTNR
+dJ9hGURYDMmwQKMNZovooKHn8Hlex1q0h+lVvtKh4ArUKzk41NY1K8xOcNOgkQne
+dj9x1yDc2WuV3YuQC3pbsmHY1kLb17v63WujrDk6Tzx2Rhm6XlCf0tzqKwIDAQAB
+AoGBAKFclkfF9yKOOxpDGMuU0F2hiwOJt6uZMPRsyOEbdkXWYPJ35Ljs+tKZH/JA
+oV5XRzJZ4FSMuXfQEV987wFJrEtcQH4GaH+ZUGmoeCmYs1Gal3Pumexvbn5ffduu
+HiFkoGhFUQuVGuBE1W7yOk/EmJQZlOBqQCuSW5rxzJGvwu55AkEA+pUgJsdSDMwk
+KVNWb2UvDOYwJMa1PP7q32+P8o2S092zGm9HxPhYUhBdx8OqGfKbOUQTPlMOK9f4
+6ECD1stgLwJBANMsIIpHwah/B5DJaJEOI2iqc1RwntdpsxYTFsptMDkzi576q7y+
+JQXtc3DkfEMc/9oJSG+Tb+LHWdhhWADy+sUCQBU7Z4MBpokhDvtVbWB48VildHTZ
+RWgKrXoLKOZDaqp7AX7+6NTeuhUR//A6OwKB1PcwNnU0cmHypcuAE+uyRc8CQCD6
+pD5URIdHB2xyN/Vnato+vHI0gGoN5N0OsCF++egFB8oVRdrdKzUIx12bIVjt33sy
+tfBO60tUbNChKzhCui0CQQC+8dx4GlJ/AR/51b5zLIQ+XDcfj0SbHAEn/cdrNJb2
+x1LSckVayPvaVslesPzicC8cHfFqD3i8GSt6wRs7/fI8
+-----END RSA PRIVATE KEY-----

0 comments on commit 237bab9

Please sign in to comment.