Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added HTTPS support #4

Merged
merged 1 commit into from

2 participants

@jeromegn

No description provided.

@assaf assaf merged commit 237bab9 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 2, 2012
  1. @jeromegn

    Added HTTPS

    jeromegn authored
This page is out of date. Refresh to see the latest.
View
7 lib/replay/index.coffee
@@ -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)->
View
11 lib/replay/pass_through.coffee
@@ -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
2  lib/replay/proxy.coffee
@@ -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
3  package.json
@@ -19,7 +19,8 @@
},
"devDependencies": {
"express": "~2.5.9",
- "mocha": "~1.0.2"
+ "mocha": "~1.0.2",
+ "async": "~0.1.18"
},
"repository": {
"type": "git",
View
1  test/fixtures/example.com:3443/minimal
@@ -0,0 +1 @@
+GET /minimal
View
34 test/helpers.coffee
@@ -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
View
29 test/pass_through_test.coffee
@@ -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
20 test/replay_test.coffee
@@ -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
13 test/ssl/certificate.pem
@@ -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
15 test/ssl/privatekey.pem
@@ -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-----
Something went wrong with that request. Please try again.