Skip to content

Commit

Permalink
First alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Percival committed Jun 17, 2011
1 parent 309e634 commit 9724dd4
Show file tree
Hide file tree
Showing 18 changed files with 313 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/docs
/node_modules
36 changes: 36 additions & 0 deletions Cakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
fs = require 'fs'
{print} = require 'sys'
{spawn, exec} = require 'child_process'

build = (watch, callback) ->
if typeof watch is 'function'
callback = watch
watch = false
options = ['-c', '-o', 'lib', 'src']
options.unshift '-w' if watch

coffee = spawn 'coffee', options
coffee.stdout.on 'data', (data) -> print data.toString()
coffee.stderr.on 'data', (data) -> print data.toString()
coffee.on 'exit', (status) -> callback?() if status is 0

task 'docs', 'Generate annotated source code with Docco', ->
fs.readdir 'src', (err, contents) ->
files = ("src/#{file}" for file in contents when /\.coffee$/.test file)
docco = spawn 'docco', files
docco.stdout.on 'data', (data) -> print data.toString()
docco.stderr.on 'data', (data) -> print data.toString()
docco.on 'exit', (status) -> callback?() if status is 0

task 'build', 'Compile CoffeeScript source files', ->
build()

task 'watch', 'Recompile CoffeeScript source files when modified', ->
build true

task 'test', 'Run the test suite', ->
build ->
require.paths.unshift __dirname + "/lib"
{reporters} = require 'nodeunit'
process.chdir __dirname
reporters.default.run ['test']
20 changes: 20 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2011 Mark Percival

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
This is a Node.js project template written in CoffeeScript. It's set
up with a Cakefile for building files in `src/` to `lib/` and running
tests with nodeunit. There's also a `docs` task that generates Docco
documentation from the source in `src/`.

Released under the MIT license.

Sam Stephenson <<sstephenson@gmail.com>>
19 changes: 19 additions & 0 deletions certs/ca.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDKjCCApOgAwIBAgIJAM4bl1pmvC0tMA0GCSqGSIb3DQEBBQUAMGwxCzAJBgNV
BAYTAlVTMQswCQYDVQQIEwJDQTELMAkGA1UEBxMCU0YxFTATBgNVBAoTDE1pZGRs
ZUZpZGRsZTENMAsGA1UECxMEU1RGVTEdMBsGA1UEAxMUbWlkZGxlZmlkZGxlLmlu
Zm8gQ0EwIBcNMTEwNTA4MjMyMTA3WhgPMjExMTA0MTQyMzIxMDdaMGwxCzAJBgNV
BAYTAlVTMQswCQYDVQQIEwJDQTELMAkGA1UEBxMCU0YxFTATBgNVBAoTDE1pZGRs
ZUZpZGRsZTENMAsGA1UECxMEU1RGVTEdMBsGA1UEAxMUbWlkZGxlZmlkZGxlLmlu
Zm8gQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMRZrJlUN5sNNm1YAkLo
Ad2UjVA0RC4vYHftxtBaHtNndDlGWyRrf4dtBYPRA0bdecHReH6k4AWyHpsvyRIq
bodyX1JexnAsPT1uz0VKxdOsEvxB8XFMH6BQpjJf6FeA3SGjU5WjIS2tTMmFCx1+
v3aesWPB8xalqpd//Bqz6zo9AgMBAAGjgdEwgc4wHQYDVR0OBBYEFE5uaCugHulo
EakX6x6swJQjVkGeMIGeBgNVHSMEgZYwgZOAFE5uaCugHuloEakX6x6swJQjVkGe
oXCkbjBsMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMRUw
EwYDVQQKEwxNaWRkbGVGaWRkbGUxDTALBgNVBAsTBFNURlUxHTAbBgNVBAMTFG1p
ZGRsZWZpZGRsZS5pbmZvIENBggkAzhuXWma8LS0wDAYDVR0TBAUwAwEB/zANBgkq
hkiG9w0BAQUFAAOBgQBdcV+zVbtwVSIyYyzD/qAkQhuHyqS2qDFuNhKbPRqJ1QZc
yzV/gDlXvymyp5d3T/+MYDIYe9KOYyiaYS8rYFFn6zQrPco23ttp1CgDeY4K96X8
DKKUDc3pN38f/crkKiioZndHUmkUKL2BgRhmXmFnNtx0FGwor34U96E2wIBEdQ==
-----END CERTIFICATE-----
15 changes: 15 additions & 0 deletions certs/ca.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDEWayZVDebDTZtWAJC6AHdlI1QNEQuL2B37cbQWh7TZ3Q5Rlsk
a3+HbQWD0QNG3XnB0Xh+pOAFsh6bL8kSKm6Hcl9SXsZwLD09bs9FSsXTrBL8QfFx
TB+gUKYyX+hXgN0ho1OVoyEtrUzJhQsdfr92nrFjwfMWpaqXf/was+s6PQIDAQAB
AoGBAJxYKy8L+BrmMmhuo55Szul41+z9MSz1XIMiOiS9Hb6HqevRMdGWJz3WeYW0
cD+FKuZBvQhakGb4pZY8PobQcqDPpkB117CIZevCsrH9c07NMg/XaCUl4KbtVzEl
rQP5+l2rzM0STfSXIcJ5zV7KQucxl9eZG6fbpufI83jUNu6hAkEA/UEg5oj5ZF6a
bBADk/HYXGaPdgNvdNvKy3M6tZxWo3fqIk8lRM9ISJ/URMxR1mAkDF79tq1bOJCQ
Z33jSt4NcwJBAMZ6nc6ehtTyMzJSDVIE3GwfWd95Yr+SQ0LiDNWD9a9KLZ9/yLcK
KQcpPcyCpgXY8B8FyPpXbV6qUUVVvs9JrY8CQGnhuOepjNsx0k4rw9Mu4c5/8qrc
dNTer8KvwnP7kR13HSSLAoHqR8ZVTGIXKn/+YhPqAxlFEUZs6nLaZxT+EZECQQCJ
24Dgkpt0LQYCXZuC7H1tXBlAbz93cE/nlLr1UsLDDfLCZi8zc4srvil+cwB970BZ
S9tchn0g04u/bN8rezFhAkBd8G9kcaBf/bIZ5J42hFb6Qc2bLEjfig945X0zWZ/4
j701X+zYMrpiZOT/fLjbRK52LRI0BUZhBLtAFgm5SX1X
-----END RSA PRIVATE KEY-----
11 changes: 11 additions & 0 deletions certs/certgen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

openssl genrsa -out ca.key 1024
openssl req -new -x509 -days 36500 -key ca.key -out ca.crt -subj "/C=US/ST=CA/L=SF/O=MiddleFiddle/OU=STFU/CN=middlefiddle.info CA"

# Setup the server key
openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr -subj "/C=US/ST=CA/L=SF/O=MiddleFiddle/OU=STFU/CN=*.middlefiddle.info CA"

# Sign with the CA
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
15 changes: 15 additions & 0 deletions certs/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICSTCCAbICAQEwDQYJKoZIhvcNAQEFBQAwbDELMAkGA1UEBhMCVVMxCzAJBgNV
BAgTAkNBMQswCQYDVQQHEwJTRjEVMBMGA1UEChMMTWlkZGxlRmlkZGxlMQ0wCwYD
VQQLEwRTVEZVMR0wGwYDVQQDExRtaWRkbGVmaWRkbGUuaW5mbyBDQTAeFw0xMTA1
MDgyMzIxMDdaFw0xMjA1MDcyMzIxMDdaMG4xCzAJBgNVBAYTAlVTMQswCQYDVQQI
EwJDQTELMAkGA1UEBxMCU0YxFTATBgNVBAoTDE1pZGRsZUZpZGRsZTENMAsGA1UE
CxMEU1RGVTEfMB0GA1UEAxQWKi5taWRkbGVmaWRkbGUuaW5mbyBDQTCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAzV8VhvKUo/VkmMnxiann5Phv98z6NawRQt3Y
gbNJwuRIMD8BHLKAmtLyznzYPeG0kcnd3Cj/bTt7nxqOfDSqx2nTx1qz13jvZ+wB
MMqS2FLnzRN19+icDT7nUgR3gGzpugB9ARkfLuONLj6wGW9lPoaAfBbci4+Z+mVL
cm5qMbkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQA09AQ/A+mOPbr6IND9pmZ/xC8x
BhlCbJPqlyUyCdw0JeDKzdURI3FQIb5JGGtvaiOCn40LzzVaKTqLntaj9uT2/wfV
NNrAXqNcUHyHvCQ3ro4F9umv2Lg04iTQViceQ/qqs6XCWTri82a9LqqxcrRouHkw
3jRWIKS7QYHNPeJsDw==
-----END CERTIFICATE-----
12 changes: 12 additions & 0 deletions certs/server.csr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBrjCCARcCAQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQswCQYDVQQH
EwJTRjEVMBMGA1UEChMMTWlkZGxlRmlkZGxlMQ0wCwYDVQQLEwRTVEZVMR8wHQYD
VQQDFBYqLm1pZGRsZWZpZGRsZS5pbmZvIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQDNXxWG8pSj9WSYyfGJqefk+G/3zPo1rBFC3diBs0nC5EgwPwEcsoCa
0vLOfNg94bSRyd3cKP9tO3ufGo58NKrHadPHWrPXeO9n7AEwypLYUufNE3X36JwN
PudSBHeAbOm6AH0BGR8u440uPrAZb2U+hoB8FtyLj5n6ZUtybmoxuQIDAQABoAAw
DQYJKoZIhvcNAQEFBQADgYEAdIesDgKcJAl/mCePpIGj+eN0T9ca4koNoohWfSdg
lowBwW07RDN2FdVIjlNHnMs6Eg1CBuGhgEaWCHLm8EeZSk3YL+9HUYY+gLfKwsxx
UpAAPTAnFLyw+EDRDA0e5VaObiqHaUoZmUHM7EwIzv93lmDTwbT5YatbGuLreFES
4MI=
-----END CERTIFICATE REQUEST-----
15 changes: 15 additions & 0 deletions certs/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDNXxWG8pSj9WSYyfGJqefk+G/3zPo1rBFC3diBs0nC5EgwPwEc
soCa0vLOfNg94bSRyd3cKP9tO3ufGo58NKrHadPHWrPXeO9n7AEwypLYUufNE3X3
6JwNPudSBHeAbOm6AH0BGR8u440uPrAZb2U+hoB8FtyLj5n6ZUtybmoxuQIDAQAB
AoGAfWzZv939C5l+A5YpzrKWro9QCp4EHa1lqVnFtYiivsUelWCVNEqMIoI8ygET
K8/hsLwBpEjhnnuah1P3u0GLHj87Y0+x9bjsUAQcrNkcV+xxNTvHMzRQ27KfJ0Fk
s2f2wbni/vsVbxhdc4d4XlbxEEb07YpVat9GcholHFFE9IECQQD9U4vo9MEwT9VQ
+ZcMUVj4+NrLOeFV1HMrqnJDeWHfawbrDTi+K/sexKIwC+AOmPB3a4tr3jXhH4Gr
GqL1cNhRAkEAz4n4R4SutsZqflh4zHq1oQ//I2Jzlk2xp3WvImXMwaJTx3idyhPx
NO8NPN22bkc8FGH9VJIrqw30YKBG6lxQ6QJBALa+h0Z1Ecw1OxAgDRvgrwtkEgna
5jgRe0e7vJP6Q2V1gtcbgZyGg7BNbyaz2l0NbSLo3PniogGVxefV3kqqrhECQC4Y
Wsins5Zs42JEjC/+YTDwuJ5HU5zijL7A6LEfIycuwqTfKUykuUIkhjAqnkZIFBQC
351VCdXoN4rujlGnR2ECQHZn4FN4z/Wirb1xEB53MM09RMbyltA/MysSgqYPHCgX
lp+qER+Af4WU+UchySclPfKrn92vXRauOBc19z06wYc=
-----END RSA PRIVATE KEY-----
11 changes: 11 additions & 0 deletions example/host_fucker.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Mf = require '../lib/index'

hostFucker = (origHost,host) ->
(req, res, next) ->
if origHost == req.headers['host']
req.realHost = origHost
req.headers['host'] = host
return next()


Mf.createProxy(Mf.logger()).listen(8080).listenHTTPS(8081)
24 changes: 24 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{ "name": "MiddleFiddle"
, "description": "Fiddle and log all your outbound HTTP/HTTPS requests"
, "author": "Mark Percival"
, "version": "0.1.0"
, "licenses": [
{ "type": "MIT"
, "url": "https://github.com/mdp/middlefiddle/raw/master/LICENSE"
}]
, "repository":
{ "type": "git"
, "url": "https://github.com/mdp/middlefiddle.git"
}
, "main": "./lib/index.js"
, "dependencies":
{
}
, "devDependencies":
{ "nodeunit": ">=0.5.0"
, "coffee-script": ">=1.1.1"
}
, "engines":
{ "node": "~0.4"
}
}
11 changes: 11 additions & 0 deletions src/http_server.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fs = require "fs"
sys = require "sys"
connect = require "connect"


{version} = JSON.parse fs.readFileSync __dirname + "/../package.json", "utf8"

# `HttpServer` is a subclass of
# [Connect](http://senchalabs.github.com/connect/)'s `HTTPServer` with
# but with the final middleware an external directed proxy
module.exports = class HttpServer extends connect.HTTPServer
7 changes: 7 additions & 0 deletions src/index.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
exports.createProxy = require "./proxy_server"

middlewares = require './middlewares'
for property of middlewares
console.log(property)
if (middlewares.hasOwnProperty(property))
module.exports[property] = middlewares[property]
8 changes: 8 additions & 0 deletions src/middlewares.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
exports.logger = (regex) ->
regex ?= /.*/
(req, res, next) ->
if req.fullUrl.match(regex)
console.log(req.method + ": " + req.fullUrl)
next()
else
next()
29 changes: 29 additions & 0 deletions src/proxy.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
fs = require "fs"
sys = require "sys"
http = require "http"
url = require "url"

safeParsePath = (proxy_url) ->
if (proxy_url.match(/\/http\:\/\//))
parseUrl = '/'
parsedUrl = url.parse(proxy_url)
return parsedUrl.pathname + parsedUrl.search

module.exports = proxy = (req, res, next) ->
console.log(req.url)
if (req.realHost?)
server_host = req.realHost
else
server_host = req.headers['host']
passed_opts = {method:req.method, path:safeParsePath(req.url), host:server_host, headers:req.headers, port:80}
console.log(passed_opts)
upstream_request = http.request passed_opts, (upstream_res) ->
console.log(upstream_res.statusCode)
upstream_res.on 'data', (chunk) ->
res.write(chunk, 'binary')
upstream_res.on 'end', ->
res.end()
res.writeHead(upstream_res.statusCode, upstream_res.headers)
upstream_request.end()


64 changes: 64 additions & 0 deletions src/proxy_server.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
fs = require "fs"
sys = require "sys"
http = require "http"
url = require "url"
connect = require "connect"

safeParsePath = (proxyUrl) ->
safeUrl = ''
proxyUrl = url.parse(proxyUrl.slice(1))
safeUrl += proxyUrl.pathname
safeUrl += proxyUrl.search if proxyUrl.search?
return safeUrl

module.exports = (middlewares...) ->
proxy = new ProxyServer(middlewares)
return proxy

class ProxyServer extends connect.HTTPServer

# Shamelessly pilfered from POW
o = (fn) -> (req, res, next) -> fn req, res, next
x = (fn) -> (err, req, res, next) -> fn err, req, res, next

constructor: (middlewares) ->
middlewares ?= []
middlewares.unshift(@proxyHostCleanup)
middlewares.push(@outboundProxy)
super middlewares

proxyHostCleanup: (req, res, next) ->
req.url = safeParsePath(req.url)
req.fullUrl = req.headers['host'] + req.url
next()

listenHTTPS: (port) ->
return this

listen: (port) ->
super port
return this

outboundProxy: (req, res, next) ->
if (req.realHost?)
server_host = req.realHost
else
server_host = req.headers['host']
passed_opts = {method:req.method, path:req.url, host:server_host, headers:req.headers, port:80}
upstream_request = http.request passed_opts, (upstream_res) ->
upstream_res.on 'data', (chunk) ->
res.write(chunk, 'binary')
upstream_res.on 'end', ->
res.end()
res.writeHead(upstream_res.statusCode, upstream_res.headers)
upstream_request.end()


ProxyServer.logger = (regex) ->
regex ?= /.*/
(req, res, next) ->
if req.fullUrl.match(regex)
console.log(req.method + ": " + req.fullUrl)
next()
else
next()
6 changes: 6 additions & 0 deletions test/test_project.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
project = require ".."

module.exports =
"true is ok": (test) ->
test.ok true
test.done()

0 comments on commit 9724dd4

Please sign in to comment.