Compare commits

...

1157 Commits

Author SHA1 Message Date
Jarrett Cruger
9b96cd7251 1.18.1 2020-05-17 17:26:59 -04:00
Jason
335aeeba2f
Skip sending the proxyReq event when the expect header is present (#1447)
* Skip sending the proxyReq event when the expect header is present

* Adjust padding to match advisory

Co-authored-by: Smylnycky, Jason M <jason.smylnycky@cengage.com>
2020-05-17 17:18:42 -04:00
Jason
dba39668ba
Remove node6 support, add node12 to build (#1397) 2020-05-17 17:16:55 -04:00
indexzero
9bbe486c5e [dist] Version bump. 1.18.0 2019-09-17 21:40:59 -04:00
Jason
6e4bef4d1c
Added in auto-changelog module set to keepachangelog format (#1373)
Removed last nodejitsu reference
2019-09-05 14:11:16 -04:00
Nick Gilligan
d05624167c fix 'Modify Response' readme section to avoid unnecessary array copying (#1300) 2019-08-22 02:40:15 -05:00
IdeaHunter
244303b994 Fix incorrect target name for reverse proxy example (#1135) 2019-08-22 02:39:14 -05:00
Ben Costolo
b4028ba78b Fix modify response middleware example (#1139)
* declare app variable to house middleware

* remove deprecated connect.createServer() function call

* specify middleware with app.use() and pass app middleware to an http
server
2019-08-22 02:38:28 -05:00
renovate[bot]
77a98159d2 [dist] Update dependency async to v3 (#1359) 2019-08-22 02:37:57 -05:00
Kristoffer Lundén
c662f9ebcd Fix path to local http-proxy in examples. (#1072) 2019-08-22 02:35:20 -05:00
Li Bin
806e4927c9 fix reverse-proxy example require path (#1067) 2019-08-22 02:34:29 -05:00
Subomi Oluwalana
c8fa599983 Update README.md (#970)
There were errors in the examples highlighted, check issue #969
2019-08-22 02:31:44 -05:00
renovate[bot]
0d9ed366b1 [dist] Update dependency request to ~2.88.0 [SECURITY] (#1357) 2019-08-22 02:30:06 -05:00
renovate[bot]
9d75b981a1 [dist] Update dependency eventemitter3 to v4 (#1365) 2019-08-22 02:29:37 -05:00
renovate[bot]
192b2b980b [dist] Update dependency colors to v1 (#1360) 2019-08-22 02:29:14 -05:00
renovate[bot]
4a657a7126 [dist] Update all non-major dependencies (#1356) 2019-08-22 02:24:41 -05:00
renovate[bot]
7a154f81d1 [dist] Update dependency agentkeepalive to v4 (#1358) 2019-08-22 02:24:25 -05:00
renovate[bot]
749eec65c3 [dist] Update dependency nyc to v14 (#1367) 2019-08-22 02:21:15 -05:00
renovate[bot]
e588213644 [dist] Update dependency concat-stream to v2 (#1363) 2019-08-22 02:16:50 -05:00
indexzero
59c4403e9d [fix] Latest versions. 2019-08-22 02:12:51 -05:00
indexzero
dd1d08b631 [fix test] Update tests. 2019-08-22 02:12:51 -05:00
indexzero
16d4f8a951 [dist] Regenerate package-lock.json. 2019-08-22 02:12:51 -05:00
indexzero
fc93520d74 [dist] .gitattributes all the things. 2019-08-22 02:12:51 -05:00
indexzero
7e4a0e511b [dist] New test fixtures. 2019-08-22 02:12:51 -05:00
indexzero
a9b09cce43 [dist] End of an era. 2019-08-22 02:12:51 -05:00
Renovate Bot
b00911c937 [dist] Update dependency ws to v3 [SECURITY] 2019-08-22 02:12:51 -05:00
Jaggernoth
36bfe566a7 x-forwarded-host overwrite for mutli level proxies (#1267)
With more than 1 proxy the original host was lost, now it will be passed down the proxy chain
2019-08-22 02:09:26 -05:00
Charlie Robbins
91fee3e943
[refactor doc] Complete rename to http-party org. (#1362) 2019-08-22 01:46:16 -05:00
Justin Russell
235f0aa047 Highlight correct lines for createProxyServer (#1117) 2019-08-22 01:41:47 -05:00
Stein Martin Hustad
acdbec09c6 Fix docs for rewrite options - 201 also handled (#1147)
Updates options documentation for location rewrite to include 201 responses. See #1024
2019-08-22 01:40:03 -05:00
Marcin K
569e2ac4fb Update .nyc_output (#1339)
Currently published version includes .nyc_output and coverage
2019-08-22 01:39:17 -05:00
renovate[bot]
cb3171abfa Configure Renovate (#1355)
* Add renovate.json

* [dist] Configure renovate more.
2019-08-22 01:38:48 -05:00
任侠
a3fe02d651 [examples] Restream body before proxying, support for Content-Type of application/x-www-form-urlencoded (#1264) 2018-06-06 12:39:50 -04:00
Jarrett Cruger
42e8e1e099 1.17.0 2018-04-20 11:42:55 -04:00
Jarrett Cruger
e94d52973a [dist] doc updates 2018-04-20 11:35:07 -04:00
Jarrett Cruger
4a37175a52 [test] add test for selfHandleRequest and remove modifyResponse as selfHandleRequest is the only way that functionality works 2018-04-20 11:35:07 -04:00
guoxiangyang
e5c02b8a8a add support for modify response 2018-04-20 11:35:07 -04:00
Jake Furler
2c44039a7c issue #953: stop using writeHead
object.keys in web-incoming.js results in a non-deterministic ordering of keys, which means that in web-outgoing writeHead might be called before setHeader, which throws an error
2018-04-20 11:35:07 -04:00
Thiago Bustamante
8097ae237e Fix "Can't set headers after they are sent" errors
This PR tries to fix "Can't set headers after they are sent" errors.
That are a lot of situations where this error can occurs. In my case, it is happening because I have others middlewares (in an expressjs application that tries to proxy requests). Some of those middlewares (like [passportjs](http://passportjs.org/), or [cors](https://www.npmjs.com/package/cors)) can run ```res.end()``` and when the proxy receive a response, it is already finished.
So, it is necessary to test if we can write on the user response when the proxy response is ready.
I think it could also fix #930, #1168, #908
2018-04-20 11:35:07 -04:00
Jarrett Cruger
abf882e03c [dist] update package-lock.json 2018-04-20 11:35:07 -04:00
Gustav Tiger
bab02e909e Include websocket non-upgrade response
When the server do not accept the upgrade request for websockets the
server's response was previously not included and sent back. Now the
proxy will include the response in these cases. Fixes #890.
2018-04-20 11:35:07 -04:00
n30n0v
c9a556cfa5 Add followRedirects option 2018-04-20 11:35:07 -04:00
Jon Hunter
6f88caf6e4 Add detail about "buffer" option 2018-04-20 11:35:07 -04:00
Radu Serbanescu
d2f9db8241 Add use case for proxy to HTTPS using a PKCS12 client certificate 2018-04-20 11:35:07 -04:00
carpsareokiguess
8231984fb0 fix small typos in README 2018-04-20 11:35:07 -04:00
Jarrett Cruger
81d58c531b [test] for override method feature 2018-04-20 11:35:07 -04:00
Jarrett Cruger
d533a1be43 [dist] document the feature 2018-04-20 11:35:07 -04:00
shaohui.tsh
89f9ef87e0 feat: 添加response自处理参数 2018-04-20 11:35:07 -04:00
Aydin
c5d8466483 Update common.js
Add method parameter to options for overriding the proxy-outgoing HTTP-method
2018-04-20 11:35:07 -04:00
jlaamanen
107c18720c Added timeout option to docs 2018-04-20 11:35:07 -04:00
Jarrett Cruger
de1b80851a [fix] slightly more tolerant 2018-04-20 11:35:07 -04:00
Sean Willis
bc6a23709c Removing unnecessary check since this is a private API 2018-04-20 11:35:07 -04:00
Sean Willis
f5c2381395 Updating docs and adding more tests. 2018-04-20 11:35:07 -04:00
Sean Willis
50f58b4cd9 Forgot 'i' flag when changing from regex shorthand to string. 2018-04-20 11:35:07 -04:00
Sean Willis
2c98416ac2 Adding ability to set cookie path 2018-04-20 11:35:07 -04:00
Jarrett Cruger
543636d0f6 [fix] move badges 2018-04-20 11:35:07 -04:00
Jarrett Cruger
a4bccc332d [dist][test] codecov config 2018-04-20 11:35:07 -04:00
Jarrett Cruger
f4ff1006b9 [wip] proper tests and reporting 2018-04-20 11:35:07 -04:00
Jarrett Cruger
09dcb98456 [dist] make tests work reliably, add package-lock.json 2018-04-20 11:35:07 -04:00
Georgi Yordanov
812757541d Fix overwriting of global options (#1074) 2018-01-02 19:48:17 -05:00
Elad Ben-Israel
c979ba9f2c Update README.md (#1131)
Update link to properties
2017-01-11 15:53:05 -05:00
Jarrett Cruger
e6f24ba617 [fix] rm newline 2016-12-24 17:03:33 -05:00
Ivan Nieto
d73f1ee873 Update README.md with CoC link (#1120)
* Add Code Of Conduct

* Update CODE_OF_CONDUCT.md

Fix placeholder

* Update REAME.md
2016-12-24 17:02:41 -05:00
Ivan Nieto
a539f3cbc1 Add Code Of Conduct (#1119)
* Add Code Of Conduct

* Update CODE_OF_CONDUCT.md

Fix placeholder
2016-12-24 13:27:54 -05:00
Luigi Pinca
d4d85ac5c4 [deps] Update eventemitter3 to version 2.0.x (#1109) 2016-12-16 12:28:52 -05:00
Jarrett Cruger
c1fb596b85 1.16.2 2016-12-06 10:49:02 -05:00
Yuta Shimizu
961f457622 [WIP] Revert default behavior of writeHeaders method (#1104)
* Replace header key only

* Add preserveHeaderKeyCase Option
2016-12-06 09:51:01 -05:00
Jarrett Cruger
ac1a01b1f3 [dist] Version bump. 1.16.1 2016-12-04 10:59:46 -05:00
Kris Williams
8cb451f20c Enable proxy response to have multiple Set-Cookie raw headers #1101 2016-12-04 10:58:49 -05:00
Jarrett Cruger
c252b32f6c 1.16.0 2016-12-02 09:13:10 -05:00
Maarten ter Horst
927357bedc Fix newly introduced error in error handler for ECONNREFUSED in forward proxy (#1100) 2016-12-02 09:09:11 -05:00
Yuta Shimizu
4edbb62cc5 Keep original letter case of response header keys (#1098)
* Keep original letter case of response header keys

* Support node older than v0.11.6

messege.rawHeaders was added in v0.11.6

* Extract duplicated logic to method
2016-12-01 20:03:13 -05:00
Maarten ter Horst
69cf892519 Handle errors for forward request, add test case (#1099) 2016-12-01 09:39:46 -05:00
purificant
2f7f03778c add node 6 to travis 2016-11-29 09:01:06 -05:00
Jarrett Cruger
d8223884f6 1.15.2 2016-10-22 11:47:23 -04:00
Jarrett Cruger
d0f1dfeb82 [fix] style nits 2016-10-22 11:45:16 -04:00
François Leurent
220f5fb795 Expose full callback names 2016-10-22 11:45:16 -04:00
François Leurent
d48f67eb90 Do not rely on func.name (no scope) 2016-10-22 11:45:16 -04:00
François Leurent
61c2889109 Do not rely on func.name (no scope) 2016-10-22 11:45:16 -04:00
François Leurent
fbc266809c With a comment 2016-10-22 11:45:16 -04:00
François Leurent
8eddf45f2a Fix browserification
Browserify fails to resolve the "./http-proxy/" as "./http-proxy/index.js" but as "./http-proxy.js" (so nothing works)
Beeing explicit here does not cost much for http-proxy, yet it's intrinsically complicated for browserify to fix (as trailing slash might be used as a pollyfill shim for native/non-natives addons i.e.  require('url/') vs require('url') )
2016-10-22 11:45:16 -04:00
Niranjan Ojha
f5217d6c20 test case added 2016-10-06 16:24:44 -04:00
Niranjan Ojha
2d01edc5a5 not setting connection header in case of http2 as it is deprecated 2016-10-06 16:24:44 -04:00
Ashish Dahiya
d0a1588639 Add proxy-timeout option to documentation (#1075)
http-proxy provides a [proxyTimeout option](https://github.com/nodejitsu/node-http-proxy/blob/master/lib/http-proxy/passes/web-incoming.js#L122) that allows us to set a timeout on the outgoing socket connection to the target. This timeout is very effective when the upstream target does not respond within an expected time.

I had wasted a few hours searching for this option. Documenting this option can save others a significant amount of time.
2016-10-04 09:54:52 -04:00
Jarrett Cruger
912cd3acae [dist] Version bump. 1.15.1 2016-09-14 17:12:30 -04:00
briman0094
84087208dd Properly write response header optionally including statusMessage (#1061) 2016-09-14 17:08:26 -04:00
Jarrett Cruger
b98c75b1ff [dist] Version bump. 1.15.0 2016-09-14 13:05:56 -04:00
Alex Indigo
b781af641a Made it not to crash with omited Host http header (#1050) 2016-09-14 07:03:48 -04:00
Michael Ira Krufky
cbd5777060 README.md: fix typo: 'ingoing' should be 'incoming' (#1060) 2016-09-14 07:02:30 -04:00
Cole Chamberlain
d8fb344715 Fix for Reason-Phrase being overwritten on proxy response. (#1051)
* Fix for Reason-Phrase being overwritten on proxy response.

Calling res.writeHead has the side effect of defaulting the Reason-Phrase to default ones.  I'm using Reason-Phrase codes to sub-route api responses and they were all being reset.  This change only sets the statusMessage (Reason-Phrase) if it exists on the proxyRes and is successfully passing it through in my tests.

* Fixed spaces and bracket formatting.
2016-09-13 18:19:33 -04:00
Jeremy Judeaux
1e52f660f0 cookieDomainRewrite option (#1009) 2016-08-12 13:42:18 -04:00
wuchangming
9d06ca99d3 Update ntlm-authentication.js (#1025) 2016-08-11 12:37:57 -04:00
Mati B. Terefe
d0e000e1f9 Restream body before proxying (#1027)
Support for bodyparser.json and bodyparser.urlencoded.

Fixes #955 #843 #791
2016-08-11 12:37:32 -04:00
Gabriel Boucher
183b5bb4fc Location rewriting for responses with status 201 (#1024)
Implement rewriting of the location header for responses with status code 201, according to RFC2616 section 10.2.2
2016-08-11 12:36:17 -04:00
Ken
3a347af543 #866 Copy CA from options into outbound proxy (#1042)
While using secure: true for proxy connections, there is no way to pass the trusted root CA(s) or intermediate CA(s). This change allows that to be passed in the httpProxy createServer options and used for the outgoing proxy connection.
2016-08-11 12:20:35 -04:00
Jarrett Cruger
fcfb0b37f6 [dist] Version bump. 1.14.0 2016-06-15 10:52:53 -04:00
Deividy Metheler
42df703830 Emit disconnected event instead of error when ECONNRESET (#966)
* Emit disconnected event instead of error when ECONNRESET

ECONNRESET means the other side of the TCP conversation abruptly
closed its end of the connection.

If we get an ECONNRESET error from the proxy request and the
socket is destroyed this means that the client has closed
his connection, and emit this as an error can lead to
confusion and hacks to filter that kind of message.

I think that the best we can do is abort and emit another event,
so if any caller wants to handle with that kind of error, he can
by listen the disconnected event.

https://github.com/nodejitsu/node-http-proxy/issues/813

* code standards, move econnreset check, change ev name
2016-06-03 13:39:40 -04:00
Jeremy Judeaux
3e966361bc fix test for node 0.10 + socket.io-client@1.4.6 (engine.io-client@1.6.9) (#1010) 2016-05-25 12:18:51 -04:00
Jarrett Cruger
5082acc067 [dist] Version bump. 1.13.3 2016-05-15 23:14:51 -04:00
idjem
433a7408cf fix browserify compatibility (#975) 2016-05-15 15:40:01 -04:00
Muromi Ukari
6baf1498cb alter message error (#998)
message error about port 9001 -> port 9002
2016-04-28 09:15:03 -07:00
Mihai Ene
284903d379 Sanitize header keys before setting them (#997)
Fixes #996.
2016-04-26 13:26:35 -07:00
Jarrett Cruger
b223275ebb Merge pull request #989 from aroder/patch-1
Update ntlm-authentication.js
2016-04-26 13:23:33 -07:00
Adam Roderick
ecdfff408f Update ntlm-authentication.js
missing bracket
2016-04-14 16:21:39 -05:00
Jarrett Cruger
28cecb5a96 Merge pull request #983 from deanshelton913/add-datatype-to-readme
Add expected datatype to readme
2016-03-23 18:36:21 -04:00
deanshelton913
bdb3492b21 Add expected datatype to readme
This confused me while attempting to use this feature
2016-03-23 15:19:50 -07:00
Jarrett Cruger
a4b2857216 Merge pull request #982 from kylehayes/patch-1
Update README
2016-03-22 15:13:09 -04:00
Kyle Hayes
820fc5987c Update README
For clarity
2016-03-22 08:47:14 -07:00
indexzero
f345a1ac2d [dist] Update LICENSE to reflect 2015 changes. 2016-03-12 00:05:21 -08:00
Jarrett Cruger
018352955e Merge pull request #974 from bmac/patch-1
Fix formatting of the `headers` option
2016-03-08 17:26:38 -08:00
Brendan McLoughlin
f8d605d53f Fix formatting of the headers option 2016-03-08 18:07:11 -05:00
Jarrett Cruger
c1440b58f1 Merge pull request #967 from jbacklund/patch-1
Set the x-forwarded-host flag when xfwd is enabled
2016-02-26 09:52:26 -08:00
Jakob Backlund
ef86b50427 Set the x-forwarded-host flag when xfwd is enabled
Reasoning: Rack's request class [makes use of](https://github.com/rack/rack/blob/master/lib/rack/request.rb#L243) this HTTP header. Certain edge-case scenarios (proxying from ember-cli to a Rails backend) can be problematic without this header being present.

/cc @perlun, @jesjos
2016-02-26 14:29:55 +02:00
Jarrett Cruger
e1b2f4c31b [dist] Version bump. 1.13.2 2016-02-17 11:00:08 -05:00
Jarrett Cruger
820f198729 Merge pull request #806 from chimurai/master
Fixed missing documentation: #options.headers
2016-02-16 18:05:28 -05:00
Jarrett Cruger
d2df053677 Merge pull request #950 from caioquirino/master
#949 Proxy example using req instead res on README
2016-02-15 10:36:24 -05:00
Jarrett Cruger
7357200334 Merge pull request #962 from Turbo87/default-mocha-reporter
mocha: Use default reporter
2016-02-15 10:35:41 -05:00
Jarrett Cruger
d19be83858 Merge pull request #961 from Turbo87/transfer-encoding-fix
Remove "transfer-encoding" header if "content-length" is set to zero
2016-02-15 10:35:32 -05:00
Tobias Bieniek
570cf3b4f9 mocha: Use default reporter
Unfortunately the "landing" reporter doesn't really look good on CI servers at all...
2016-02-15 15:47:46 +01:00
Tobias Bieniek
5c46e4b754 Remove "transfer-encoding" header if "content-length" is set to zero 2016-02-15 15:43:14 +01:00
Caio Quirino da Silva
25e56d0182 #949 Proxy example using req instead res on README
README example implies request instead of response parameter
2016-02-02 11:56:39 -02:00
Jarrett Cruger
9d9fa940cf [dist] Version bump. 1.13.1 2016-02-01 21:02:33 -08:00
Jarrett Cruger
2831d9a4f9 Merge pull request #932 from afriza/patch-1
README.md: summary to specify reverse proxy
2016-02-01 20:59:49 -08:00
Jarrett Cruger
a379d160f3 Merge pull request #947 from coderaiser/fix-urlJoin
fix(common) urlJoin replace: ":/" -> "http?s:/"
2016-02-01 20:59:18 -08:00
Jarrett Cruger
7aed1f4559 Merge pull request #948 from Alfredo-Delgado/patch-1
Update README.md
2016-02-01 20:58:45 -08:00
Alfredo Delgado
bfcab93d8d Update README.md
Fixed typo.
2016-01-30 12:26:26 -05:00
coderaiser
7bad3fbca4 fix(common) urlJoin replace: ":/" -> "http?s:/" 2016-01-29 02:47:12 -05:00
Jarrett Cruger
268994ea45 [dist] Version bump. 1.13.0 2016-01-26 17:11:50 -05:00
Jarrett Cruger
58c0fdc761 Merge pull request #934 from Torthu/master
Fix for #839 (Ignore path and the trailing slash)
2016-01-26 15:56:58 -05:00
Charlie Robbins
d73b0d312a Merge pull request #943 from pra85/patch-1
Update license year range to 2016
2016-01-26 01:02:52 -08:00
Prayag Verma
a76e226221 Update license year range to 2016 2016-01-26 14:12:24 +05:30
Jarrett Cruger
db576d75c1 Merge pull request #942 from merpnderp/patch-1
Bump version for npm publish
2016-01-24 15:19:54 -05:00
Kaleb Murphy
e017fa8189 Bump version for npm publish
Would be great to get the NTLM fix into npm.
2016-01-24 14:11:12 -06:00
Jarrett Cruger
646a7493a4 Merge pull request #940 from merpnderp/FixSetHeader
Added check to passes/web-outgoing.js to make sure the header being s…
2016-01-23 12:27:49 -05:00
merpnderp
3b39d2c3dc Added check to passes/web-outgoing.js to make sure the header being set is not undefined, which should be the only falsey value that could accidently show up and break that call. This fixes windows NTLM auth issues behind http-proxy. 2016-01-22 09:17:14 -06:00
Torstein Thune
0cb1d3c68e Added note for appending trailing / when using ignorePath 2016-01-13 15:27:51 +01:00
Torstein Thune
f9540de7b1 Fixed tests depending on ignorePath 2016-01-13 15:24:46 +01:00
Torstein Thune
f2093b5313 No longer appends / to path if ignorePath is set 2016-01-13 09:16:50 +01:00
Afriza N. Arief
41414a56a1 README.md: introduction to specify reverse proxy
clarify proxy type to be reverse proxy in the introduction
2016-01-04 12:40:05 +08:00
Charlie Robbins
6371231086 Merge pull request #825 from pose/patch-1
Created reverse-proxy.js example.
2015-12-29 23:53:21 -05:00
Jarrett Cruger
6c83980f29 Merge pull request #922 from aaronmaturen/sse
SSE example and test
2015-12-07 15:58:22 -05:00
Aaron T. Maturen
e4760727f1 SSE example and test 2015-12-06 19:34:42 -05:00
Charlie Robbins
222a4d0fa1 Merge pull request #912 from nodejitsu/more-structured-readme
More structured readme
2015-11-23 13:12:37 -05:00
donasaur
6106d4c32f Added back to top helpers 2015-11-23 09:46:15 -08:00
donasaur
cd1d7776e8 Organized README more 2015-11-23 09:30:05 -08:00
Jarrett Cruger
642e9cc2cb Merge pull request #910 from nodejitsu/proxy-table-readme
Updated markdown docs to mention proxy rules module
2015-11-22 14:19:09 -05:00
donasaur
eea79cab53 Updated markdown docs to mention proxy rules 2015-11-20 17:28:37 -08:00
Jarrett Cruger
f82ce18d2f [ci] use node 4.2 to test and do not allow failures 2015-11-09 19:43:18 -08:00
Jarrett Cruger
470475b896 Merge pull request #901 from jedverity/master
Add tests for forwarding of continuation frames
2015-11-09 14:53:05 -08:00
Jarrett Cruger
2a5e69d48c Merge pull request #904 from shinnn/deps
Bump requires-port, server and ws
2015-11-06 13:20:22 -08:00
Shinnosuke Watanabe
9ea1e89a2f [fix] bump requires-port, server and ws
npm v3 tries to dedupe the dependencies by default, and keeping
dependencies up-to-date helps better deduplication.

https://github.com/unshiftio/requires-port
https://github.com/npm/node-semver
https://github.com/websockets/ws
2015-11-05 17:49:45 +09:00
Jarrett Cruger
ab42124d54 Merge pull request #903 from nodejitsu/ntlm-authentication
[example] add an example for NTLM authentication
2015-10-30 14:16:10 -07:00
Jarrett Cruger
5d593e8ef1 [example] add an example for NTLM authentication 2015-10-30 14:14:03 -07:00
glortho
64fa520789 Add tests for testing forwarding of continuation frames
This adds two tests that send payloads below and at the threshold for continuation frames. Using node 0.12.7 both tests pass. Using node 4.1.2 the test below the threshold passes but the other fails.
2015-10-28 15:52:37 -04:00
Jarrett Cruger
b5a6d0e583 [dist] Version bump. 1.12.0 2015-10-22 19:27:24 -04:00
Jarrett Cruger
0bc4c783ca Merge pull request #897 from lbrucher/issue-896
Issue #896: provide a "proxyReq" event also for websocket connections.
2015-10-22 19:26:02 -04:00
Laurent Brucher
9752652e76 fixes after PR review 2015-10-22 18:38:58 +02:00
Laurent Brucher
a05fc2d169 Provide a "proxyReq" event also for websocket connections. 2015-10-22 15:56:34 +02:00
Jarrett Cruger
60baca5aed [dist] Version bump. 1.11.3 2015-10-19 09:30:18 -04:00
Charlie Robbins
6b65c428b3 Merge pull request #893 from donasaur/master
Removed unspecified trailing slash in proxy url
2015-10-18 16:15:53 -05:00
donasaur
eb97bf5423 Removed unspecified trailing slash in proxy url 2015-10-18 13:04:06 -07:00
Jarrett Cruger
ec64e4f597 Merge pull request #892 from donasaur/patch-1
Updating the upgrading doc
2015-10-18 10:45:45 -04:00
Don Mai
e666a4e07d Updating the upgrading doc
Recently ran into a case where I had to upgrade the `http-proxy` version for an app, and that app was using a proxy table.

I'm not sure how many users are still using the 0.x.x version of `http-proxy`, but the added link (found from one of the GH issues) may encourage them to switch over to 1.x.x if they were using the old version due to its proxy table support and the activation energy to upgrade was too high.

I might release a module for this eventually, lol, since there was some work involved in creating a proxy table to map paths to paths for the same hostname.
2015-10-18 01:12:19 -07:00
chimurai
c86ae51bb9 docs: options.headers 2015-09-26 23:46:11 +02:00
indexzero
302d981dd2 [dist] Update .travis.yml to be more modern. 2015-09-21 18:22:31 -07:00
Jarrett Cruger
30e3b371de [dist] Version bump. 1.11.2 2015-08-30 17:29:25 -04:00
Jarrett Cruger
cea0e8676b [fix] make more functional 2015-08-30 17:28:05 -04:00
Arttu Liimola
3d2350c54f Replaced Object.keys().map with for in loop. 2015-08-30 17:16:42 -04:00
Arttu Liimola
ca73208749 Websocket key was unnecessary long. 2015-08-30 17:16:36 -04:00
Arttu Liimola
da674ec4df Modify the set-cookie header fix to work with node 0.10.x. 2015-08-30 17:16:07 -04:00
Arttu Liimola
855cebdac4 Added websocket set-cookie headers test 2015-08-30 17:16:00 -04:00
Arttu Liimola
8bfd90c4d9 Use raw headers instead parsed.
Set-Cookie headers are parsed into single header with cookies in array.
This messes up the Set-Cookie headers, because browser receives multiple Set-Cookie headers as single with cookies separted with comma.
2015-08-30 17:15:54 -04:00
Charlie Robbins
931f73dc98 Merge pull request #870 from justsml/patch-1
Update gzip-middleware.js
2015-08-24 12:38:27 -07:00
Daniel Levy
349b843731 Update gzip-middleware.js
Punctuation
2015-08-24 13:23:53 -06:00
Charlie Robbins
2e3eb0950d Merge pull request #863 from stuartpb/patch-1
Fix broken option list indentation
2015-08-14 12:30:42 -07:00
Stuart P. Bentley
1f4fccd2c6 Fix broken option list indentation 2015-08-14 09:02:50 -07:00
Jarrett Cruger
ecbba1a008 Merge pull request #852 from jpatters/patch-1
Added missing configuration options
2015-07-09 09:55:36 -04:00
Jordan
fe3dd8363f Added missing configuration options
Added missing config options for httpProxy.createProxyServer. Updated to include all options listed in `lib/http-proxy.js`
Addresses nodejitsu/node-http-proxy#851
2015-07-09 08:03:23 -03:00
Alberto Pose
38864d0167 Created reverse-proxy.js example. 2015-05-18 20:30:43 -03:00
Jarrett Cruger
76051032e7 Merge pull request #823 from montogeek/patch-1
Added installation instructions
2015-05-13 10:24:09 -07:00
Fernando Montoya
7e82a04a16 Added installation instructions 2015-05-12 21:38:05 -05:00
Jarrett Cruger
1912b62ddb Merge pull request #817 from klammbueddel/master
fixes comment
2015-05-09 14:23:03 -07:00
klammbueddel
3f997b9289 fixes comment 2015-04-30 10:19:40 +02:00
Jarrett Cruger
7e6c66a7e4 [dist] Version bump. 1.11.1 2015-04-22 11:09:36 -04:00
Jarrett Cruger
d26ef56e1b [fix] dont use bind in the one case we do 2015-04-22 11:09:05 -04:00
Jarrett Cruger
607f96c00c [dist] update to new version of EE3 2015-04-22 11:07:24 -04:00
Jarrett Cruger
18c77cafc7 [fix] use the main export for EE3 2015-04-22 11:07:13 -04:00
Jarrett Cruger
934e6c4d54 [dist] Version bump. 1.11.0 2015-04-20 16:48:14 -04:00
Jarrett Cruger
0db8f195d7 Merge pull request #759 from nodejitsu/ignore-path
[api] add an ignorePath option if you want to disregard the path of the ...
2015-04-20 16:47:27 -04:00
Jarrett Cruger
0bd446c680 [dist] Version bump. 1.10.1 2015-04-02 12:41:02 -04:00
Jarrett Cruger
a6ae6c4997 [ci] add 0.12 and iojs to travis 2015-04-02 12:32:08 -04:00
Jarrett Cruger
1b89bc9a76 [dist] add semver and normalize package.json with --save-dev 2015-04-02 12:31:17 -04:00
Jarrett Cruger
c6dfb04a67 [fix] properly support iojs with test checking for HTTPS 2015-04-02 12:30:55 -04:00
Jarrett Cruger
6201ac76f7 Merge pull request #799 from F4-Group/fix_https
Fix default port detection with node 0.12.x
2015-04-02 12:05:03 -04:00
Jeremy Judeaux
5f14bcaa70 fix protocol and default port detection on node 0.12.x, compatible with 0.10.x 2015-04-02 14:23:58 +02:00
Jeremy Judeaux
0ee314c436 fix expected error message when node 0.12.x 2015-04-02 14:22:26 +02:00
Jeremy Judeaux
c33d1616cd force cipher AES128-GCM-SHA256 in https tests 2015-04-02 14:11:45 +02:00
Jarrett Cruger
1dabda241f [dist] Version bump. 1.10.0 2015-04-01 12:24:26 -04:00
Jarrett Cruger
5a969d077b Merge pull request #787 from mokafive/master
Fixes / additions to URL rewriting
2015-04-01 12:20:37 -04:00
Jarrett Cruger
21b30b754d [dist] Version bump. 1.9.1 2015-04-01 12:09:42 -04:00
Jarrett Cruger
aa8f3e9a6e Merge pull request #798 from damonmcminn/master
Fix #747
2015-04-01 11:07:42 -04:00
Damon McMinn
ab37a224aa Fix https://github.com/nodejitsu/node-http-proxy/issues/747 2015-04-01 13:19:03 +01:00
Damon McMinn
d145152655 Add test for https://github.com/nodejitsu/node-http-proxy/issues/747 2015-04-01 13:14:11 +01:00
Jarrett Cruger
87a92a7280 [dist] Version bump. 1.9.0 2015-03-12 18:59:32 -04:00
Jarrett Cruger
507f818df5 Merge pull request #792 from ashubham/master
Adding the nodejs0.12 auth option
2015-03-12 18:58:06 -04:00
ashubham
e907d7bb2a end of file line space 2015-03-12 15:17:26 -07:00
ashubham
7298510e91 space instead of tabs 2015-03-12 15:16:17 -07:00
ashubham
63c9262df5 space instead of tabs 2015-03-12 15:14:49 -07:00
ashubham
ff1626f071 added auth header test 2015-03-12 15:12:53 -07:00
ashubham
df158bfc53 added auth header test 2015-03-12 15:11:56 -07:00
ashubham
f55ffa356a auth header added tests 2015-03-12 13:40:49 -07:00
ashubham
ab5c3e5c81 auth header added 2015-03-12 13:15:06 -07:00
Jarrett Cruger
245d73ae6c Merge pull request #789 from feross/master
fix "x-forwarded-proto" in node 0.12 and iojs
2015-03-11 21:07:38 -04:00
Feross Aboukhadijeh
6d074eff47 fix "x-forwarded-proto" in node 0.12 and iojs
The way to detect TLSSockets in node 0.12 and iojs has changed. You can
just check `socket.encrypted` now :)

Fixes #772
2015-03-11 00:33:34 -07:00
Matt Hauck
26029ba7ac only rewrite redirect urls when it matches target
if functioning as a reverse proxy for host1.foo.com,
with a backend target of backend.foo.com:8080, the
node proxy should only rewrite the redirect if it is
a redirect to somewhere on backend.foo.com:8080
2015-03-09 13:17:52 -07:00
Matt Hauck
14415a5074 refactor some tests for greater readability 2015-03-09 11:49:28 -07:00
Matt Hauck
62e4b75101 Merge pull request #1 from matthauck/master
Add support for auto host rewriting and protocol rewriting
2015-02-05 12:33:10 -08:00
Matt Hauck
7f2f3ac35c Add support for auto host rewriting and protocol rewriting
auto host rewriting allows rewriting to work as expected in most
cases without extra cumbersome configuration

protocol rewriting allows node-http-proxy to be able to listen
over HTTPS and properly reverse-proxy to sites running over HTTP
(to avoid doing SSL twice)
2015-02-05 12:17:26 -08:00
Jarrett Cruger
9eefd4678e [api] add an ignorePath option if you want to disregard the path of the incoming request when proxying to the target server fixes #758 2014-12-23 13:22:49 -05:00
Jarrett Cruger
9ece52fac4 Merge pull request #756 from PanManAms/patch-1
changed highlighted part - very minor
2014-12-22 12:02:36 -05:00
PanManAms
32aa10dfe2 changed highlighted part - very minor 2014-12-20 15:40:46 +01:00
Charlie Robbins
c82c9ece8a Merge pull request #625 from bkochendorfer/master
Update README.md for benchmarks
2014-12-19 02:01:53 -07:00
Jarrett Cruger
3311106c2c [dist] Version bump. 1.8.1 2014-12-17 10:11:42 -07:00
Alistair Jones
402ab05734 Pass HTTPS client parameters.
For more detailed control over HTTPS client behaviour, pass through the
parameters listed here:
http://nodejs.org/api/https.html#https_https_request_options_callback

The `rejectUnauthorized` parameter is omitted, because it overlaps with
the existing `secure` parameter:
https://github.com/nodejitsu/node-http-proxy/blob/master/README.md#using-https

Conflicts:
	test/lib-http-proxy-common-test.js
2014-12-17 10:09:29 -07:00
Jarrett Cruger
f0db5b3f70 [dist] Version bump. 1.8.0 2014-12-17 00:58:17 -07:00
Jarrett Cruger
f30486195c [minor] grammar 2014-12-17 00:57:43 -07:00
Jarrett Cruger
ea0a4ded80 [fix] style spacing wtf 2014-12-17 00:53:51 -07:00
Jorge Leal
8a8a894092 Changed proxyServer and destiny to local variables. 2014-12-17 00:52:41 -07:00
Jorge Leal
c62610e8e4 Deprecated proxySocket event in favor to open event.
Maintained both proxySocket and open for backward compatibility.

Conflicts:
	test/lib-http-proxy-test.js
2014-12-17 00:52:19 -07:00
Jorge
05d18a4e1b Update README.md 2014-12-17 00:51:24 -07:00
Jorge Leal
8bff3ddc12 Added websocket close event test 2014-12-17 00:51:19 -07:00
Jorge
26537866b3 [api] add close event in ws-incoming.js 2014-12-17 00:51:06 -07:00
Charlie Robbins
f92a1b6839 Merge pull request #752 from ezhdan-sugarcrm/tests-fix
Fix variables scope in test
2014-12-13 14:34:45 -07:00
Eugene Zhdan
c1a94176a8 Fix variables scope in test 2014-12-13 21:45:14 +03:00
Arnout Kazemier
099eb86948 Merge pull request #751 from seanhussey/patch-1
Fix typo
2014-12-11 17:26:24 +01:00
Sean Hussey
4bd3c4671f Fix typo 2014-12-11 11:02:09 -05:00
Jarrett Cruger
6a330ff904 [dist] Version bump. 1.7.3 2014-12-08 23:05:01 -05:00
Jarrett Cruger
89f9ca1e89 [test] show that we support protocol without the colon 2014-12-08 23:04:41 -05:00
Jarrett Cruger
c04485671a [fix] use simple regex instead of indexOf to check the protocol to support without the colon fixes #711 2014-12-08 23:04:23 -05:00
Jarrett Cruger
2086e4917c [dist] Version bump. 1.7.2 2014-12-08 16:16:05 -05:00
Jarrett Cruger
71a06aab02 [test] add tests for the changeOrigin cases in properly setting the host header 2014-12-08 16:14:48 -05:00
Jarrett Cruger
501e8c2a9b [fix] properly include port in host header with changeOrigin in all cases fixes #750 2014-12-08 16:14:16 -05:00
Jarrett Cruger
81874f795b [dist] pin down deps and add requires-port 2014-12-08 16:11:28 -05:00
Charlie Robbins
75a9a2de61 Merge pull request #749 from kblanks/patch-1
Fix grammar in README.md
2014-12-03 04:51:11 -07:00
Kailan Blanks
aeb42a3614 Fix grammar in README.md 2014-12-03 11:49:19 +00:00
Jarrett Cruger
56a7b77645 [dist] Version bump. 1.7.1 2014-12-02 10:28:04 -07:00
Jarrett Cruger
9c0b8697bc [fix] fix #738 2014-12-02 10:25:46 -07:00
Jarrett Cruger
410a8ce94c [test] add proper failing test case for #738 2014-12-02 10:25:30 -07:00
Jarrett Cruger
d98d9516ea [fix] simple fixes #748 #744 #746 2014-12-02 09:58:06 -07:00
koolc
70ed1c4273 [Bugfix] Allow for multiple ? in outgoing urls.
Without this fix urls that had multiple ? in them would drop sections
of the url since before there was an assumption of there only being one.
2014-12-01 12:34:16 -05:00
Jarrett Cruger
361d4e3b00 Merge pull request #716 from No9/master
Adding harmon to the README
2014-11-28 12:02:39 -05:00
Jarrett Cruger
276f65a3b8 [dist] Version bump. 1.7.0 2014-11-25 17:31:28 -05:00
Jarrett Cruger
8d68ac0e0f [fix] be defensive and ensure location is in headers before running url.parse() 2014-11-25 17:22:23 -05:00
Jarrett Cruger
48ae5d828c [minor] style consistency 2014-11-25 17:21:24 -05:00
Jarrett Cruger
95a588706b Merge pull request #741 from samccone/sjs/redirect-host-rewrite
Allow optional redirect host rewriting.
2014-11-25 17:08:54 -05:00
Jarrett Cruger
3194d819b4 Merge pull request #742 from jugglinmike/option-content-length
Set `Content-Length` header for OPTIONS requests
2014-11-25 11:15:46 -05:00
Mike Pennisi
8a24a1e18f Set Content-Length header for OPTIONS requests
Web browsers automatically issue an OPTIONS request in advance of other
HTTP requests when the document's domain does not match the target in
order to facilitate Cross-Origin Resource Sharing. These requests are
forbidden from specifying a body and typically do not specify an
(unecessary) `Length` header.

Node.js automatically adds the `Content-Encoding: chunked` header value
to requests that do not specify a `Length` header. This makes proxied
OPTIONS requests from web browsers invalid.

Explicitly set the `Content-Length` header of all `OPTIONS` requests to
"0", disabling the default "chunked" encoding behavior [2].

[1] http://www.w3.org/TR/cors/
[2] http://nodejs.org/api/http.html
2014-11-24 17:14:48 -05:00
Sam Saccone
add81338a9 📝 Add host rewrite docs and specs. 2014-11-23 19:22:07 -05:00
Sam Saccone
daf66a7a88 Allow optional redirect host rewriting. 2014-11-23 19:22:07 -05:00
Jarrett Cruger
aba505d159 Merge pull request #736 from richardkazuomiller/copy-headers
copy headers instead of referencing them so they don't unexpectedly get overwritten
2014-11-12 16:46:51 -05:00
Ricky Miller
84036e9ddd style changes 2014-11-13 06:05:32 +09:00
Ricky Miller
daa2ce0ee3 copy headers instead of referencing them so they don't unexpectedly get overwritten 2014-11-13 04:37:45 +09:00
Jarrett Cruger
69a693034e Merge pull request #735 from jleal52/master
Updated to support error callback on proxy.web and start/proxyReq/end co...
2014-11-12 13:05:04 -05:00
jleal52
9ba8311343 Updated to support error callback on proxy.web and start/proxyReq/end continue working. 2014-11-12 14:41:46 +00:00
Jarrett Cruger
709b3e9656 [dist] Version bump. 1.6.2 2014-11-11 11:47:43 -05:00
Jarrett Cruger
3f19e6e178 [minor] this shouldnt be in var block 2014-11-11 11:47:15 -05:00
Jarrett Cruger
7c5e40a429 [fix] style changes 2014-11-10 23:02:43 -05:00
Jarrett Cruger
eb95660822 Merge pull request #733 from richardkazuomiller/double-slash-fix
do not modify the query string
2014-11-10 22:29:16 -05:00
Ricky Miller
4a2b870cc9 do not modify the query string 2014-11-09 08:44:22 +09:00
Jarrett Cruger
fa797fca90 [dist] Version bump. 1.6.1 2014-11-04 18:14:09 -05:00
Jarrett Cruger
57329b6327 Merge pull request #729 from lightblade/master
websocket needs to respect `options.secure` too
2014-11-04 18:13:26 -05:00
Ming Liu
d1eabccf93 websocket needs to respect options.secure too 2014-11-04 15:06:45 -08:00
Jarrett Cruger
60bd697051 Merge pull request #724 from whitecolor/change-origin-option
changeOrigin option docs fix
2014-10-29 10:52:10 -04:00
Alex Oshchepkov
1af8224cc1 changeOrigin option docs fix 2014-10-29 08:09:43 +05:00
Jarrett Cruger
43641b00b3 [dist] Version bump. 1.6.0 2014-10-28 22:53:54 -04:00
Jarrett Cruger
70fa8ad58c Merge pull request #723 from whitecolor/change-origin-option
Added changeOrigin option with test and docs
2014-10-28 22:52:50 -04:00
Alex Oshchepkov
796ab0bcc5 Added changeOrigin option with test and docs 2014-10-29 07:25:19 +05:00
Charlie Robbins
f70015f001 Merge pull request #717 from waded/patch-1
I presume you mean couchdb here
2014-10-15 01:35:41 -04:00
Wade Dorrell
f64954a08b I presume you mean couchdb here 2014-10-14 22:49:33 -06:00
no9
9f684d0439 harmon notes 2014-10-15 01:52:27 +01:00
Jarrett Cruger
3768cce4ca Merge pull request #712 from zhudan/master
update modify request body eg
2014-10-09 09:48:08 -04:00
dan
d46e876e27 update modify request body eg 2014-10-09 14:33:04 +08:00
dan
0378b03e53 update modify request body eg 2014-10-09 14:32:52 +08:00
dan
04c45a022c update modify request body eg 2014-10-09 14:30:11 +08:00
Jarrett Cruger
9577a0faf2 [dist] Version bump. 1.5.3 2014-10-01 07:10:51 -04:00
Jarrett Cruger
fcdbf46e4d Merge pull request #709 from minrk/close-on-error
close socket if upstream request fails
2014-10-01 07:10:22 -04:00
MinRK
c62766391e close socket if upstream request fails
adds socket.end() to on('error') handlers for proxyReq and proxySocket
2014-09-30 19:58:57 -07:00
Jarrett Cruger
43c6f0c7c0 [dist] Version bump. 1.5.2 2014-09-30 21:21:04 -04:00
Jarrett Cruger
b065d92908 Merge pull request #708 from minrk/close-closes
close websocket if proxyReq is closed before upgrade
2014-09-30 20:55:38 -04:00
MinRK
bcd8a564a8 close websocket if proxyReq is closed before upgrade
avoids leaving client sockets open when upstream
connections are rejected.
2014-09-30 17:01:20 -07:00
MinRK
77305489d9 test closing upstream socket prior to upgrade
should close the client socket with ECONNRESET,
but currently is left hanging.
2014-09-30 16:11:49 -07:00
Jarrett Cruger
f0bf741815 [dist] Version bump. 1.5.1 2014-09-30 15:23:02 -04:00
Jarrett Cruger
10a294af4d [fix] do a check to make sure the server exists before we try and emit 2014-09-30 15:22:52 -04:00
Jarrett Cruger
232258b6ec [dist] Version bump. 1.5.0 2014-09-29 22:38:47 -04:00
Jarrett Cruger
9210b56c9e Merge pull request #706 from thlorenz/expose-proxy-socket
exposing proxySocket on socket to support sniffing messages coming from proxy target
2014-09-29 22:34:06 -04:00
Thorsten Lorenz
000eb533de emitting proxySocket on proxyServer
- emitted once proxySocket was created and socket was piped into it
- needed to support sniffing messages coming from proxy target
2014-09-29 20:09:46 -04:00
Jarrett Cruger
2aa3b84d7b Merge pull request #705 from Jimbly/patch-1
Fixed misleading documentation
2014-09-26 00:01:36 -04:00
Jimb Esser
a4ca578b44 Fixed misleading documentation
options.xfwd definitely works fine without using the .listen method, and, AFAICT, .toProxy should as well.  Only .ssl and .ws are referenced in .listen.
2014-09-25 20:54:46 -07:00
Jarrett Cruger
e7d50b1a37 [minor] extra space 2014-09-25 22:11:12 -04:00
Jarrett Cruger
c0a796b3e3 [fix] perf optimization so we have a precompiled regexp 2014-09-17 07:53:18 -04:00
Jarrett Cruger
90d40d6a6a Merge pull request #702 from shebson/fix-readme-typo
Fix typo in README.md
2014-09-16 18:21:35 -04:00
Stephen Hebson
45cf95a82e Fix typo in README.md
"Is it then possible" -> "It is then possible"
2014-09-16 14:55:12 -07:00
Jarrett Cruger
42c35aedca Merge pull request #691 from minrk/firefox-ws-connection-close
handle 'upgrade' in comma-separated connection header
2014-09-16 15:42:41 -04:00
MinRK
ec683b924b test new detection of connection: upgrade 2014-09-16 12:09:26 -07:00
MinRK
65a21bce6d use regex to check for upgrade header
in websocket connections
2014-09-16 12:07:15 -07:00
MinRK
51eeebef68 handle 'upgrade' in comma-separated connection header
Firefox sends `keep-alive, upgrade`, not just `upgrade`,
which the proxy incorrectly turned into `close`
2014-09-16 11:15:17 -07:00
cronopio
554f59c518 Bump version v1.4.3 2014-09-12 12:31:28 -05:00
Arnout Kazemier
73e8a4cdd5 [minor] Added missing JSDoc comments 2014-09-12 19:21:12 +02:00
Arnout Kazemier
3ab6e9591e [minor] Code style adjustment. 2014-09-12 19:13:53 +02:00
Arnout Kazemier
a934cb6a46 [ignore] Ignore npm-debug.log 2014-09-12 19:11:49 +02:00
Arnout Kazemier
107b9da256 Merge pull request #699 from STRML/master
Urgent: Fix breaking bug on url joining resulting in paths like `///path`.
2014-09-12 19:10:30 +02:00
Samuel Reed
73d865bc9f Fix breaking bug on url joining resulting in paths like ///path.
Added OS-agnostic url join helper.
2014-09-12 13:08:10 -04:00
Jarrett Cruger
df12aeb12d [dist] Version bump. 1.4.2 2014-09-12 07:50:36 -04:00
Jarrett Cruger
ed73f06ed3 [fix] ensure path works on windows because path.join doesnt like URLs 2014-09-12 07:50:16 -04:00
Jarrett Cruger
d5c656bceb [dist] Version bump. 1.4.1 2014-09-11 18:52:13 -04:00
Jarrett Cruger
dceef407a1 [dist] Version bump. 1.4.0 2014-09-11 18:51:49 -04:00
Jarrett Cruger
e44fabe58a [test] add test for prependPath option 2014-09-11 18:51:49 -04:00
Jarrett Cruger
9a534c6ff6 [api] add prependPath option to go with path change 2014-09-11 18:51:49 -04:00
Arnout Kazemier
d1facd52c3 Merge pull request #644 from CaleyD/master
Trimming contents of distributed npm package.
2014-09-11 14:09:53 +02:00
Arnout Kazemier
5568cb5575 Merge pull request #669 from baer/remove-changelog
Remove changelog - it was not maintained
2014-09-11 14:08:50 +02:00
Arnout Kazemier
6ac05259ca Merge pull request #695 from outime/patch-1
Removed duplicated imported dependencies
2014-09-11 14:07:15 +02:00
Rubén Díaz
0e64568b4e Removed duplicated imported dependencies 2014-09-11 14:21:33 +03:00
Jarrett Cruger
fc73828035 [dist] Version bump. 1.3.1 2014-09-09 13:22:17 -04:00
Jarrett Cruger
814fbd254d Merge pull request #693 from EndangeredMassa/fix-path
Allow proxy to maintain the original target path
2014-09-08 18:23:42 -04:00
Sean Massa
a65021d52b fix tests for maintaining proxy path 2014-09-08 17:17:15 -05:00
Domi
511b7b3d47 Fix proxy path
This fix considers the actual target path again (which has been ignored).
2014-09-08 15:57:53 -05:00
Jarrett Cruger
6b83ae47bb [ci] remove 0.11.x to avoid failing builds caused by TLS errors 2014-09-08 16:28:51 -04:00
Jarrett Cruger
d16062bba2 Merge pull request #686 from joeyespo/master
Clarify usable parameters for 'proxyRes' event
2014-08-21 19:50:48 -04:00
Joe Esposito
49a0de1e7c Clarify usable parameters for proxyRes event. 2014-08-21 17:02:36 -04:00
Jarrett Cruger
05f0b891a6 [dist] Version bump. 1.3.0 2014-08-14 17:28:00 -04:00
Jarrett Cruger
261742a429 [fix] cleanup and stylize close function 2014-08-14 17:16:56 -04:00
Jarrett Cruger
f92f7aea9b Merge pull request #679 from RackspaceEmailAndApps/close_proxy
Added functionality to close proxy.
2014-08-14 17:12:42 -04:00
John Catron
8be9d945d0 updated close function for safety 2014-08-14 20:12:20 +00:00
Jarrett Cruger
0a6b424e2c [dist] Version bump. 1.2.1 2014-08-14 13:40:40 -04:00
Jarrett Cruger
37036dd325 [fix] emit an error if proper URL is not passed in as a target 2014-08-14 13:32:32 -04:00
John Catron
a3d02196c5 Added close method to proxy server.
Ensured server exists before closing.
Updated tests to use new close function.
Added documentation to README.
2014-08-14 17:30:38 +00:00
Jarrett Cruger
63c53a1772 [dist] Version bump. 1.2.0 2014-08-05 17:27:21 -04:00
Jarrett Cruger
3e8ee042fb Merge pull request #673 from digitalbazaar/mod-header-event
[api] Add event-based ability to modify pre-flight proxy requests.
2014-07-20 15:15:49 -04:00
Manu Sporny
db5f2954b2 [api] Add event-based ability to modify pre-flight proxy requests. 2014-07-18 11:46:04 -04:00
Jarrett Cruger
ed9e12b0ed [dist] Version bump. 1.1.6 2014-07-17 10:57:38 -04:00
Jarrett Cruger
5f838541cb do proper checking for a pass not existing. fixes #671 2014-07-17 10:56:53 -04:00
Eric Baer
e336b52629 Remove changelog - it was not maintained 2014-07-10 11:59:43 -04:00
Jarrett Cruger
7104a7c023 [dist] Version bump. 1.1.5 2014-07-09 23:27:35 -04:00
Jarrett Cruger
d1baa3684e [api] also emit the target on a proxy error 2014-07-08 16:12:57 -04:00
Jarrett Cruger
e50846b967 Merge pull request #666 from eiriklv/master
Fix simple-balancer example
2014-07-08 12:08:51 -04:00
Eirik Langholm Vullum
9df4bc1e12 fix balancer example 2014-07-04 23:37:23 +02:00
Jarrett Cruger
f6bac7b257 Merge pull request #658 from RushPL/master
Added proxyTimeout option and two tests for timeout
2014-06-10 13:11:13 -04:00
Damian Kaczmarek
48d46e6750 Merge branch 'master' of github.com:RushPL/node-http-proxy 2014-06-10 19:04:48 +02:00
Damian Kaczmarek
7b79a7409a Change name targetTimeout to proxyTimeout 2014-06-10 19:04:12 +02:00
Damian Kaczmarek
4193d3bd74 Fix #657 2014-06-10 01:50:59 +02:00
Damian Kaczmarek
159ca83652 Fix #657 2014-06-10 01:50:13 +02:00
Damian Kaczmarek
0f243516e1 Added targetTimeout option and two tests for timeout 2014-06-10 01:35:53 +02:00
unknown
431aba79d8 Trimming contents of distributed npm package.
https://www.npmjs.org/doc/developers.html#Keeping-files-out-of-your-package
Keep deployments as small as they can be.
2014-05-21 14:10:52 -07:00
Jarrett Cruger
7cb98a4e41 [dist] Version bump. 1.1.4 2014-05-11 19:03:07 -04:00
Jarrett Cruger
5ebf9833c8 Merge pull request #642 from bruce-one/proxyRes-req-res
`proxyRes` event, provide access to the req and res objects
2014-05-11 19:01:05 -04:00
Bryce Gibson
1385635e18 Add a test for the proxyRes event 2014-05-12 08:44:02 +10:00
Bryce Gibson
1213e46b1b Add the req and res objects to the proxyRes event 2014-05-12 08:22:54 +10:00
Jarrett Cruger
c472527ea6 [dist] Version bump. 1.1.3 2014-05-11 01:03:39 -04:00
Jarrett Cruger
ccad177954 [minor] style 2014-05-11 01:02:35 -04:00
Jarrett Cruger
896ee7c9c3 Merge pull request #640 from jayharris/master
Don't override connection header if Upgrading
2014-05-09 23:25:45 -04:00
Jay Harris
8aa7c519b1 Adding test cases on preventing upgrade override 2014-05-09 22:49:23 -04:00
Jay Harris
d637b96420 Don't override connection header if Upgrading 2014-05-09 20:48:30 -04:00
Brett Kochendorfer
4947484806 Update README.md for benchmarks
Remove number of requests flag from `wrk` as it no longer exists. Swapped out for 5 minute duration.
2014-04-20 20:34:08 -05:00
Jarrett Cruger
c54278bd3b [dist] Version bump. 1.1.2 2014-04-14 13:17:58 -04:00
Jarrett Cruger
61c8734e8b [fix test] handle proxy error since we are properly aborting the proxy Request 2014-04-14 13:17:18 -04:00
Jarrett Cruger
77a1cff9bc [fix] handle error on incoming request as well and properly abort proxy if client request is aborted 2014-04-14 13:08:10 -04:00
Jarrett Cruger
d908e2ad61 [dist] Version bump. 1.1.1 2014-04-10 20:03:06 -04:00
Jarrett Cruger
4f07dc220d [fix] let user make the decision on what to do with the buffer 2014-04-10 20:02:46 -04:00
Jarrett Cruger
97ceeb37d0 [dist] Version bump. 1.1.0 2014-04-09 13:38:40 -04:00
Jarrett Cruger
8b48a9fdab [api] emit a start an an end event 2014-04-09 13:38:13 -04:00
Jarrett Cruger
c6b7a7919f [fix] always be an eventemitter for consistency fixes #606 2014-04-09 13:37:27 -04:00
Jarrett Cruger
7e5feec34f Merge pull request #616 from hipstern/patch-1
Update UPGRADING.md
2014-04-06 02:41:27 -04:00
hipstern
d658c9fa39 Update UPGRADING.md
Fixing a typo
2014-04-05 11:05:17 -07:00
Jarrett Cruger
eca765a856 [minor] missing angle bracket 2014-03-26 22:48:35 -04:00
Jarrett Cruger
07fceb7c7a [dist] Version bump. 1.0.3 2014-03-26 22:41:51 -04:00
Jarrett Cruger
ece85b4e1b [doc] update docs with toProxy option 2014-03-26 22:36:59 -04:00
Jarrett Cruger
5251a238e7 Merge branch 'customizeOutgoingAddress' of github.com:sberan/node-http-proxy into sberan-customizeOutgoingAddress
Conflicts:
	lib/http-proxy.js
	lib/http-proxy/common.js
2014-03-26 22:30:11 -04:00
Jarrett Cruger
89a22bc003 [fix] set connection to CLOSE in cases where the agent is false. 2014-03-26 22:07:09 -04:00
Jarrett Cruger
a7b16eb136 [api] add toProxy method to allow absolute URLs to be sent when sending to another proxy fixes #603 2014-03-26 21:59:10 -04:00
Jarrett Cruger
c22610af75 Merge pull request #592 from SkeLLLa/patch-1
Fix for #591
2014-03-11 18:03:12 -04:00
Alexander
99f757251b Fix for #591
Fix for proxy crash if `HOST` header is not defined bug https://github.com/nodejitsu/node-http-proxy/issues/591.
2014-02-26 15:12:38 +02:00
Sam Beran
e633b0f7e4 Add support for localAddress
When we make outgoing requests, we may want to bind to a specific local
address. This change allows the localAddress property to be specified
via the options object.
2014-02-11 15:01:03 -06:00
Jarrett Cruger
10670540ac Merge pull request #578 from xtreme-topher-bullock/patch-1
Add Repository field to package.json
2014-02-10 23:47:47 -05:00
@xtreme-topher-bullock / @xtreme-todd-ritchie
68fa17bbca @xtreme-topher-bullock - update package.json to have proper repository key and formatting 2014-02-10 10:07:00 -05:00
Topher Bullock
7923cf3c6b Add Repository field to package.json
Seeing "npm WARN package.json http-proxy@1.0.2 No repository field." makes me anxious and its such an easy action to add a repo field to the package.json.
2014-02-07 16:49:45 -05:00
Jarrett Cruger
81daf26a43 Merge pull request #575 from ozh/patch-2
Fix doc: option lines
2014-02-05 09:42:51 -05:00
྅༻ Ǭɀħ ༄༆ཉ
80f645c7c0 Fix doc: option lines 2014-02-05 15:03:36 +01:00
Jarrett Cruger
4bdc3e4f45 [dist] Version bump. 1.0.2 2014-01-28 14:34:25 -05:00
David Glasser
4c3ba74c4e Close outgoing ws if incoming ws emits error
Fixes #559, which contains a full reproduction recipe.
2014-01-28 13:58:09 -05:00
Jarrett Cruger
daad4703f3 [fix] replicate node core behavior and throw an error if the user does not add their own error listener 2014-01-28 12:32:43 -05:00
yawnt
b60673522b Merge pull request #566 from Septembers/patch-1
Update README.md
2014-01-28 05:54:27 -08:00
Sep
4ecc6e26ce Update README.md
Syntax error correction
2014-01-28 21:51:59 +08:00
Arnout Kazemier
8004f4e5fc [doc] Fix broken image in npm by using an absolute link 2014-01-28 11:25:24 +01:00
yawnt
3b2178d1f7 Merge pull request #560 from meteor/fix-ws-arg-order
Fix argument order for ws stream pass
2014-01-27 23:04:09 -08:00
David Glasser
0b223abb65 Fix argument order for ws stream pass
head and error handling was broken before this commit.
2014-01-22 15:28:23 -08:00
Jarrett Cruger
7a53ec2fd6 Merge pull request #558 from p-a-c-o/master
Extend listen to enable IPv6 support.
2014-01-21 11:49:46 -08:00
p-a-c-o
96ea631fb6 Extend listen to enable IPv6 support. 2014-01-21 20:35:49 +01:00
yawnt
3e47c2485c Merge pull request #556 from alevicki/fix/before_and_after
Fix before and after type check
2014-01-20 09:55:28 -08:00
alevicki
c5ec1836b2 Fix before and after type check 2014-01-20 10:24:53 -06:00
yawnt
e936d186b6 [fix] closes #555 2014-01-19 11:49:26 +01:00
yawnt
68c5512303 [dist] bump v1.0.1 2014-01-17 22:19:42 +01:00
yawnt
689459fe46 typo 2014-01-17 22:18:54 +01:00
yawnt
53a2653b5e [fix] closes #553 2014-01-17 22:18:20 +01:00
yawnt
3330e125aa Merge pull request #552 from nodejitsu/caronte-merge
Http proxy 1.0
2014-01-16 07:34:37 -08:00
yawnt
d6d2d0c882 [fix] remove caronte 2014-01-16 16:28:08 +01:00
yawnt
d4942e52e7 Merge pull request #551 from nodejitsu/caronte
Caronte
2014-01-16 07:25:15 -08:00
yawnt
d23353d980 [fix] ee3 error handling 2014-01-16 15:05:52 +01:00
yawnt
4351ed1c86 [fix] closes #547 2014-01-16 15:03:44 +01:00
yawnt
0ba4fa8e5e Merge pull request #549 from mmoulton/caronte
Only emit response if a valid server is present
2014-01-14 01:23:28 -08:00
Mike Moulton
969a623542 Only emit response if a valid server is present 2014-01-14 00:45:42 -07:00
yawnt
0b642d4cf7 Merge remote-tracking branch 'origin/caronte' into caronte-merge 2014-01-08 10:19:11 +01:00
yawnt
a4ee8f9d82 [nuke] old files 2014-01-08 10:19:06 +01:00
yawnt
2c8edc170d Merge pull request #539 from nodejitsu/fix-before-after
[fix] add `type` to before and after to grab correct `passes`, fixes #537
2013-12-29 14:20:46 -08:00
Jarrett Cruger
c47adac391 [fix] add type to before and after to grab correct passes, fixes #537 2013-12-29 16:00:30 -05:00
yawnt
c17b591b7d Merge pull request #536 from nodejitsu/caronte-api
export the proxy itself from the main require
2013-12-28 10:58:28 -08:00
Jarrett Cruger
6fa23e11f6 [fix] comments 2013-12-27 19:04:44 -05:00
Jarrett Cruger
182c76cd23 [api] export the httpProxy.Server as the main export but preserve the createServer factory 2013-12-27 19:01:28 -05:00
yawnt
e5991519db [docs] upgrade UPGRADING.md 2013-12-27 23:38:48 +01:00
indexzero
840f6d8d29 [dist] Version bump. 0.10.4 2013-12-27 00:05:18 -08:00
indexzero
a81dd8d53e [dist] Bump dependencies. 2013-12-27 00:04:25 -08:00
vinodsr
8eb6780f87 added option for eventlistenerCount(max) 2013-12-27 00:01:15 -08:00
vinodsr
1333c0cc62 added unlimited listeners to the reverproxy event obj. 2013-12-27 00:01:07 -08:00
indexzero
2d42709c32 [fix] Optimize fix for x-forwarded-for-port. 2013-12-26 23:59:48 -08:00
blahed
d4e91ebc33 determine x-forwarded-port from host header
`req.remotePort' returns the ephemeral port, which is not useful.
node v0.10.0 added `req.localPort' which returns what we want, but
we want to maintain backwards compatibility. Fixes #341 & #227
2013-12-26 23:52:05 -08:00
indexzero
7e8041d2b6 [dist minor] 2 space indents next time @samalba 2013-12-26 23:50:19 -08:00
Sam Alba
8332e74420 Prevent headers to be sent twice 2013-12-26 23:48:06 -08:00
Phil Jackson
145798062e Put the arguments the right way around in the README. 2013-12-26 23:39:49 -08:00
Phil Jackson
7c8ecc8ea8 Put the arguments the right way around in emitter. 2013-12-26 23:39:44 -08:00
Phil Jackson
25bb3bfa70 Update the README to describe middleware err handler. 2013-12-26 23:39:40 -08:00
Phil Jackson
bc12ca3939 Emit middlewareError when on middleware error.
Now it's possible to pass an Error object to next() and have it handled
in a custom way that's suitable to your application.
2013-12-26 23:39:37 -08:00
Jan Jongboom
781c038f2b Fix for #458. Host header may cause some sites not to be proxyable with changeOrigin enabled 2013-12-26 23:35:47 -08:00
Charlie Robbins
d60f1a9353 Merge pull request #521 from derekdreery/patch-1
Update README.md
2013-12-26 23:10:25 -08:00
yawnt
162a42f58f [fix] legacy 2013-12-20 21:33:49 +01:00
yawnt
9243444ac0 fix docs 2013-12-20 20:24:49 +01:00
yawnt
db12f6c24e [docs] add UPGRADING.md 2013-12-20 20:22:40 +01:00
yawnt
16828a9915 Merge pull request #520 from nodejitsu/better-examples
Better examples
2013-12-18 10:03:46 -08:00
cronopio
e2a5d513ca Set travis to run npm test while we fix coveralss.io integration 2013-12-18 12:18:59 -05:00
cronopio
d83fdf69a1 [tests] disabled the examples-test by now 2013-12-18 12:18:59 -05:00
cronopio
bc236d7e95 [tests] Added a test case for run all the examples
* I changed all the ports across examples to be different and can run at same time
2013-12-18 12:18:58 -05:00
cronopio
c82ff2c3c0 [examples] updated bodyDecoder middleware example 2013-12-18 12:18:58 -05:00
cronopio
d7064f2e1e [examples] added error-handling using callbacks and HTTP-to-HTTPS examples 2013-12-18 12:18:58 -05:00
cronopio
de3ff11656 [examples] updated the modifyResponse-middleware example 2013-12-18 12:18:58 -05:00
cronopio
2142c506e0 [examples] add example of gzip using the connect.compress() middleware 2013-12-18 12:18:58 -05:00
cronopio
e592c53d1a [examples] fix the copyright header of example files 2013-12-18 12:18:58 -05:00
cronopio
d85ccdd333 [examples] added package.json with the dependencies needed by examples 2013-12-18 12:18:58 -05:00
cronopio
831a44b3c8 [examples] updated balancer examples 2013-12-18 12:18:58 -05:00
cronopio
ed8c9eeba9 [examples] updated websockets examples 2013-12-18 12:18:58 -05:00
cronopio
588327c2c4 [examples] updated old examples 2013-12-18 12:18:58 -05:00
cronopio
e02317ce86 [examples] updated old proxy examples 2013-12-18 12:18:58 -05:00
cronopio
b726116134 [examples] update forward and custom error examples 2013-12-18 12:18:58 -05:00
cronopio
7e44d3669b [examples] update old examples 2013-12-18 12:18:58 -05:00
cronopio
bdeabb767a [examples] deleted this examples 2013-12-18 12:18:58 -05:00
cronopio
cfd417de23 [tests] fix tests set correct host headers 2013-12-18 12:17:41 -05:00
cronopio
c4d56a5faf [tests] fix test using undefined url 2013-12-18 11:50:49 -05:00
yawnt
4d65280ea3 [fix] remove old reminescence 2013-12-18 13:30:02 +01:00
yawnt
36389384cb Merge pull request #416 from MiLk/req-path
Send path in req.path and not the url
2013-12-18 03:49:59 -08:00
yawnt
9e74a633a7 [fix] closes #529 2013-12-18 12:45:41 +01:00
yawnt
97e4600e94 [fix] fixes #341 2013-12-18 12:33:23 +01:00
cronopio
03880d8d06 [docs] typos, typos everywhere... 2013-12-13 13:06:19 -05:00
cronopio
0393b5da99 [docs] more short examples to the Readme 2013-12-13 12:58:37 -05:00
cronopio
ae0faef5aa [docs] Update readme with more how to 2013-12-09 12:33:16 -05:00
derekdreery
ef8150af95 Update README.md
I struggled to get the section about using https to http with two certificates to work, because I didn't understand where the myCert etc. came from. Once I realised they had to be created by the user I could get it working. I want to save someone else the time it took me.
2013-11-21 17:33:19 +00:00
cronopio
584ce76e75 [misc] add a LICENSE file 2013-11-19 20:03:23 -05:00
yawnt
10c0f11b68 [fix] remove duplicate 2013-11-19 20:05:46 +01:00
yawnt
83367e7e91 Merge pull request #518 from bfirsh/fix-ws-error-handling
Fix websocket error handing
2013-11-18 15:27:23 -08:00
Ben Firshman
cb7af4f4d7 Fix websocket error handing
Websockets have sockets, not responses.
2013-11-18 23:06:56 +00:00
yawnt
dcb873ad99 [doc] update README.md 2013-11-13 18:29:15 +01:00
cronopio
54eceb4a86 Merge branch 'caronte' of github.com:nodejitsu/node-http-proxy into caronte 2013-11-11 11:22:23 -05:00
cronopio
7a3f6dfbcc [examples] added forward example 2013-11-11 11:22:04 -05:00
cronopio
04c10113f7 [examples] added concurrent proxy example 2013-11-11 11:14:42 -05:00
yawnt
961d2f9400 [fix] support target and forward 2013-11-08 20:56:26 +01:00
cronopio
bbe3bfdf98 [tests] added test HTTPS to HTTP using own server 2013-11-07 21:27:50 -05:00
cronopio
31d919b0a3 [tests] added HTTPS to HTTPS test 2013-11-07 18:06:51 -05:00
cronopio
6a6dfbb79d [examples] fix styling and bad spaces 2013-11-07 18:06:12 -05:00
cronopio
a467b7b4a9 [examples] fixed https examples 2013-11-07 17:20:28 -05:00
cronopio
fd42dcef01 [tests] https test pass, fix #511. Exposed the rejectUnauthorized flag 2013-11-07 15:09:37 -05:00
cronopio
a2b1f0a4c9 [tests] disable test, by now is not throwing without options 2013-11-07 15:06:45 -05:00
yawnt
d0862aff0c [fix] merge #495, thanks @glasser 2013-11-07 19:13:09 +01:00
yawnt
cde08fb2ee [fix] closes number #487 2013-11-07 19:05:59 +01:00
yawnt
590bb604da [fix] _ because it is unused 2013-11-07 19:00:01 +01:00
Jarrett Cruger
b8c6397a94 [fix] pass proper options object that extend the global options and parse the per proxy args into options. fixes #510 2013-11-05 16:30:39 -05:00
yawnt
dda6f7a45a [feature] add emit proxyRes 2013-11-05 17:44:04 +01:00
cronopio
8085178dc2 [tests] Using target field, tests now pass. We are missing the tests using forward field 2013-10-29 16:46:27 -05:00
yawnt
1204a35e46 [fix] support buffer 2013-10-29 18:12:23 +01:00
cronopio
f720e36b42 Merge branch 'caronte' of github.com:nodejitsu/node-http-proxy into caronte 2013-10-28 13:19:35 -05:00
cronopio
33a2462d28 [wip] Initial HTTPS->HTTP test, updated https-secure example. Work in progress, need to add more https tests 2013-10-28 13:18:21 -05:00
yawnt
e3f8d5fdbe [feature] add buffer support 2013-10-26 17:20:30 +02:00
cronopio
a1b25a123b [examples] update the error-handling example using the new error handle way 2013-10-22 17:04:18 -05:00
cronopio
920f1e7707 [tests] this test is already in web-incoming tests 2013-10-22 16:09:11 -05:00
cronopio
c75d06c5f9 [tests] now each test use a different port to avoid some slow opening and closing ports 2013-10-22 15:57:52 -05:00
cronopio
d60353f80b [tests] tests fixed 2013-10-21 23:22:59 -05:00
cronopio
02df9a33c5 [fix] fix the correct order of arguments in ws-incoming passes 2013-10-21 23:22:32 -05:00
cronopio
881c7e62e0 [tests] this file is not necessary anymore 2013-10-21 21:22:39 -05:00
cronopio
cc09ae6a34 [fix] use the correct arguments order 2013-10-21 21:19:52 -05:00
cronopio
7c72f3b407 [tests] move contributions of @mmoulton to correct place 2013-10-21 21:11:19 -05:00
mmoulton
0bfb9be418 Fixed issue where error callback would not invoke, including new test cases. Added req/res values to error events.
Conflicts:
	lib/http-proxy/passes/web-incoming.js
2013-10-21 17:36:20 -05:00
cronopio
5d66ce11bb [fix] minor typo 2013-10-21 14:51:45 -05:00
cronopio
5e130de854 Revert "[fix] fixed passes functions, now 'this' can be used and options are stored on 'this.options'"
This reverts commit 9b3e1eb247df29d18ea299ff4ebb2f10eeb71269.
2013-10-21 14:49:39 -05:00
cronopio
babdf531fe Revert "[fix] fixed options and server reference to can access them from passes functions"
This reverts commit 90fb01d38ac5af7ef395547b24e985b6f63b4abc.
2013-10-21 14:45:03 -05:00
cronopio
2bf20d61d5 Revert "[tests] fix test to use the new way to pass options"
This reverts commit 52ecd52ee5aa78603e44ba8d5ff9187410351622.
2013-10-21 14:44:49 -05:00
cronopio
52ecd52ee5 [tests] fix test to use the new way to pass options 2013-10-21 03:59:14 -05:00
cronopio
9b3e1eb247 [fix] fixed passes functions, now 'this' can be used and options are stored on 'this.options' 2013-10-21 03:46:30 -05:00
cronopio
90fb01d38a [fix] fixed options and server reference to can access them from passes functions 2013-10-21 03:26:54 -05:00
cronopio
1d1ee88582 [tests] the options got a problem and this test probe that timeout is not being set 2013-10-21 03:25:47 -05:00
Jarrett Cruger
e4450132e2 Merge pull request #502 from jamesmanning/patch-1
attempting to fix links to 2 source locations in README.md
2013-10-20 02:19:58 -07:00
James Manning
bbe2b2788a attempting to fix link to valid options properties
Current link for 'valid properties are available here' goes to url:

https://github.com/nodejitsu/node-http-proxy/blob/caronte/tree/master/lib/http-proxy.js#L26-L39

The url works fine if 'tree/master/' is removed, so this is trying to remove that part of the relative path.

The same removal of 'tree/master/' is being made for the 'available here' link that is preceded by "When a request is proxied it follows two different pipelines" since it suffers the same issue.
2013-10-19 23:43:22 -04:00
cronopio
86750c7e59 [tests] throw error when no options, ALL TESTS PASSING! YAY 2013-10-10 11:04:17 -05:00
cronopio
c65ffbb976 [tests] fixed inherits problem and listen for the correct event 2013-10-09 12:40:05 -05:00
cronopio
a7042132c8 [tests] fixing tests, fixed some typos and changed how passes are stored 2013-10-09 12:00:42 -05:00
cronopio
b333e63648 [tests] fixing minor typos 2013-10-09 11:04:41 -05:00
cronopio
c9f5772fc1 [tests] remove caronte and use http-proxy for file names 2013-10-09 10:49:13 -05:00
yawnt
a9f9e21eda [fix] 2013-10-09 17:37:20 +02:00
yawnt
3d8e5383cd [fix] better code 2013-10-09 17:31:02 +02:00
yawnt
5a1504f076 [fix] minor typo 2013-10-09 17:28:39 +02:00
yawnt
c7924e01f9 [fix] callback as optional error handler 2013-10-09 17:23:44 +02:00
yawnt
601dbcbfe9 [fix] refactor error handling 2013-10-09 16:59:03 +02:00
yawnt
b79bd29d5e [feature] start working on the new server 2013-10-08 22:24:16 +02:00
3rd-Eden
a51b062278 [minor] Remove duplicate dependencies and cleanup of the scripts 2013-10-01 09:14:37 +02:00
yawnt
8269eca2bb [fix] tests 2013-09-26 11:13:16 +02:00
yawnt
1436b715ae Merge pull request #492 from nodejitsu/1.0.0-dev
[merge] rename codename to actual project name
2013-09-26 02:05:02 -07:00
indexzero
bb0d28c587 [refactor minor] s/caronte/http-proxy/ or s/caronte/httpProxy/ where appropriate. 2013-09-26 03:37:08 -04:00
indexzero
f7f5fa727e [dist doc] Added documentation for consistent benchmarking of node-http-proxy 2013-09-26 03:27:55 -04:00
yawnt
455f97e14c [fix] finished jshint fixes 2013-09-25 15:11:04 +02:00
yawnt
17399e7c3e [fix] more jshint intendation 2013-09-25 15:08:27 +02:00
yawnt
0aeaba7fe6 [fix] remove trailing whitespaces 2013-09-25 14:58:59 +02:00
yawnt
94ec6fa5ce Merge pull request #484 from srossross/error_handling
[merge] Added error handling example
2013-09-22 04:22:40 -07:00
srossross
32a40889ce DOC: Added error handling example 2013-09-21 13:15:34 -07:00
yawnt
32dcb0449c Merge pull request #482 from srossross/caronte
[merge] https & agent
2013-09-21 01:49:00 -07:00
cronopio
4a517fbe6e [readme] add links to badges on readme, fix #483 2013-09-20 20:47:02 -05:00
cronopio
5dcdf2b36c [doc] added some documentation to functions and comments to understand better the code 2013-09-20 19:28:53 -05:00
srossross
7ad5c0f993 DOC: updated readme
@yawnt I think it is good to go. If you have any other tests in mind let me know.
2013-09-18 09:07:56 -07:00
srossross
39b0c46a69 TEST: added agent and header tests 2013-09-17 15:29:48 -07:00
srossross
a350fadea6 FIX: tests. still need to add more tests tho 2013-09-17 15:06:22 -07:00
srossross
1b5fb1d8fc DOC: updated readme with options 2013-09-17 15:00:28 -07:00
srossross
12cda561af ENH: updated agent options in common.setupOutgoing 2013-09-17 14:52:53 -07:00
srossross
f566a42e51 ENH: updated examples 2013-09-17 14:51:56 -07:00
srossross
4ee96ddd66 Merge branch 'agent' into caronte 2013-09-17 11:51:17 -07:00
srossross
1c7ace26c5 ENH: updated example 2013-09-17 11:50:04 -07:00
srossross
7d840d3515 ENH: added 'headers' to available options, to add or overwrite existing headers 2013-09-17 11:45:41 -07:00
srossross
427d8d8536 ENH: added new https example, needs to be simplified before merge
updated existing example with log output
2013-09-17 11:44:09 -07:00
srossross
13741a823f ENH: updated https and agent option
Removed logic from createProxyServer and put it into setupOutgoing.

Conflicts:
	lib/caronte.js
2013-09-17 11:23:12 -07:00
yawnt
69f126b34c [fix] space 2013-09-17 20:15:34 +02:00
yawnt
72a89eab8b [fix] link 2013-09-17 20:14:16 +02:00
yawnt
1ceea3e5f9 [docs] test badge 2013-09-17 20:11:03 +02:00
yawnt
f36cb4d5a1 [fix] coveralls.. will it work? 2013-09-17 19:30:59 +02:00
yawnt
ca092635e7 [test] remove chunked on http1.0 2013-09-17 16:32:55 +02:00
yawnt
8663ac1c43 [fix] do not send chunked responses to http1.0 clients 2013-09-17 16:28:54 +02:00
yawnt
afc4d0931f [fix] pooled connections, closes #478 2013-09-17 12:14:52 +02:00
yawnt
6b61878759 [docs] add travis build status 2013-09-17 11:24:35 +02:00
yawnt
16a4d9da11 [test] added tests for web-outgoing.js 2013-09-17 11:20:18 +02:00
yawnt
2c10f256b6 [fix] write connection header 2013-09-17 10:59:45 +02:00
yawnt
611a1b1961 [fix] add 0.10 link, fixes #459 2013-09-17 10:38:25 +02:00
yawnt
031452e400 [fix] closes #473 2013-09-17 10:31:52 +02:00
yawnt
9efa40a9d2 Merge pull request #476 from nodejitsu/caronte-tests
[merge] caronte tests
2013-09-17 01:23:55 -07:00
cronopio
8eff1a1f26 [test][misc] remove node@0.8 to test on travis 2013-09-16 21:40:42 -05:00
cronopio
10a0db4f0d [tests] added test for socket.io proxying 2013-09-16 21:37:49 -05:00
cronopio
0602500230 [tests] added .travis.yml file 2013-09-16 21:00:34 -05:00
cronopio
02007ed0fb [tests] added tests for websockets 2013-09-16 20:59:10 -05:00
cronopio
40902506af [tests] fix code coverage, changed pattern on blanket options 2013-09-16 19:37:28 -05:00
cronopio
7e25bded27 [tests] removed unused tests 2013-09-16 19:04:49 -05:00
Jarrett Cruger
c01fd2c54e Merge pull request #475 from srossross/fix/ws_err_event
FIX: ws error event
2013-09-16 17:04:38 -07:00
cronopio
dc9d7e5452 [tests] drop the test of own streams, moved the usable tests 2013-09-16 18:59:48 -05:00
srossross
7b9169c8c5 FIX: ws error event 2013-09-16 16:42:53 -07:00
cronopio
1cb967b90a [tests] fixed according new refactor and added test to common.setupSocket() 2013-09-16 17:27:06 -05:00
cronopio
5bb83b967e [tests] make the tests run with the last refactor 2013-09-16 16:50:30 -05:00
cronopio
275a5192fa [fix] typo 2013-09-16 16:49:51 -05:00
cronopio
f1aeb0500c [misc] use the local mocha instead the global 2013-09-16 15:26:44 -05:00
yawnt
da9de7034a [docs] fix syntax highlighting 2013-09-16 22:12:52 +02:00
yawnt
38e6d7cd54 [merge] PR #470 2013-09-16 22:02:14 +02:00
yawnt
469b0d4e9f [fix] add 0.10 compatibily.. closes #474 2013-09-16 21:36:09 +02:00
Maciej Małecki
9f3508805a Merge pull request #472 from glasser/patch-1
Fix accidental write to global variable.
2013-09-16 12:01:27 -07:00
David Glasser
dfdedf23b7 Fix accidental write to global variable. 2013-09-16 11:33:57 -07:00
srossross
bd106d69f0 Updated readme 2013-09-16 11:24:00 -07:00
srossross
07091b5077 ENH: updated README and added examples file. 2013-09-16 11:21:20 -07:00
srossross
edd8e2f04e ENH: updated readme with an example 2013-09-16 11:01:34 -07:00
srossross
ef946a7697 ENH: updated target and forward options so that a string may be specified 2013-09-16 10:49:53 -07:00
srossross
268afe34bb ENH: updated ws and web functions to use the global options object as a base
even if request options is specified. request options will over write any global options in a conflict
2013-09-16 10:37:11 -07:00
srossross
1b867a7f59 ENH: added error events 2013-09-15 15:20:51 -07:00
yawnt
29afab4488 [fix] headers, closes #469 2013-09-15 22:07:35 +02:00
yawnt
e08d4edad3 [fix] write status 2013-09-15 18:02:00 +02:00
yawnt
60de543d04 [fix] headers, fixes #467 2013-09-15 17:55:41 +02:00
yawnt
adc5be020c [fix] opts 2013-09-15 17:19:07 +02:00
yawnt
0637322d96 [fix] url 2013-09-15 15:33:48 +02:00
yawnt
4d3a4e1ee7 [fix] readme 2013-09-15 15:30:05 +02:00
yawnt
dd0f7b8876 [docs] logo 2013-09-15 15:07:39 +02:00
yawnt
d7078e2fdd [fix] layout 2013-09-15 15:07:09 +02:00
yawnt
ee3cc38066 [fix] new logo 2013-09-15 15:05:22 +02:00
yawnt
aaff1966e4 [fix] move logo 2013-09-15 15:01:30 +02:00
yawnt
57abb7f26c [fix] move logo 2013-09-15 15:00:53 +02:00
yawnt
8b05626eed [docs] add logo 2013-09-15 14:59:55 +02:00
yawnt
98f29bdcfc [merge] text 2013-09-15 14:58:35 +02:00
yawnt
4c2f2f3b9a [logo] 2013-09-15 14:57:19 +02:00
yawnt
c9945dd370 Merge pull request #14 from sateffen/master
[fix] 2 spelling mistakes
2013-09-15 04:46:32 -07:00
sateffen
5823842194 [Fix] 2 spelling mistakes 2013-09-15 13:39:38 +02:00
yawnt
d1663549ec [fix] default port 2013-09-15 13:18:21 +02:00
yawnt
18341d5597 [fix] console 2013-09-15 13:07:24 +02:00
yawnt
26c4c43a06 [fix] proxying to https 2013-09-15 13:06:39 +02:00
yawnt
3c91ed3d26 [fix] proxy to http(s) 2013-09-15 13:03:51 +02:00
yawnt
46fe81e11a Merge pull request #11 from jcrugzz/https-req-ws
[fix] add ability to proxy websockets over HTTPS
2013-09-15 02:22:49 -07:00
Jarrett Cruger
92de6a6f95 [fix] add ability to proxy websockets over HTTPS 2013-09-14 20:46:05 -04:00
yawnt
6e77cd3909 [fix] do not call .end 2013-09-15 00:43:01 +02:00
yawnt
7599cee3fd [fix] minor 2013-09-14 22:52:45 +02:00
yawnt
dad211e71c keepalive sockets 2013-09-14 22:52:22 +02:00
yawnt
63b016c8ef [fix] yawnt baaaka .. fixes #8 2013-09-14 22:03:00 +02:00
yawnt
ec981c5b74 [fix] docs 2013-09-14 19:10:33 +02:00
yawnt
c4ddc4edd3 [fix] quote 2013-09-14 18:46:13 +02:00
yawnt
886a870707 [docs] readme 2013-09-14 18:44:39 +02:00
yawnt
8c8c455541 support forward 2013-09-14 14:00:31 +02:00
yawnt
031aa0fbf3 [fix] slimmer proxying 2013-09-14 13:33:38 +02:00
yawnt
07cfa6b981 [experiment] new api for proxying 2013-09-14 13:17:45 +02:00
yawnt
7d71a867a8 [fix] naming convention 2013-09-14 13:06:00 +02:00
yawnt
6a03e5f7cf [fix] remove stuff 2013-09-14 13:04:59 +02:00
yawnt
2a593664a5 [fix] naming 2013-09-14 13:02:28 +02:00
yawnt
893100972c [fix] naming 2013-09-14 13:01:53 +02:00
yawnt
79a14acfd2 [feature] websocket support 2013-09-14 12:48:53 +02:00
yawnt
f97c0c6167 write 2013-09-14 10:22:31 +02:00
yawnt
1a7bef0cda mm test file 2013-09-14 10:06:03 +02:00
yawnt
e45bfd66a2 stuff 2013-09-13 23:38:12 +02:00
yawnt
a74cd85c8a socket.io stuff 2013-09-13 20:49:52 +02:00
yawnt
4a4607d075 support websockets 2013-09-13 20:06:51 +02:00
yawnt
0fb33810f5 merge with @cronopio 2013-09-13 19:08:34 +02:00
yawnt
c9cd6d2ad3 [fix] make @mmalecki a happy camper 2013-09-13 19:07:34 +02:00
cronopio
8b3fe32f6a [tests] added the ws passes test and the streams webscokets test 2013-09-10 19:36:19 -05:00
cronopio
e0faaaf811 [fix] minor and short fixes 2013-09-10 19:31:47 -05:00
yawnt
1993faf8a4 new error propagation - follows 2013-09-05 17:45:03 +02:00
yawnt
3a39e444ff new error propagation 2013-09-05 17:44:23 +02:00
yawnt
07551c63e4 websocket draft 2013-09-05 17:28:25 +02:00
cronopio
79f7f99528 [lib] initial draft to websockets passes 2013-09-03 14:09:35 -05:00
yawnt
4480699d3a [fix] use some 2013-09-03 20:57:22 +02:00
yawnt
a6256cac1d [fix] short circuit 2013-09-03 20:56:18 +02:00
cronopio
b85aa16e75 [test] test onError part, proxying to no where 2013-08-28 14:01:55 -05:00
cronopio
27df8d72ad [test] testing the onResponse proxy method 2013-08-28 13:45:09 -05:00
yawnt
abf1d90fdf [fix] use agent pool 2013-08-28 15:22:04 +02:00
yawnt
c9612798f1 [test] proxystream test 2013-08-28 14:58:57 +02:00
yawnt
8fc3389367 [test] add test for forwardstream 2013-08-28 14:49:27 +02:00
yawnt
f4e9945856 Merge pull request #3 from yawnt/tests
Tests
2013-08-28 05:18:08 -07:00
cronopio
2fac7b9b00 [test] added the lib/caronte/streams/forward.js initial test, one test pending 2013-08-26 16:34:32 -05:00
cronopio
c02b721321 [test] passes/web.js XHeaders func 2013-08-26 00:21:30 -05:00
yawnt
d40e4beb62 [test] passes/web.js (first 2 funcs) 2013-08-21 17:37:38 +02:00
yawnt
356f43d719 [fix] ProxyStraem now works 2013-08-20 17:32:29 +02:00
yawnt
d4f0da898e [fix] some stuff start debugging proxystream 2013-08-20 16:09:37 +02:00
yawnt
9ab8749a9b [feature] started working on error propagation, kinda sucks, gotta think it over 2013-08-10 20:41:25 +02:00
yawnt
bd3df45010 [fix] woops 2013-08-09 20:52:55 +02:00
yawnt
2e7343d728 [fix] making @jcrugzz a happy camper 2013-08-09 20:52:21 +02:00
yawnt
6a4294cbdf [feature] implement _write and _read 2013-08-09 19:40:40 +02:00
yawnt
4f24664e8a [api] add draft for proxystream 2013-08-09 19:37:58 +02:00
yawnt
cedc5c4bd2 [tests] add more tests 2013-08-09 19:13:44 +02:00
yawnt
335af81d02 [minor] remove coverage 2013-08-09 18:59:20 +02:00
yawnt
a255f984fe [fix] tests 2013-08-09 18:58:56 +02:00
yawnt
16eacfa961 [test] started writing tests 2013-08-03 16:54:48 +02:00
yawnt
004a46c09d [test] COVERAGE 2013-08-03 16:44:23 +02:00
yawnt
34f16e7464 [fix] making @stoke a happy camper 2013-08-03 15:56:05 +02:00
yawnt
d05af4af60 [refactor docs] add descriptions 2013-08-03 15:45:07 +02:00
yawnt
8273cb6461 [refactor] move to leaner architecture 2013-08-03 08:47:07 +02:00
yawnt
4d13156721 [dist] first 2013-08-01 10:50:39 +02:00
Maciej Małecki
ebbba73eda [test] Test on newer version of node 2013-06-20 15:37:48 +02:00
Maciej Małecki
2fd748fb61 [dist] Bump version to 0.10.3 2013-06-20 15:29:14 +02:00
Maciej Małecki
e1d384e769 [fix] Respect maxSockets from target options in RoutingProxy 2013-06-20 15:28:47 +02:00
Charlie Robbins
5ff2b6e1a1 Merge pull request #419 from Raynos/patch-1
Pass default certs to SNICallback example
2013-06-14 19:20:24 -07:00
Raynos
f5e1844abd Pass default certs to SNICallback example
Using only SNICallback to create a HTTPS / TLS server is bad. It means all non SNI clients can't do anything because there are no certs.

in v0.10 of node TLS server was updated to throw if you forgot to supply certs.

Which means that every HTTPS server needs to supply certs as a fallback for when SNI is not available.

 - closes #399
2013-05-10 17:55:01 -06:00
Emilien Kenler
0c753234c0 Send path in req.path and not the url
Signed-off-by: Emilien Kenler <hello@emilienkenler.com>
2013-05-04 22:48:50 +02:00
indexzero
de0928f616 [dist] Version bump. 0.10.2 2013-04-21 17:06:54 -04:00
indexzero
7fc39d77f4 [minor] Strip trailing whitespace. 2013-04-21 17:02:18 -04:00
indexzero
59b71c033f [minor] Style compliance. Fixes #402. 2013-04-21 17:01:20 -04:00
Ivan Jaramillo
985025c90f Add headers on 'handshake'
The headers in the 'handshake' event were not written to the socket, the client received data but not the headers.
2013-04-21 16:59:08 -04:00
Charlie Robbins
98f5c462ea Merge pull request #407 from GUI/master
Correct keep-alive responses to HTTP 1.0 clients
2013-04-21 13:25:35 -07:00
Nick Muerdter
daf53bd753 Don't test raw HTTP 1.0 requests over HTTPS. 2013-04-18 18:11:58 -06:00
Nick Muerdter
a29b5e8e28 Correct keep-alive responses to HTTP 1.0 clients.
Since the proxy requests comes from NodeJS's HTTP 1.1 request client, a
backend server may default to setting Connection: keep-alive in its
response. However, the real HTTP 1.0 client may not be able to
handle that.

Force HTTP 1.0 client's to Connection: close, unless the client
explicitly supports keep-alive.
2013-04-18 16:33:10 -06:00
indexzero
9c13ad46e4 [dist] Version bump. 0.10.1 2013-04-12 04:55:26 -04:00
Charlie Robbins
3763dc935f Merge pull request #370 from jmatthewsr-ms/master
Fix for slab buffer retention, leading to large memory consumption
2013-04-09 11:02:56 -07:00
indexzero
71183bf30b [dist] Version bump. 0.10.0 2013-03-18 01:53:12 -04:00
indexzero
8665f3cc60 [dist] Update CHANGELOG.md 2013-03-18 01:53:03 -04:00
Charlie Robbins
4335f49b0e Merge pull request #385 from nodejitsu/breaking-proxy-response
Change the emitter of the `proxyResponse` event
2013-03-17 22:51:50 -07:00
Charlie Robbins
ea10bb22d9 Merge pull request #383 from thefosk/master
Fixing a bug that generates an unexpected TypeError
2013-03-17 22:50:17 -07:00
indexzero
2620f06e2d [fix breaking] Emit the proxyResponse event on the HttpProxy instance to reduce listener churn and reference counts. 2013-03-18 01:49:01 -04:00
Charlie Robbins
3ebc795c33 Merge pull request #384 from No9/master
Mention Harmon used for response modifications in the readme
2013-03-16 07:56:26 -07:00
No9
4e42354e77 Harmon messsage 2013-03-16 12:17:54 +00:00
No9
35ba0db554 Harmon messsage 2013-03-16 12:17:35 +00:00
thefosk
c9b6895c5e Fixing the if statement as it lead to 'TypeError: Parameter 'url' must be a string, not undefined' in certain cases 2013-03-14 19:09:03 -07:00
indexzero
701dc698e3 [dist] Version bump. 0.9.1 2013-03-09 05:09:18 -05:00
indexzero
ea5e214522 [dist doc] Updated CHANGELOG.md for v0.9.1 2013-03-09 05:09:10 -05:00
indexzero
c78356e9cf [breaking] Ensure that webSocketProxyError also receives the error to be consistent with proxyError events. 2013-03-09 05:08:55 -05:00
indexzero
c68e038912 [dist] Version bump. 0.9.0 2013-03-09 04:59:53 -05:00
indexzero
133115c976 [doc dist] Update CHANGELOG.md for v0.9.0. 2013-03-09 04:59:41 -05:00
indexzero
ad213106d0 [dist] Update devDependencies 2013-03-09 04:59:19 -05:00
indexzero
ea0587a8f9 [minor] Small whitespace compliance. 2013-03-09 04:42:07 -05:00
indexzero
5d515e4728 [api test] Manually merge #195 from @tglines since that fork was deleted. Update tests to use new macros. Fixes #195. Fixes #60. 2013-03-09 04:20:05 -05:00
Mikkel Garcia
5e6be6ccf5 [doc] added comments to pathnameOnly block. 2013-03-09 03:18:15 -05:00
Mikkel Garcia
a1607c1684 pathnameOnly option documented in the Readme.md 2013-03-09 03:18:11 -05:00
Mikkel Garcia
46b078a98d pathnameOnly flag added. Ignores hostname and applies routing table to the paths being requested. 2013-03-09 03:18:07 -05:00
Niall O'Higgins
10f6b05775 add support for loading CA bundles
fix loop

typo

another typo *sigh*

this wasn't doing what I thought it was doing.
2013-03-09 03:12:58 -05:00
Niall O'Higgins
2c3650746c problem: don't want to run my server as root to bind to privileged ports (e.g. 80, 443).
solution: support privilege drop after socket bind via new --user <username> parameter.
2013-03-09 03:12:52 -05:00
pdoran
89d43c20dd Added timeout option and test to test new timeout parameter, added requestFail assertion. 2013-03-09 03:04:29 -05:00
indexzero
476cbe741f [minor] Move private helper to end of file. 2013-03-09 02:44:46 -05:00
indexzero
9be0af3166 [fix] Set "content-length" header to "0" if it is not already set on DELETE requests. Fixes #338. 2013-03-09 02:44:28 -05:00
indexzero
a89e2f2688 [fix] Do not use "Transfer-Encoding: chunked" header for proxied DELETE requests with no "Content-Length" header. Fixes #373. 2013-03-09 02:40:09 -05:00
indexzero
6a278b3dd8 [fix] http-proxy should not modify the protocol in redirect request for external sites. Fixes #359. 2013-03-09 02:35:50 -05:00
indexzero
3130665d9f [fix] Emit notFound event when ProxyTable location does not exist. Fixes #355. Fixes #333. 2013-03-09 02:29:58 -05:00
indexzero
4c1a2c1416 [fix] Make options immutable in RoutingProxy. Fixes #248. 2013-03-09 02:21:31 -05:00
colinmollenhour
b1c4bd61e8 Remove data event that is not needed after-all. 2013-03-09 01:48:42 -05:00
Colin Mollenhour
3b86a7aae3 Add 'proxyResponse' event so observer can modify response headers or abort response. 2013-03-09 01:48:37 -05:00
Colin Mollenhour
4c130f5dac Allow event observers to access upstream response headers and data. 2013-03-09 01:48:29 -05:00
indexzero
9cecd97153 [minor] s/function(/function (/ s/){/) {/ 2013-03-09 01:43:25 -05:00
indexzero
440013c263 [fix doc] Fix bad variable reference in README.md. 2013-03-09 01:36:57 -05:00
jpetazzo
ba65a485fc Fix typo which slipped in during patch clean-up 2013-03-09 01:21:30 -05:00
jpetazzo
ef66833c4d Fix truncated chunked responses 2013-03-09 01:21:21 -05:00
Charlie Robbins
af9eb06e47 Merge pull request #298 from Kami/connection_keep_alive_on_1_1
If HTTP 1.1 is used and backend doesn't return 'Connection' header, expicitly  return Connection: keep-alive.
2013-03-08 22:11:37 -08:00
indexzero
28a3b0a6f0 [fix] Remove special case handling of 304 responses since it was fixed in 182dcd3. Fixes #322. 2013-03-09 01:10:02 -05:00
Gilad Oren
ecb547223f Add tests for headers bug fixes 2013-03-09 01:05:27 -05:00
Yosef Dinerstein
ffe74ed299 - support unix donain sockets and windows named pipes (socketPath) on node 0.8.x. On node 0.6.x the support was opaque via port, but on the new node, socketPath should be set explicitely.
- avoid adding multiple headers with the same name
- fix bug in setting connection
2013-03-09 01:05:22 -05:00
Charlie Robbins
eee6babc98 Merge pull request #332 from ramitos/patch-1
add "with custom server logic" to the "Proxying WebSockets" section of the readme
2013-03-08 21:45:30 -08:00
indexzero
c6da760ca9 Revert "[fix minor] Prevent crashes from attempting to remove listeners more than once when proxying websocket requests."
This reverts commit a681493371ae63f026e869bf58b6fea682dc5de3.
2013-03-09 00:43:25 -05:00
indexzero
a681493371 [fix minor] Prevent crashes from attempting to remove listeners more than once when proxying websocket requests. 2013-03-09 00:40:00 -05:00
unknown
2055d0c8ec memory leak fix in closing of the scokets 2013-03-09 00:36:19 -05:00
indexzero
013cb2e0c2 [fix] Ensure response.headers.location is defined. Fixes #276. 2013-03-09 00:28:50 -05:00
indexzero
deca7565c5 [doc fix] Add undefined var in example. 2013-03-09 00:24:04 -05:00
Oscar Östlund
64efa7f929 Added comments 2013-03-09 00:23:41 -05:00
Oscar Östlund
83fbd42506 Added simple round robin example with websocket support 2013-03-09 00:23:36 -05:00
Otávio Ribeiro
9672b99271 cleanning 2013-03-09 00:20:46 -05:00
Otávio Ribeiro
8d8739999f cleanning 2013-03-09 00:20:42 -05:00
Otávio Ribeiro
31fc94aa5e working on x-forwarded-for 2013-03-09 00:20:38 -05:00
Otávio Ribeiro
133240937d working on x-forwarded-for 2013-03-09 00:20:33 -05:00
Otávio Ribeiro
916d44e3d2 Routing Proxy was not sending x-forward-*. Fixing It... 2013-03-09 00:20:26 -05:00
Charlie Robbins
025adc2912 Merge pull request #365 from adjohnson916/master
routing proxy 'this' reference bug?
2013-03-08 21:14:14 -08:00
Charlie Robbins
8b38c994a9 Merge pull request #374 from erasmospunk/master
fixed issue #364 'proxyError' event emitted twice
2013-03-08 21:11:56 -08:00
Charlie Robbins
c686ac7b01 Merge pull request #349 from jamie-stackhouse/patch-1
Misleading documentation for Websockets via .createServer
2013-03-08 20:49:05 -08:00
jamie-stackhouse
603106a13d Re-added previous description 2013-02-22 10:31:44 -04:00
jamie-stackhouse
ee6bbe0024 Change wording for handling websocket proxy events 2013-02-22 09:59:16 -04:00
Giannis Dzegoutanis
3b84e27ab4 remove offending code, final fix for issue #364 2013-02-12 20:43:22 +01:00
Giannis Dzegoutanis
43e5f33320 fixed issue #364 'proxyError' event emitted twice 2013-02-10 23:07:40 +01:00
Justin Matthews
d2888c83f5 Fix for retaining large slab buffers in node core 2013-01-24 15:44:06 -08:00
Anders Johnson
15afc23a27 fix 'this' reference in routing proxy listener bindings 2013-01-12 21:55:46 -06:00
Maciej Małecki
26d3646ff2 [dist] Bump version to 0.8.7 2012-12-23 00:56:23 +01:00
Maciej Małecki
223eacda85 [fix] Don't remove error listener after response ends
In some rare cases, `error` event might still be emitted after the
response has ended. This is (most likely) a bug in the `node` core.
2012-12-23 00:44:21 +01:00
Maciej Małecki
edfe869159 [fix] Handle errors on request object
Sometimes a request emits `error` event with a `Parse Error`.
2012-12-21 20:56:01 +01:00
Maciej Małecki
6cd78f6af9 [dist] Bump version to 0.8.6 2012-12-21 16:51:47 +01:00
Maciej Małecki
2a61ec85bd [fix] Handle socket errors 2012-12-13 00:02:54 +01:00
Maciej Małecki
7bc1a628fe [bench] More exact size display 2012-11-30 13:54:36 +01:00
Maciej Małecki
b81d9b71da [dist] Update devDependencies 2012-11-30 03:25:53 +01:00
Maciej Małecki
6797a2705a [bench] Add a benchmark for websockets throughput 2012-11-30 03:25:53 +01:00
Maciej Małecki
2bd9cd9adb [bench] Remove silly "benchmarks" 2012-11-30 03:25:53 +01:00
Charlie Robbins
8b3cfdaaea Merge pull request #337 from indutny/feature-304-end
http-proxy: 304 responses should emit 'end' too
2012-11-29 03:51:42 -08:00
Fedor Indutny
0fd5884a0f http-proxy: 304 responses should emit 'end' too 2012-11-21 12:21:55 +04:00
Maciej Małecki
22639b3781 [dist] Bump version to 0.8.5 2012-11-16 06:19:31 +01:00
Sérgio Ramos
03dbe115c2 add "with custom server logic" to the "Proxying WebSockets" section of the readme.md 2012-11-08 09:47:44 +00:00
Colton Baker
8a88774ecf [fix] Convert strings to numbers if possible in .createServer
Fixes #321
2012-11-06 17:47:47 -05:00
Maciej Małecki
b8c27ed565 [fix] Correctly kill test processes 2012-10-29 12:59:04 +01:00
Maciej Małecki
886a395429 [test] Delete invalid core test 2012-10-29 12:50:41 +01:00
Maciej Małecki
9042665ea9 [test] Stop testing on node v0.9, tests timeout 2012-10-28 14:43:15 +01:00
Maciej Małecki
41c9a9caad [test] Run core tests on npm test 2012-10-28 14:42:18 +01:00
Maciej Małecki
74ec175715 [test] Kill child process when exiting test runner 2012-10-28 14:31:15 +01:00
Maciej Małecki
3531fd609a [test] Make global detection work with older node versions 2012-10-28 14:25:36 +01:00
Maciej Małecki
fefbf04ac0 [test] Upgrade common.js from node core 2012-10-28 13:56:53 +01:00
Maciej Małecki
3d618777ea Merge pull request #323 from indutny/fix-maciej-issue
lib: allow overriding maxSockets
2012-10-25 18:13:59 -07:00
Fedor Indutny
a487dc9b58 lib: allow overriding maxSockets 2012-10-26 01:39:13 +04:00
Maciej Małecki
4d7e8a808d [dist] Bump version to 0.8.4 2012-10-23 22:01:57 +02:00
Maciej Małecki
ebfdbede31 Merge pull request #320 from indutny/master
Events patch
2012-10-23 12:59:33 -07:00
Fedor Indutny
5df6e7bdb8 http-proxy: emit websocket:start
* routing-proxy: allow listening for websocket:* event
2012-10-23 23:54:23 +04:00
Farrin Reid
1df2b30e84 Merge pull request #315 from yawnt/options-doc
documentation for options
2012-10-15 12:19:26 -07:00
yawnt
213e03c998 [fix] function 2012-10-15 20:58:30 +02:00
yawnt
d4cb9dad6c [docs] more options 2012-10-14 20:25:19 +02:00
yawnt
4c8e1d96a3 [docs] options 2012-10-14 19:36:02 +02:00
Maciej Małecki
2e7d8a88f4 [fix] Partial fix for rejecting self-signed certs in tests
Since joyent/node@35607f3a2d, https and
tls modules validate server certificate by default. Turn this feature
off since we're using self-signed certificates in tests.

Currently wss tests are still failing, pending investigation.

Commited on a plane from Poznań to Munich.
2012-09-27 10:00:10 +02:00
Maciej Małecki
eafdc744b6 [refactor] Pass all options to Agent constructor 2012-09-27 10:00:10 +02:00
Maciej Małecki
e925e4928f Merge pull request #308 from peters/patch-1
Added travis build status
2012-09-24 16:20:16 -07:00
Bradley Meck
a89a5b8088 [dist] v0.8.3 2012-09-20 10:59:02 -05:00
Bradley Meck
698b01da8e [fix] spdy should look like https when forwarding (until we get a client) 2012-09-20 10:54:29 -05:00
Peter Rekdal
a64cec0be9 Added travis build status 2012-09-13 10:57:28 +03:00
Nuno Job
bf04bbde8f Merge pull request #302 from janl/patch-1
Fix installation instructions: s/http/https/
2012-08-27 08:48:41 -07:00
Jan Lehnardt
1db9542723 Fix installation instructions: s/http/https/ 2012-08-27 18:37:59 +03:00
Tomaz Muraus
850171cdc4 If HTTP 1.1 is used and backend doesn't return 'Connection' header, explicitly
return Connection: keep-alive.
2012-08-16 21:47:56 -07:00
Maciej Małecki
4f6387c17f [test] Add node v0.9 testing, test all branches 2012-08-10 21:46:58 +02:00
Maciej Małecki
cee27feedd [minor doc] Correct comment 2012-08-10 21:45:30 +02:00
Maciej Małecki
812868ddfc [minor] Remove setEncoding on incoming socket
This isn't needed as we don't do any string operations and `setEncoding`
results in a higher memory usage and is slower.
2012-08-10 21:43:55 +02:00
indexzero
1783ab0625 [fix] Dont use -i when running vows because it supresses --target= and --proxy= CLI arguments 2012-07-26 04:57:02 -04:00
indexzero
a454666e7a [fix] Ignore npm version errors when installing dependencies for examples 2012-07-26 04:53:48 -04:00
indexzero
c4a7b15843 [fix] Suppress EADDRINUSE errors from test/examples-test.js since we are just looking for require-time errors. Isolate tests to ensure idempotency of ports 2012-07-26 04:47:25 -04:00
indexzero
fd648a5290 [fix test] Fix examples to use newest version of socket.io and helpers. Added tests for ensuring that examples require as expected with no errors. 2012-07-26 04:29:47 -04:00
Charlie Robbins
82da8535c5 Merge pull request #285 from 1stvamp/pass-change-origin-from-routing-proxy
If supplied pass changeOrigin option through to HttpProxy instance if set in RoutingProxy
2012-07-26 00:51:10 -07:00
Wesley Mason
89459bfd32 If supplied pass changeOrigin option through to HttpProxy instance if set in RoutingProxy 2012-07-25 14:17:48 +01:00
Bert Belder
24b84068ea Fix socket leaks when FIN packet isn't responded to 2012-07-24 23:05:04 +02:00
Maciej Małecki
0d00b06af3 [fix] destroy() websockets in case of an error
Not doing so caused websockets in `CLOSE_WAIT` to pile up and cause
proxy to exceed open file descriptor limit.
2012-07-24 16:30:51 +02:00
indexzero
13c34d09b2 [dist] Version bump. 0.8.2 2012-07-22 17:24:44 -04:00
indexzero
67539519fa [doc] Minor formatting updates to README.md 2012-07-22 14:27:38 -04:00
Charlie McConnell
29e6e748f7 [test] Add .travis.yml file for Travis CI. 2012-07-22 00:39:57 -07:00
indexzero
2d75510d82 [dist] Remove out-dated docco docs 2012-07-22 03:14:42 -04:00
indexzero
36226daa2e [dist] Complete JSHint compliance except for too many var statements 2012-07-22 03:14:01 -04:00
Charlie Robbins
46c184cb08 Merge pull request #221 from coderarity/gzip-middleware-proxytable-example
Add example for gzip middleware using a proxy table.
2012-07-21 23:55:30 -07:00
indexzero
4999b20b84 Merge branch '0.8.2' 2012-07-22 02:49:43 -04:00
Charlie Robbins
02b914d609 Merge pull request #246 from tellnes/proxy-remove
Implement RoutingProxy.prototype.remove
2012-07-21 23:33:07 -07:00
Charlie Robbins
f28c62c815 Merge pull request #235 from Filirom1/patch-1
prefer `target.hostname` over `target.host`
2012-07-21 23:31:35 -07:00
Christian Howe
0273958b0a Use changeOrigin for proxyRequest. 2012-07-22 02:24:15 -04:00
Christian Howe
04ce49c5b2 Whitespace fixes. 2012-07-22 02:24:02 -04:00
Charlie Robbins
1cc1f90527 Merge pull request #275 from jfromaniello/patch-1
add "Using two certificiates" to the https section of the readme.md
2012-07-21 23:17:58 -07:00
Charlie Robbins
54f83717b2 Merge pull request #268 from shapeshed/patch-1
Add support for setting the host in the executable
2012-07-21 23:17:23 -07:00
indexzero
7e854d778b [refactor tests] Finished refactoring tests to support ws*-to-ws* tests based on CLI arguments 2012-07-22 01:38:23 -04:00
indexzero
828dbebcaa [refactor test] Add support for http*-to-http* testing from CLI arguments 2012-07-22 01:03:41 -04:00
indexzero
55286a7c49 [fix api] Optimize lookups in the ProxyTable. Ensure that RoutingProxy can proxy to https by default. 2012-07-22 01:02:51 -04:00
indexzero
e2dc7f9693 [refactor test] Finish removing old test code. 2012-07-21 20:46:30 -04:00
indexzero
4ae7a5b840 [refactor] Rewrite tests to use saner vows idioms. Update tests to use latest socket.io 2012-07-21 19:29:23 -04:00
José F. Romaniello
0b6c7f5f7e add "Using two certificiates" to the https section of the readme.md 2012-07-03 16:26:20 -03:00
Maciej Małecki
fd16aeb4f8 Merge pull request #270 from node-migrator-bot/clean
Hi! I fixed some calls to "sys" for you!
2012-06-25 05:28:12 -07:00
Farrin Reid
bf7e328fb8 [fix] Changed require('util') to require('util') for compatibility with node v0.8 2012-06-24 22:18:02 -08:00
George Ornbo
415d4ed908 match style requested by @cronopio 2012-06-20 20:59:17 +01:00
George Ornbo
06e78f2747 adding support for setting the host 2012-06-20 15:51:31 +01:00
Joshua Holbrook
ccd8f840b2 Merge pull request #266 from rampr/master
Fix bug: x-forwarded-proto set incorrectly as httphttps or wswss
2012-06-18 23:42:50 -07:00
Ramprasad Rajendran
0933f1c598 Fix bug: x-forwarded-proto set incorrectly
When routed via multiple proxies, x_forwarded_proto set as httphttps or
wswss instead of http,https or ws,wss, since + operator seems to have a
higher precedence than the terniary operator and the expression was
getting evaluated to true always
2012-06-19 12:00:24 +05:30
cronopio
81f6095cf0 [dist] Version bump 0.8.1 2012-06-05 17:09:17 -05:00
cronopio
45d67f42cb [tests] used socket.io 0.6.17 fixed version for tests 2012-06-05 17:06:03 -05:00
Charlie Robbins
27fa708449 Merge pull request #256 from nodejitsu/changelog
[misc] Updating the changelog. Close #137
2012-06-05 14:19:52 -07:00
cronopio
e9a3a3012c [misc] changelog updated to version 0.8.1 2012-06-05 15:37:55 -05:00
Christian Howe
64c974755d Merge pull request #218 from CodeRarity/proxy-table-fix
Fix problem with req.url not being not properly replaced.
2012-06-05 13:04:18 -07:00
cronopio
df650d11dd [minor fix] delete white space 2012-05-31 15:26:28 -05:00
cronopio
b5847733cd [misc] Updating the changelog. Close #137 2012-05-31 15:19:45 -05:00
Ryan Stevens
ca37ad7436 [fix] x-forwarded-proto sets properly
The ternary was evaluating truthy for "," + req.connection.pair which is always true because its always a non empty string.  Wrapped actual condition to properly concatenate the product of the ternary.  let me know if you prefer the style   (req.connection.pair ? 'https' : 'http')

https://github.com/nodejitsu/node-http-proxy/issues/250
2012-05-22 12:54:47 -07:00
Christian Tellnes
0532995dfa Implement RoutingProxy.prototype.remove 2012-05-17 05:44:56 +02:00
Christian Howe
f223ce8b4e Merge pull request #216 from CodeRarity/master
Re-emit 'start', 'forward' and 'end' events in RoutingProxy, and fix some hanging issues.
2012-05-10 09:34:46 -07:00
Christian Howe
27316e22e8 [dist] Update author field for consistency 2012-05-07 16:59:05 +00:00
Romain
c4d185dca9 prefer target.hostname over target.host 2012-04-24 10:22:56 +03:00
Christian Howe
5d839dd5f8 Add tests for remapping URL properly. 2012-04-11 16:13:25 -04:00
Joshua Holbrook
ed06af97ef [doc] Fix style in websockets example 2012-04-03 00:36:52 -07:00
Joshua Holbrook
4d7eaff65b Merge pull request #225 from darashi/fix-readme
Fixes to make the websockets example work.
2012-04-03 00:34:10 -07:00
Yoji SHIDARA
4fc1ee85d3 [doc] call listen() to get the server started 2012-04-03 16:25:00 +09:00
Yoji SHIDARA
843901eeeb [doc] add missing {} to make an object 2012-04-03 16:23:00 +09:00
Christian Howe
b26b434e9f Fix RoutingProxy hanging when there is an error 2012-03-30 20:45:29 -04:00
Joshua Holbrook
11315e63fa Merge branch 'master' of https://github.com/thefosk/node-http-proxy into thefosk-master 2012-03-30 15:53:48 -07:00
Marco Palladino
4358a4c122 finally removed hidden char 2012-03-30 15:33:55 -07:00
Marak Squires
1a014f96dd Merge pull request #222 from thefosk/master
[minor] Syntax error
2012-03-30 15:25:15 -07:00
Marco Palladino
5842d0ee7d syntax error fixed 2012-03-30 15:16:34 -07:00
Christian Howe
62013281b8 Added example for gzip middleware using a ProxyTable. 2012-03-30 15:38:51 -04:00
Christian Howe
f1611ec8dc Fix problem with req.url not being not properly replaced. 2012-03-29 13:05:49 -04:00
Marak Squires
fd7fcd8dec [examples] Added simple load balancer example 2012-03-28 22:40:50 -07:00
Marak Squires
f20b3740b1 Merge branch 'master' of github.com:nodejitsu/node-http-proxy 2012-03-28 22:36:23 -07:00
Christian Howe
4f2bc58431 Add documentation for listening for proxy events to prevent a common mistake. 2012-03-28 00:10:37 -03:00
Christian Howe
99ee54259e Re-emit 'start', 'forward' and 'end' events in RoutingProxy. 2012-03-27 21:38:35 -04:00
Christian Howe
e9fd3f43d7 Whitespace fixes 2012-03-27 21:36:36 -04:00
Marak Squires
a088efdb04 Merge pull request #208 from larsburgess/patch-1
[docs] Making README links consistent with latest project structure.
2012-03-13 17:29:20 -07:00
Lars Burgess
7fa6599f4f Making README links consistent with latest project structure. 2012-03-13 17:10:14 -07:00
Marak Squires
b979cb32a1 Merge pull request #205 from drewp/master
[docs] improved grammar
2012-03-01 20:37:43 -08:00
Drew Perttula
e15db4fb50 fix the broken english and clarified the sentence (I hope) 2012-03-01 20:35:56 -08:00
Charlie Robbins
91bb2a9106 Merge pull request #189 from drewp/master
proposed doc addition for #180
2012-02-11 18:41:03 -08:00
Drew Perttula
73e415a226 Address ticket #180 here since that problem is so hard to discover when you run into it. If there was an error, people would search for the error text, but there isn't. 2012-02-06 17:15:44 -08:00
MetaHack
868f7e7a28 fixed comment typos in examples/http/proxy-https-to-http.js and proxy-https-to-https.js, lines 37 and 46 2012-01-09 19:10:33 +08:00
indexzero
5055689a11 [dist] Version bump. 0.8.0 2011-12-23 01:42:26 -05:00
indexzero
c81bae2fdd [fix minor] Correctly set x-forwarded-proto in WebSocket requests 2011-12-23 01:40:35 -05:00
indexzero
6f8ad3b8c3 Merge branch '0.6-compatibility' 2011-12-23 01:34:02 -05:00
indexzero
3828616816 [refactor] Listen for socket events since reverseProxy.socket is no longer set synchronously 2011-12-23 01:33:24 -05:00
indexzero
ea7fea6272 [refactor minor] Update vendor/websocket.js to be compatible with node@0.6.x 2011-12-23 01:32:49 -05:00
Maciej Małecki
8358ef8a2b [test dist] Run core tests on npm test 2011-12-18 22:54:08 +01:00
Maciej Małecki
c4124da4f2 [minor] Fix indent on timeout notice 2011-12-18 22:49:20 +01:00
Maciej Małecki
bc98c0dbce [test] Add core test-http-upgrade-server2 test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:20 +01:00
Maciej Małecki
feb324b0d4 [test] Add core test-http-proxy test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:20 +01:00
Maciej Małecki
275109b2f8 [test] Add core test-http-contentLength0 test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:19 +01:00
Maciej Małecki
c26ab5e46f [test] Add core test-http-extra-response test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:19 +01:00
Maciej Małecki
d7f15d02f7 [test] Add core test-http-server-multiheaders test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:19 +01:00
Maciej Małecki
35d2088c96 [test] Add core test-http-multi-line-headers test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:19 +01:00
Maciej Małecki
48d4a8b263 [minor] Allow user to set colors.mode 2011-12-18 22:49:19 +01:00
Maciej Małecki
5c3d41bf4e [minor] Nicer output from test runner 2011-12-18 22:49:19 +01:00
Maciej Małecki
38bd906f2b [minor] Everybody loves Unicode
Tick and X marks in test runner output.
2011-12-18 22:49:19 +01:00
Maciej Małecki
b76680b045 [minor] Change test runner output order 2011-12-18 22:49:19 +01:00
Maciej Małecki
68cebbe0e7 [test] Run tests in test/core/simple by default 2011-12-18 22:49:19 +01:00
Maciej Małecki
e109eba972 [minor] When running tests output only basename 2011-12-18 22:49:19 +01:00
Maciej Małecki
219b0ff8f8 [dist] Test runner depends on async 2011-12-18 22:49:19 +01:00
Maciej Małecki
a4079c6a1c [test] Implement basic runner for multiple tests
Features:

  * timeout
  * running tests in separate processes
  * printing basic summary
2011-12-18 22:49:19 +01:00
Maciej Małecki
2ccc5c73ea [test minor] Update copyright notice on test runner 2011-12-18 22:49:19 +01:00
Maciej Małecki
004be38048 [test refactor] test/core/{run => run-single} 2011-12-18 22:49:19 +01:00
Maciej Małecki
4e1ca6e618 [test] Add core test-http-many-keep-alive-connections test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
  * `process.exit` instead of `server.close` (process wouldn't exit
    otherwise, I'm not sure why)
2011-12-18 22:49:19 +01:00
Maciej Małecki
13389db1be [test] Add core test-http-head-response-has-no-body-end test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:19 +01:00
Maciej Małecki
f79f3adf02 [test] Add core test-http-head-response-has-no-body test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:19 +01:00
Maciej Małecki
f298411f76 [test] Add core test-http-host-headers test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
  * remove https part
  * change assertion to match `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:19 +01:00
Maciej Małecki
5ac987857c [test] Add core test-http-client-upload-buf test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
f1c0be3f0b [test] Add core test-http-response-close test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
7bf8d4a7be [test] Add core test-http-client-abort test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`

As off a95cf9bd63, this test doesn't hang.
2011-12-18 22:49:18 +01:00
Maciej Małecki
4d43d81e5c [fix] When client request is aborted, abort server request 2011-12-18 22:49:18 +01:00
Maciej Małecki
80c216df0c [test] Add core test-http-eof-on-connect test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
a6353897cd [test] Add core test-http-malformed-request test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
7648fe50c1 [test] Add core test-http-client-upload test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
25a9e2d217 [test] Add core test-http test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
60ff181af9 [test] Add core test-http-upload-timeout test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
98bbe541e4 [test] Add core test-http-client-abort2 test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
d7461f3206 [test] Add core test-http-chunked test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
c0857f2d59 [test] Add core test-http-head-request test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
b3b5cce3ae [test] Add core test-http-set-cookies test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
82060a5343 [test] Add core test-http-status-code test
Modifications:

  * make client connect to `PROXY_PORT` instead of `PORT`
2011-12-18 22:49:18 +01:00
Maciej Małecki
31a8c6800d [fix test] Make test runner exit after test exits 2011-12-18 22:49:18 +01:00
Maciej Małecki
87999d0288 [test] Add basic test runner 2011-12-18 22:49:18 +01:00
Maciej Małecki
543f214361 [test] Add common.js file from core
Modifications:

  * add `PROXY_PORT` constant
2011-12-18 22:49:18 +01:00
Maciej Małecki
8ca5d83497 [docs] Little explanation for test/core directory 2011-12-18 22:49:17 +01:00
Maciej Małecki
63dfc7f175 [fix] In routing proxy, match line beginning
Previous approach failed in case of routing table like:

    {
      'domain.com': 'localhost:9000',
      'a.domain.com': 'localhost:9001'
    }

without `hostnameOnly`. When routing request to `a.domain.com`,
`RegExp` matched first entry (`domain.com`) and returned it.
2011-12-18 21:47:06 +01:00
Charlie Robbins
9f05e6c567 Merge pull request #165 from elfsternberg/master
Fix issue where front-end is HTTPS, back-end is HTTP, and server issues a redirect.
2011-12-13 22:21:51 -08:00
Charlie Robbins
d1b19a1205 Merge pull request #164 from elfsternberg/553e7fbc335a9befd166d472f057aa50452a9d40
Modified the ad-hoc proxy lookup to use _getKey(), rather than the error-prone in-line method.
2011-12-13 22:21:07 -08:00
indexzero
5b52c89694 [refactor] Updates to support http2 from @mikeal
Conflicts:

	lib/node-http-proxy/http-proxy.js
2011-12-14 01:45:52 +01:00
Maciej Małecki
86b4122323 [v0.6] http.Agent uses different structure for sockets 2011-12-14 01:45:44 +01:00
Maciej Małecki
6655e01642 [v0.6] Don't use agent.appendMessage()
Instead, just perform a request.
2011-12-14 01:45:34 +01:00
Maciej Małecki
8d701bb20b [example] Replace sys usages with util 2011-12-14 01:45:21 +01:00
Bradley Meck
e2dccbca48 Merge pull request #163 from samyakbhuta/master
Allows node-http-proxy to append new values to existing headers for incoming "x-forward-for","x-forward-proto" and "x-forward-port"
2011-12-08 14:07:21 -08:00
Marak Squires
f086692619 Merge branch 'master' of github.com:nodejitsu/node-http-proxy 2011-12-05 14:20:32 -08:00
Ken "Elf" Mathieu Sternberg
411bb51cc6 Fix issue where front-end is HTTPS, back-end is HTTP, and server issues a redirect.
This handles the case where a back-end web application such as Django or
Rails issues a redirect and automatically decorates the URL with the
protocol with which it was addressed.  If the back-ends are internal and
HTTP-only, then they'll issue a URL with 'http://' as the protocol.
This must be fixed before leaving the proxy.

This also handles the (unusual) case where a back-end speaks only
https://, but the user is deploying node-http-proxy to make that service
available to non-SSL capable browsers.  Works only with 301 and 302
codes.
2011-11-29 10:10:16 -08:00
Ken "Elf" Mathieu Sternberg
553e7fbc33 Modified the ad-hoc proxy lookup to use _getKey(), rather than the
error-prone in-line method.

_getKey() will look for options.target as well as
options.host:options.port, and so is useful for a segmented
proxy server where the destination proxies are not constructed before
first references.
2011-11-29 09:52:32 -08:00
Samyak Bhuta
621f9b425a Allowing the common proxy headers' value to be appended in proxy chain scenarios. 2011-11-28 08:56:45 +00:00
Charlie McConnell
1e33434fcc Revert "[dist] Adjusted engines field to allow for 0.6; version bump 0.7.7"
This reverts commit 30dac898f30a8508b4c4b4236e9438987f320167.
2011-11-26 10:10:24 -08:00
Charlie McConnell
30dac898f3 [dist] Adjusted engines field to allow for 0.6; version bump 0.7.7 2011-11-22 11:01:52 -08:00
Charlie McConnell
3ab02f3ad7 [fix] Fix incorrect depth check. 2011-11-16 19:15:51 -08:00
Max Ogden
c03a450d9b simplify proxytable path segment rewrite logic 2011-11-16 19:15:51 -08:00
Cloud9
2061c71366 Revert "update outgoing.headers.host incase the destination does proxying"
This reverts commit 65b7872e6ad433deae4de823c63629cb341bd649.
2011-11-16 16:42:07 -08:00
Fabian Jakobs
d6ea3a425c don't add upgrade handler if a custom handler is passed in
if a callback but no static proxy is defined and
no routes are provided then handlers.length is 1.
However the upgrade event is still automagically
attached in spite of having an explicit callback.
2011-11-16 16:40:51 -08:00
koichik
152d258ea0 [fix] Avoid Transfer-Encoding: chunked for HTTP/1.0 client, closes #59. 2011-11-16 16:10:00 -08:00
Marak Squires
6a9751eb0d Merge branch 'master' of github.com:nodejitsu/node-http-proxy 2011-11-16 15:19:01 -08:00
Camilo Aguilar
c98ccb40e9 Fixes memory leak when clients abort connections 2011-11-15 20:20:47 -05:00
Dominic Tarr
c5dc9295c7 bump version 0.7.6 2011-11-15 07:43:43 +11:00
Dominic Tarr
f27d26f451 changeOrigin option: set the host header to the proxy destination 2011-11-15 07:41:09 +11:00
Dominic Tarr
b4d41c3628 bump version 0.7.5 2011-11-11 12:27:49 +11:00
Dominic Tarr
65b7872e6a update outgoing.headers.host incase the destination does proxying 2011-11-11 12:27:21 +11:00
Dominic Tarr
f004788098 Merge branch 'master' of github.com:nodejitsu/node-http-proxy 2011-11-10 17:00:30 +11:00
bradleymeck
dd8319972c [example] Response modification middleware 2011-11-09 23:56:16 -06:00
Dominic Tarr
c60c6a27f6 Merge branch 'master' of github.com:nodejitsu/node-http-proxy 2011-11-10 16:45:39 +11:00
Dominic Tarr
3dfba2ba45 bump version 0.7.4 2011-11-10 16:44:49 +11:00
Dominic Tarr
182dcd3455 always emit end in 0.4 2011-11-10 16:44:23 +11:00
Maciej Małecki
6e65c20017 [examples] Add some hand-crafted middleware 2011-11-08 17:05:33 +01:00
root
c83d88ee88 Revert "[refactor] Improved event handler cleanup "
This reverts commit 9f923325d08ac018a3325beaa9e0805b5eda61e6.
2011-10-25 16:13:43 +00:00
Marak Squires
9f923325d0 [refactor] Improved event handler cleanup 2011-10-25 09:09:40 -07:00
Marak Squires
9e630daf81 [minor] Indentation fix 2011-10-25 06:25:15 -07:00
Marak Squires
63ac925260 [refactor] core proxy logic. all tests should be passing. 2011-10-25 06:18:35 -07:00
Charlie Robbins
cdb45247ca Merge pull request #136 from bmeck/drain-fix
[fix] only set one drain listener while paused
2011-10-22 11:24:36 -07:00
bradleymeck
7feee194f8 [fix] only set one drain listener while paused 2011-10-22 13:13:10 -05:00
Marak Squires
a72696533b Merge pull request #134 from quackingduck/grammar-fix
[docs] grammar correction
2011-10-20 13:33:17 -07:00
Myles Byrne
729496d289 grammar correction 2011-10-20 15:25:59 -05:00
Max Ogden
91e9bb9070 adding tests for url segment proxytable routing 2011-10-15 14:22:36 -07:00
Max Ogden
4d50915373 change proxytable routing to route one level shallower 2011-10-14 15:42:39 -07:00
indexzero
f188f4ffd8 [test fix] Remove unnecessary console.log in tests/websocket/websocket-proxy-test.js 2011-10-04 01:54:27 +02:00
indexzero
db185bb303 [dist] Version bump. 0.7.3 2011-10-04 01:51:17 +02:00
Florian Traverse
b7adf866b5 added what is necessary for having proxyError on Routing proxywq 2011-10-04 01:49:12 +02:00
indexzero
ccccc45f11 [dist] Version bump. 0.7.2 2011-09-30 04:03:58 +02:00
Fedor Indutny
45ef87e71b [websockets] add latest websockets support 2011-09-30 03:28:46 +02:00
Charlie Robbins
6c6fec094e Merge pull request #118 from nodejitsu/gh-117
[fix] Examples have working require paths now.
2011-09-29 13:16:53 -07:00
Joshua Holbrook
2e8d4c6e49 [fix] Fixed require paths in examples 2011-09-29 13:14:15 -07:00
Charlie McConnell
5ad77395c0 [dist] Version bump v0.7.1, closes #107 #112 2011-09-21 15:34:12 -07:00
Charlie McConnell
2b2c4abb2c Merge pull request #114 from nodejitsu/readme-fixes
Readme fixes
2011-09-21 15:30:18 -07:00
Charlie McConnell
549360a462 [examples] More fixes to examples. 2011-09-21 14:53:57 -07:00
Charlie McConnell
8fc8d966c4 [examples] Updated examples to v0.7.x API. 2011-09-21 14:11:41 -07:00
Charlie McConnell
e5693d2b5b Merge pull request #110 from nodejitsu/gh-107
#107: Set x-forwarded-for header (amongst others)
2011-09-21 13:09:23 -07:00
Charlie McConnell
24ef919495 [docs] Updated examples in README.md for 0.7.x API. 2011-09-21 13:05:57 -07:00
Joshua Holbrook
1f33943b23 [fix] connection.socket -> socket for source of x-forwarded-for data 2011-09-20 14:34:03 -07:00
Joshua Holbrook
66e982060c [test] Added a test for the "x-forwarded-for" header 2011-09-20 13:33:07 -07:00
Joshua Holbrook
2677bb6c44 [fix] x-forwarded http headers should set properly. 2011-09-20 13:00:59 -07:00
Charlie Robbins
787370ee87 Merge pull request #109 from jnordberg/master
command line tool - make sure targetPort is an integer
2011-09-18 18:49:39 -07:00
Johan Nordberg
5ba25aa345 Make sure the target port is an integer
This fixes a bug that caused cli to fail when --target was specified with both hostname and port
2011-09-17 14:37:47 +02:00
indexzero
bdf48bea36 [doc] Drop version number from README.md. 2011-09-10 07:06:05 -04:00
indexzero
00e34a10bd [dist] Version bump. 0.7.0 2011-09-10 07:05:31 -04:00
indexzero
f7010e5169 [merge] Merge from significant internal refactor in v0.7.x. No external API changes 2011-09-10 07:05:17 -04:00
indexzero
0182ba37cd [dist] Version bump. 0.7.0 2011-09-10 07:01:32 -04:00
indexzero
0eb4917ded [fix] Add x-forward-* headers for WebSocket requests. Closes #74 2011-09-10 06:57:51 -04:00
indexzero
d6c543691b [doc] Document setMaxSockets. Fixes #81 2011-09-10 04:58:19 -04:00
indexzero
13eaec55dc [doc] Updated examples 2011-09-10 04:04:31 -04:00
indexzero
2cd8256c4d [minor] Small update to bin/node-http-proxy 2011-09-10 03:57:26 -04:00
indexzero
6c1c554451 [dist] Update .gitignore 2011-09-10 03:56:57 -04:00
indexzero
0ba5023e82 [doc] Update README.md 2011-09-10 03:56:18 -04:00
indexzero
6e1ade0bb8 [dist] Update scripts in package.json 2011-09-10 03:55:53 -04:00
indexzero
734769fa9b [test] Updated tests to reflect finalized API of the RoutingProxy 2011-09-10 03:55:35 -04:00
indexzero
f765f90ec3 [api] Finalized the RoutingProxy API 2011-09-10 03:55:07 -04:00
indexzero
598fe2e38d [api doc] Rebuilt httpProxy.createServer() with the newer high-level RoutingProxy API 2011-09-09 18:14:49 -04:00
indexzero
5927ecd62a [api test dist] Stubbed out the API for the higher-level RoutingProxy object to be exposed by node-http-proxy 2011-09-08 18:22:38 -07:00
indexzero
2937229820 [dist] Update examples/package.json to conform to nodejitsu style guidelines 2011-09-08 17:58:11 -07:00
indexzero
3a4d312eda [test] Whitespace fix 2011-09-08 17:57:44 -07:00
indexzero
81d6c31875 [dist] Reorganize examples based on classification(s): http, websocket, or middleware 2011-09-08 17:01:19 -07:00
indexzero
0eae2a913a [api] Added new close() method which cleans up sockets from HttpProxy instances 2011-09-08 16:55:45 -07:00
indexzero
ec03d72c5d [minor] Move private methods to the bottom of file(s) 2011-09-08 16:53:42 -07:00
indexzero
0e36912906 Fixed large DoS vector in the middleware implementation 2011-09-08 16:44:25 -07:00
indexzero
0c71119ee5 resume() can throw 2011-09-08 16:41:42 -07:00
indexzero
37e2541891 Emit drain if it doesn't happen on its own in 100ms 2011-09-08 16:36:19 -07:00
indexzero
6a7fd14bfa Add flow control 2011-09-08 16:29:15 -07:00
indexzero
ca1d12cf1b [fix] Memory leak hunting. 2011-09-08 16:21:20 -07:00
indexzero
38315f6b1f [minor] More contextual errors when middleware(s) error 2011-09-08 16:07:35 -07:00
Tj Holowaychuk
07c8d2ee60 Fixed large DoS vector in the middleware implementation 2011-09-08 14:36:40 -07:00
indexzero
5575bcf60c [minor] Remove commented out debug statements. 2011-09-08 14:24:43 -07:00
isaacs
558a8a4f79 resume() can throw 2011-09-08 14:06:31 -07:00
isaacs
84be9f2c3a Emit drain if it doesn't happen on its own in 100ms 2011-09-08 14:06:22 -07:00
isaacs
2b9e09b00a Add flow control
Not in the "async/fibers/coro" sense of flow control, but in the TCP
backpressure sense.

Pause the stream when a write isn't flushed, and then resume it once the
writable stream drains.
2011-09-08 14:06:14 -07:00
indexzero
967884c5de [dist] Version bump. 0.6.6 2011-08-31 11:48:24 -04:00
isaacs
f4fcf93403 Memory leak hunting.
Detach listeners and clean up buffer on error
2011-08-31 11:47:44 -04:00
indexzero
e1c41d0694 [fix] Add guards to every throw-able res.end call 2011-08-28 21:27:01 -04:00
indexzero
de4a6fe8a5 [fix] Only set x-forward-* headers if req.connection and req.connection.socket 2011-08-28 21:21:35 -04:00
indexzero
7beead5465 [dist] Version bump. 0.6.5 2011-08-28 21:14:56 -04:00
indexzero
f6dc12a971 [fix] Use req.connection for all x-forward-* headers 2011-08-28 21:14:42 -04:00
indexzero
216d46dc81 [dist] Version bump. 0.6.4 2011-08-28 19:33:41 -04:00
isaacs
7bda25b1c6 Add guards to every throw-able res.end call 2011-08-28 15:52:35 -07:00
isaacs
62201a0917 Fix #95 Don't look on req.connection if it's not set. 2011-08-28 13:41:19 -07:00
indexzero
340be42797 [minor] Dont use .bind() 2011-08-28 05:28:57 -04:00
indexzero
daf9231a66 [test fix] A few minor fixes to ensure basic WebSocket tests are working. Better scope tests by supported protocol 2011-08-28 05:06:14 -04:00
indexzero
be4562da9f [api test] Updated httpProxy.createServer() for new API exposed by simplified HttpProxy object.
[breaking] Temporarily removed pending refactor: middleware & ProxyTable support
2011-08-28 04:40:51 -04:00
indexzero
d2b0e4399e [api breaking] Begin refactor to optimize node-http-proxy by managing one instance of HttpProxy per host:port location 2011-08-28 03:38:39 -04:00
indexzero
db10c4af91 [test] Updates for readability 2011-08-28 02:09:37 -04:00
indexzero
1389b706b5 [dist] Version bump. 0.6.3 2011-08-28 01:50:44 -04:00
indexzero
5d6e6b9f78 [api] Expose adapted version of stack so it can be used with HttpProxy instances not created by httpProxy.createServer() 2011-08-28 01:49:41 -04:00
isaacs
be3a0d84a1 Handle cases where res.write throws 2011-08-28 01:49:37 -04:00
indexzero
5d0bbb38c3 [minor dist] Use pkginfo. Minor updates to variable scoping in .createServer() 2011-08-18 20:58:16 -04:00
Dominic Tarr
d8068a832d [dist] bump version 0.6.2 2011-08-09 20:34:16 +10:00
Dominic Tarr
b8f84994b0 [fix] fix syntax errors. close issue #86 2011-08-09 20:32:10 +10:00
Charlie McConnell
2626308cd8 [fix] Removed bad example. 2011-08-02 22:42:19 -07:00
Dominic Tarr
fea371dc0a [dist] bump version 0.6.1 2011-08-03 00:07:01 +10:00
Dominic Tarr
604ed2878d Merge branch 'patch-1' of https://github.com/KimSchneider/node-http-proxy
closes #80
Conflicts:
	lib/node-http-proxy.js
2011-08-03 00:06:08 +10:00
Dominic Tarr
e6ff8d6597 [api] merge middleware branch 2011-08-02 15:41:03 +10:00
Dominic Tarr
0f8fe8e246 [style] tidy 2011-08-02 15:33:03 +10:00
Dominic Tarr
5ba0f89aa3 merged 2011-08-02 15:31:10 +10:00
Dominic Tarr
20125889b3 [fix] do not use middleware code if it's not needed 2011-08-02 15:25:23 +10:00
Dominic Tarr
6ec8d6caac [minor] add example to test concurrency 2011-08-02 14:55:49 +10:00
Dominic Tarr
5bf2d59241 [doc] add note on middleware to Using node-http-proxy section of the README 2011-08-02 14:55:49 +10:00
Dominic Tarr
2cf4e0a9e6 [api] refactor out middlewares from examples. 2011-08-02 14:55:49 +10:00
Dominic Tarr
020290a162 [docs] add middleware examples (first draft) 2011-08-02 14:55:49 +10:00
indexzero
f7452bc42d [fix] Dont use res.* in proxyWebSocketRequest 2011-08-02 14:55:49 +10:00
indexzero
f0917a3f97 [minor] Style updates and whitespace cleaning for consistency 2011-08-02 14:55:49 +10:00
Charlie McConnell
8eaec35074 [minor] Added body decoder middleware example. Needs fixing. 2011-08-02 14:51:37 +10:00
Dominic Tarr
549bfeac23 [fix] broken RegExp 2011-08-02 14:51:37 +10:00
Charlie McConnell
4cc18f4217 Tested & fixed url middleware example, added comments. 2011-08-02 14:51:37 +10:00
Dominic Tarr
8b48b7e0af [minor] code style changes 2011-08-02 14:51:37 +10:00
Dominic Tarr
caa1f494ab [minor] minor fixes to gzip middleware example 2011-08-02 14:51:37 +10:00
Dominic Tarr
f6484de411 [doc] add comments to examples/url-middleware.js 2011-08-02 14:51:36 +10:00
Dominic Tarr
45f3df8093 [minor] add url-proxying middleware example 2011-08-02 14:51:36 +10:00
Dominic Tarr
b5d5eaabab [doc] note in readme about middleware 2011-08-02 14:51:36 +10:00
Dominic Tarr
d3c06973a1 [minor] add example of using middleware to gzip response 2011-08-02 14:51:36 +10:00
Dominic Tarr
7976de1121 support old (port,host) and (options) style when using middlewares 2011-08-02 14:51:36 +10:00
Dominic Tarr
c773eedeb6 [minor] add middleware to node-http-proxy 2011-08-02 14:51:36 +10:00
KimSchneider
2caa5d2b0d The number of maxSockets has to be set after the agent is created. Setting the property in the constructor does not work. 2011-08-01 13:22:30 +03:00
Dominic Tarr
b54666ff69 [minor] add middleware to node-http-proxy 2011-07-24 23:17:24 +10:00
Dominic Tarr
25c06a3a95 [fix] handler variable in createServer was global (!) 2011-07-23 05:40:29 -07:00
Dominic Tarr
03475a5944 [dist] bump version 6.0 2011-07-21 23:55:43 +10:00
Dominic Tarr
e3d95ecab2 [minor] default enableXForwarded to true 2011-07-21 23:53:25 +10:00
Dominic Tarr
5d33ad7118 [dist] bump version 5.12 2011-07-21 23:52:30 +10:00
Dominic Tarr
76aa982181 Merge pull request #73 from DanBUK/master
This adds a flag to ProxyRequest to disable the setting of x-forwarded-[for|port|proto]
(will change default to true in next commit)
2011-07-21 06:38:48 -07:00
Dominic Tarr
efa17ef6cf [fix] use routing table mhen proxying WebSockets.
closes issue #72
2011-07-21 23:08:11 +10:00
DanBUK
ee3506a8e7 Updating to enableXForwarded 2011-07-19 09:57:21 +01:00
DanBUK
404818b1dc Allow forwarding for x-forwarded-[for|port|proto] to enabled layering of http-proxies. 2011-07-18 12:07:54 +01:00
indexzero
baf0b9e25a [dist] Version bump. 0.5.11 2011-06-26 13:25:46 -04:00
indexzero
f0649d8d6a [doc] Updated docco docs 2011-06-26 13:05:59 -04:00
indexzero
eb6f9a6354 [api] Simplify the usage for the .changeHeaders option. Fixes #34 2011-06-26 12:21:06 -04:00
indexzero
9d9509f791 [doc] Small update to code docs 2011-06-26 10:56:12 -04:00
indexzero
4f85ca04e4 [api doc test] node-http-proxy now emits websocket:* on important WebSocket events. Added tests for these features and updated some code docs 2011-06-26 10:52:22 -04:00
indexzero
fcfe84626f [doc] Added examples/latent-websocket-proxy.js 2011-06-23 04:48:02 -04:00
indexzero
1ee8ae7104 [doc] Add examples/standalone-websocket-proxy.js 2011-06-23 04:36:16 -04:00
indexzero
b608a029f8 [minor] Add missing space 2011-06-23 04:34:47 -04:00
indexzero
4cdbf0e872 [doc] Added sample for custom error messages using the proxyError event 2011-06-15 09:39:35 -04:00
indexzero
7b574d3d3e [dist] Version bump. 0.5.10 2011-06-13 02:53:01 -04:00
indexzero
653c6ca1af [doc] Bump version in README.md 2011-06-12 18:29:05 -04:00
indexzero
887c5808c9 [refactor] Manage our own internal list of Agent instances 2011-05-25 00:48:44 -06:00
indexzero
a1cdf005b9 [test] Update tests to use localhost 2011-05-23 16:46:48 -04:00
indexzero
b4ac4d441f [doc] Update docco docs for 0.5.9 2011-05-23 02:23:16 -04:00
indexzero
57ca62c878 [dist] Version bump. 0.5.9 2011-05-23 02:18:48 -04:00
indexzero
028d2044e7 [fix] Change sec-websocket-location header when proxying WSS --> WS. Added test coverage for this scenario 2011-05-23 02:18:12 -04:00
indexzero
76ecb51e7b [dist] Version bump. 0.5.8. Forwards compatible with new versions of nodejs 2011-05-21 10:43:16 -04:00
indexzero
74120d8988 [doc] Update docco docs 2011-05-21 10:42:46 -04:00
indexzero
a865fe662f [test] Update to vows description for web-socket-proxy-test.js 2011-05-21 10:42:31 -04:00
indexzero
a86d18bc7f [fix] Dont force Connection: close now that Keep-Alive is supported 2011-05-21 10:41:51 -04:00
indexzero
6fd272ac18 [doc] Update to v0.5.7 in code and README.md 2011-05-19 02:48:46 -04:00
indexzero
c5fd368a8d [doc] Regenerate docco docs 2011-05-19 02:48:31 -04:00
indexzero
0911c1719e [dist] Version bump. v0.5.7. Only good on node v0.4.7. See issue #48. 2011-05-19 02:45:39 -04:00
indexzero
421895fa30 [api] Add x-forwarded-proto and x-forwarded-port to proxied HTTP requests 2011-05-19 02:43:41 -04:00
indexzero
e9b3ec9b1d [fix] Set x-forwarded-for from req.connection.socket.remoteAddress if req.connection.remoteAddress is not defined 2011-05-19 02:27:38 -04:00
indexzero
f1c0f641aa [dist] Version bump. v0.5.6 Only good on node v0.4.7. See issue #48. 2011-05-19 01:59:47 -04:00
indexzero
5d2192e654 [api minor] Small refactor to emit webSocketProxyError from a single helper function on any of the various error events in the proxy chain 2011-05-19 01:53:55 -04:00
indexzero
652cca37ea [api] Manual merge of #46: add custom proxyError event and enable production error handling. 2011-05-19 01:38:08 -04:00
indexzero
bd45216bc9 [doc] Regenerate docco docs 2011-05-19 01:33:23 -04:00
indexzero
76580c292a [fix doc] Add error handler to reverseProxy request when proxying WebSockets to prevent unhandled ParseError. Rename some variables in proxyWebSocketRequest to make the code more readable 2011-05-19 01:33:03 -04:00
indexzero
acacc0561f [dist] Version bump. 0.5.5. Only good on node v0.4.7. See issue #48. 2011-05-19 00:38:00 -04:00
indexzero
7bf0caef9f [fix] Change variable references for Websockets, bugs found from using wsbench 2011-05-19 00:37:18 -04:00
indexzero
32a15dd79d [minor] Update README.md to conform to Github flavored markdown 2011-05-18 21:09:31 -04:00
indexzero
521fe27185 [minor] Update README.md to conform to Github flavored markdown 2011-05-18 21:08:25 -04:00
indexzero
c04eec1c37 [dist] Version bump. 0.5.4. Only good on node v0.4.7. See issue #48. 2011-05-18 21:06:56 -04:00
indexzero
abc01bce29 [doc] Update README.md to reflect the new HTTPS to HTTP proxy capabilities 2011-05-18 21:06:34 -04:00
indexzero
faf2618cf3 [doc] Update docco docs 2011-05-18 21:06:21 -04:00
indexzero
91737fadb6 [doc] Update examples for HTTPS to HTTP proxying 2011-05-18 21:06:12 -04:00
indexzero
895f577744 [doc test api] Improve node-http-proxy API to allow for HTTPS to HTTP proxying scenarios. Update tests accordingly. 2011-05-18 21:05:44 -04:00
indexzero
d9fa261cdc [dist] Version bump. v0.5.3. Only good on node v0.4.7. See issue #48. 2011-05-17 21:37:43 -04:00
indexzero
03b9087446 [doc minor] Update docs and code docs for v0.5.3 release 2011-05-17 21:36:49 -04:00
indexzero
9e36d2d2e6 [doc] Regenerate docco docs 2011-05-17 21:36:27 -04:00
indexzero
9c6c4b908b [fix test api] Only change Origin headers in WebSocket requests when the changeOrigin option is set explicitly. Added tests to ensure Origin and sec-websocket-origin headers match when proxying websockets. 2011-05-17 21:29:00 -04:00
indexzero
44a85664a8 [test] Continued work around Origin mismatch tests 2011-05-17 21:03:02 -04:00
indexzero
9ab54ab47f [test] Refined tests to begin checking Origin == Sec-Websocket-Origin 2011-05-17 20:25:45 -04:00
indexzero
6e679c8019 [test] Improve websocket tests to inspect outgoing and incoming HTTP headers to test origin mismatch bugs 2011-05-17 20:09:56 -04:00
Olivier Lauzon
360e79a005 [dist] Version bump. 0.5.2. Only good on node v0.4.7. See issue #48. 2011-05-17 18:38:17 -04:00
Olivier Lauzon
a5e1e3e70d [doc] Regenerate docco docs 2011-05-18 06:21:05 +08:00
Olivier Lauzon
d08c2bb525 [dist] Include docco module as a dev dependency 2011-05-18 06:21:05 +08:00
Olivier Lauzon
1ee6beff6a [test] Fix tests in https mode
Tests can be run in https mode by adding the --https flag
vows test/*-test.js --spec --https
2011-05-18 06:20:48 +08:00
Olivier Lauzon
ff829467d3 [minor] Fix syntax in examples/ 2011-05-18 06:20:48 +08:00
Olivier Lauzon
e6c52d431f [dist] Use devDependencies in package.json 2011-05-18 06:20:47 +08:00
Olivier Lauzon
e90cbd6f14 [minor] Ignore npm modules and debug logs 2011-05-18 06:20:47 +08:00
Marak Squires
4a14bc0f29 Merge pull request #52 from benatkin/README
Readme: fix syntax error, reformat code blocks
2011-05-17 13:14:25 -07:00
Ben Atkin
ab8c264e6d add spacing around code blocks to fix README rendering 2011-05-17 13:22:20 -06:00
Ben Atkin
d5b9ba7180 don't highlight non-javascript as javascript 2011-05-17 13:19:15 -06:00
Ben Atkin
28f6dc153a format markdown for syntax highlighting on GitHub 2011-05-17 13:17:19 -06:00
Ben Atkin
332d2d780a fix syntax error in README example 2011-05-17 13:13:24 -06:00
indexzero
85223ea080 [fix] Manage bookkeeping for incoming requests to the underlying sockets behind reverse proxied websocket events. Only use the appropriate variables in the closure scope of the upgrade event from this bookkeeping 2011-05-13 17:53:14 -04:00
indexzero
6c80177340 [dist] Version bump. 0.5.1. Only good on node v0.4.7. See issue #48. 2011-05-10 15:30:56 -07:00
indexzero
40dc9dee2d Revert "Fixed "Invalid argument to getAgent" when proxying HTTP"
This reverts commit 642e15805dbd572835bb4fee9527e4f2da658833.
2011-05-10 15:29:03 -07:00
indexzero
57127a3671 [fix] Fix typo in bin/node-http-proxy 2011-04-26 18:52:58 -04:00
Charlie Robbins
ac425d70ef Merged pull request #39 from timmattison/master.
Looks like this may fix the issue that I reported
2011-04-26 14:20:53 -07:00
timmattison
642e15805d Fixed "Invalid argument to getAgent" when proxying HTTP 2011-04-26 12:27:24 -04:00
indexzero
ddf31b22ec [dist] Version bump. v0.5.0 2011-04-17 03:27:55 -04:00
indexzero
12064d8e5d [doc test] Small updates to README.md. Update to try require socket.io 2011-04-17 03:25:48 -04:00
indexzero
bd6a2622ad [doc] Update README.md 2011-04-17 03:14:59 -04:00
indexzero
40c51a703b [minor] Small update to README.md 2011-04-17 03:13:02 -04:00
indexzero
212009df6b [doc api] Update README.md and CHANGELOG.md for v0.5.0. Update bin/node-http-proxy to read files specified in config.https 2011-04-17 03:11:06 -04:00
indexzero
bf68dc30a5 [api test doc] Improve HTTPS support. Update minor documentation. Change tests accordingly. 2011-04-17 02:20:36 -04:00
indexzero
4d18ac1ae6 [test] Add WebSocket tests 2011-04-16 23:46:08 -04:00
indexzero
7cbf447320 [dist] Move pgriess' websocket client into vendor/* 2011-04-16 23:45:33 -04:00
indexzero
cfddd12e82 [api] Update .proxyRequest() and .proxyWebSocketRequest() APIs to take an options hash instead of a set of arguments. Add HTTPS support. 2011-04-16 23:08:40 -04:00
indexzero
6e4bf6a9cb [doc] Breakout demo.js into files in example/. Add web-socket-proxy.js example 2011-04-16 03:19:56 -04:00
indexzero
b0b0183c2b [api] Update WebSocket support to use http.Agent APIs 2011-04-16 03:19:22 -04:00
indexzero
5681fc1a28 [api] Emit end event when done proxying 2011-04-15 21:09:54 -04:00
indexzero
a3cb527be5 [api] Update request event to be consistent by emitting both req and res. Add x-forwarded-for header. 2011-04-15 20:43:22 -04:00
indexzero
c485c8742c [doc] Regenerate docco docs 2011-04-15 20:22:35 -04:00
indexzero
a89b3976b2 [api] Remove winston logging in favor of custom events 2011-04-15 20:22:22 -04:00
indexzero
a5d88aaacc [dist] Version bump. 0.4.2. Remove eyes dependency. 2011-04-13 17:24:22 -04:00
indexzero
0d1a3fe995 [dist] Version bump. 0.4.1. Fix package.json 2011-03-20 16:42:06 -05:00
indexzero
cbb5fbccd0 [dist] Version bump. 0.4.0 2011-03-20 13:32:09 -05:00
indexzero
6c42f04524 [doc] Regenerate docco docs 2011-03-20 13:31:44 -05:00
indexzero
1dd9b3b150 [minor] Expose version on module 2011-03-20 13:31:30 -05:00
indexzero
3fd3c96fa0 [api] Force connection header to be close until keep-alive is replemented 2011-03-20 13:17:15 -05:00
indexzero
3588687874 [test] Small update to proxy-table-test.js 2011-03-19 13:48:45 -05:00
indexzero
571531820e [doc api test] Wrap things up for v0.4.0 release: Add hostnameOnly routing to ProxyTable, add more documentation, fix edge-cases until they can be further investigated in node.js core 2011-03-10 08:22:50 -05:00
indexzero
4110448046 [doc api test] Rename HttpProxy.pause to HttpProxy.resume. Update documentation and tests accordingly 2011-03-09 23:53:41 -05:00
indexzero
3bc7d16adc [doc] Added docco generated literate coding documentation 2011-03-09 21:42:12 -05:00
indexzero
973f19fd5a [doc] Added more documentation 2011-03-09 21:41:54 -05:00
indexzero
d8c54063dc [minor doc] Update demo and small fix to node-http-proxy 2011-03-09 17:40:43 -05:00
indexzero
389159da1b [api test] All tests are passing when run as individual files 2011-03-09 16:25:32 -05:00
indexzero
e39a9f93d2 [api] Further work on refactor for node 0.4.0 2011-03-09 02:12:58 -05:00
indexzero
9faa924a29 [api] First pass at removing pool and working with node v0.4.0 2011-02-21 04:39:51 -05:00
indexzero
34cba38c29 [fix] Fixed cli parsing issue when --argument=value is not used 2010-12-07 19:27:41 -05:00
indexzero
8ef2e1fe33 [doc] Update to v0.3.1 in README.md 2010-11-23 19:12:41 -05:00
indexzero
0e7f362671 [dist] Change package.json for npm version bump 2010-11-22 00:18:20 -05:00
indexzero
de53d5eb2c [doc dist] Version bump. Added CHANGELOG.md 2010-11-22 00:15:18 -05:00
indexzero
8251296d7f [dist minor] Removed vendored pool. Changed all references of sys to util 2010-11-22 00:09:51 -05:00
indexzero
00014d624c [api test bin doc] Added bin script and simple logging 2010-11-21 23:43:25 -05:00
indexzero
c06f4bf7fe [test doc api] Added forward proxy functionality with tests 2010-11-21 22:41:47 -05:00
indexzero
bedc7a3ae5 [api test doc] Updated tests. Added ProxyTable functionality 2010-11-21 18:35:13 -05:00
indexzero
8c3e993833 [test] Simplified tests. Added tests for experimental websocket support 2010-11-21 02:07:07 -05:00
Fedor Indutny
f84880fcd9 No-server fix 2010-11-03 09:19:16 +06:00
indexzero
73381cf71a [debug] Removed pool as a dependency for stress test 2010-09-22 02:37:25 -04:00
indexzero
266e5246ea [debug] Roll back last commit ... connection = close was ineffective 2010-09-22 02:21:47 -04:00
indexzero
7b0ea85e2a [debug] Trying to repair pool busy client growth 2010-09-22 02:08:31 -04:00
indexzero
32aaf74e95 [minor] Updated max clients for pool 2010-09-20 20:38:19 -04:00
indexzero
60791f361f [minor] Pushing hot-fix from Mikeal for vendored pool repo 2010-09-20 20:37:02 -04:00
indexzero
9128a8c5a1 [doc] Updated Copyright ... added Fedor 2010-09-19 00:39:45 -04:00
indexzero
dd1918dc36 [debug] Better debug messages to try to determine if pool is slowly losing clients to forever busy 2010-09-17 13:09:43 -04:00
indexzero
7c2eb5de35 [api] pseduo-vendor pool until pull request is finalized 2010-09-17 01:30:52 -04:00
indexzero
3bb458e115 [api] Integrated commits from donnerjack and worked on pool changes 2010-09-16 23:43:55 -04:00
Fedor Indutny
7e61f0cf57 Moved error handling to response.on('end'), fixed error handling in websocket's part 2010-09-17 09:29:19 +07:00
Fedor Indutny
56003b5276 Added support of automatic websocket tunneling, added test for it 2010-09-16 11:43:35 +07:00
Fedor Indutny
cd78af5fea 'end' event becomes 'close', added more try-catch handling 2010-09-15 14:19:10 +07:00
Fedor Indutny
7249ef3ee7 WebSocket proxy support, fixed 304 code halting 2010-09-15 11:39:35 +07:00
Marak Squires
5d54ea58c9 adding more debugging messages 2010-09-13 18:41:24 -04:00
Marak Squires
4069a7e98c adding some debug messages for live testing 2010-09-13 18:29:38 -04:00
indexzero
711258ef46 [minor] Listen to error event on pool so we dont fail out unexpectedly anymore 2010-09-10 17:41:59 -04:00
indexzero
f8bff4c618 [minor] Listen to error events re-emitted by pool into the ClientRequest 2010-09-10 17:34:38 -04:00
indexzero
6d47d98f53 [doc] Update contributors for 0.3.0 2010-09-09 23:22:43 -04:00
indexzero
a9084b923a [api test dist doc] Updated for 0.3.0 release 2010-09-09 23:13:09 -04:00
indexzero
9f0aeacab1 [api] Object creation is cheap for HttpProxy, so lets take advantage 2010-09-09 22:30:00 -04:00
indexzero
66afb2a2a3 [api] Revert to old 0.1.x codebase for bug testing and performance comparison 2010-09-09 17:25:12 -04:00
65 changed files with 9842 additions and 566 deletions

6
.auto-changelog Normal file
View File

@ -0,0 +1,6 @@
{
"output": "CHANGELOG.md",
"template": "keepachangelog",
"unreleased": true,
"commitLimit": false
}

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
package-lock.json binary

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
node_modules
*.swp
cov
atest.js
notes
primus-proxy.js
tes.js
npm-debug.log
.nyc_output
coverage

9
.npmignore Normal file
View File

@ -0,0 +1,9 @@
test
examples
doc
benchmark
coverage
.nyc_output
.travis.yml
CHANGELOG.md
UPGRADING.md

12
.travis.yml Normal file
View File

@ -0,0 +1,12 @@
sudo: false
language: node_js
node_js:
- "8"
- "10"
- "12"
script:
- npm test
after_success:
- bash <(curl -s https://codecov.io/bash)
matrix:
fast_finish: true

1872
CHANGELOG.md Normal file

File diff suppressed because it is too large Load Diff

74
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,74 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <https://github.com/http-party/node-http-proxy>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@ -1,7 +1,7 @@
node-http-proxy
Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, & Marak Squires
Copyright (c) 2010-2016 Charlie Robbins, Jarrett Cruger & the Contributors.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@ -20,4 +20,4 @@
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.
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

630
README.md
View File

@ -1,110 +1,568 @@
# node-http-proxy - v0.2.0
<p align="center">
<img src="https://raw.github.com/http-party/node-http-proxy/master/doc/logo.png"/>
</p>
<img src = "http://i.imgur.com/dSSUX.png"/>
# node-http-proxy [![Build Status](https://travis-ci.org/http-party/node-http-proxy.svg?branch=master)](https://travis-ci.org/http-party/node-http-proxy) [![codecov](https://codecov.io/gh/http-party/node-http-proxy/branch/master/graph/badge.svg)](https://codecov.io/gh/http-party/node-http-proxy)
## Battle-hardened node.js http proxy
`node-http-proxy` is an HTTP programmable proxying library that supports
websockets. It is suitable for implementing components such as reverse
proxies and load balancers.
### Features
### Table of Contents
* [Installation](#installation)
* [Upgrading from 0.8.x ?](#upgrading-from-08x-)
* [Core Concept](#core-concept)
* [Use Cases](#use-cases)
* [Setup a basic stand-alone proxy server](#setup-a-basic-stand-alone-proxy-server)
* [Setup a stand-alone proxy server with custom server logic](#setup-a-stand-alone-proxy-server-with-custom-server-logic)
* [Setup a stand-alone proxy server with proxy request header re-writing](#setup-a-stand-alone-proxy-server-with-proxy-request-header-re-writing)
* [Modify a response from a proxied server](#modify-a-response-from-a-proxied-server)
* [Setup a stand-alone proxy server with latency](#setup-a-stand-alone-proxy-server-with-latency)
* [Using HTTPS](#using-https)
* [Proxying WebSockets](#proxying-websockets)
* [Options](#options)
* [Listening for proxy events](#listening-for-proxy-events)
* [Shutdown](#shutdown)
* [Miscellaneous](#miscellaneous)
* [Test](#test)
* [ProxyTable API](#proxytable-api)
* [Logo](#logo)
* [Contributing and Issues](#contributing-and-issues)
* [License](#license)
- reverse-proxies incoming http.Server requests
- can be used as a CommonJS module in node.js
- uses event buffering to support application latency in proxied requests
- minimal request overhead and latency
- fully-tested
- battled-hardened through production usage @ [nodejitsu.com][0]
- written entirely in javascript
- easy to use api
### Installation
### When to use node-http-proxy
`npm install http-proxy --save`
Let's suppose you were running multiple http application servers, but you only wanted to expose one machine to the internet. You could setup node-http-proxy on that one machine and then reverse-proxy the incoming http requests to locally running services which were not exposed to the outside network.
**[Back to top](#table-of-contents)**
### Upgrading from 0.8.x ?
Click [here](UPGRADING.md)
**[Back to top](#table-of-contents)**
### Core Concept
A new proxy is created by calling `createProxyServer` and passing
an `options` object as argument ([valid properties are available here](lib/http-proxy.js#L26-L42))
```javascript
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer(options); // See (†)
```
†Unless listen(..) is invoked on the object, this does not create a webserver. See below.
An object will be returned with four methods:
* web `req, res, [options]` (used for proxying regular HTTP(S) requests)
* ws `req, socket, head, [options]` (used for proxying WS(S) requests)
* listen `port` (a function that wraps the object in a webserver, for your convenience)
* close `[callback]` (a function that closes the inner webserver and stops listening on given port)
It is then possible to proxy requests by calling these functions
```javascript
http.createServer(function(req, res) {
proxy.web(req, res, { target: 'http://mytarget.com:8080' });
});
```
Errors can be listened on either using the Event Emitter API
```javascript
proxy.on('error', function(e) {
...
});
```
or using the callback API
```javascript
proxy.web(req, res, { target: 'http://mytarget.com:8080' }, function(e) { ... });
```
When a request is proxied it follows two different pipelines ([available here](lib/http-proxy/passes))
which apply transformations to both the `req` and `res` object.
The first pipeline (incoming) is responsible for the creation and manipulation of the stream that connects your client to the target.
The second pipeline (outgoing) is responsible for the creation and manipulation of the stream that, from your target, returns data
to the client.
**[Back to top](#table-of-contents)**
### Use Cases
#### Setup a basic stand-alone proxy server
```js
var http = require('http'),
httpProxy = require('http-proxy');
//
// Create your proxy server and set the target in the options.
//
httpProxy.createProxyServer({target:'http://localhost:9000'}).listen(8000); // See (†)
//
// Create your target server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
```
†Invoking listen(..) triggers the creation of a web server. Otherwise, just the proxy instance is created.
**[Back to top](#table-of-contents)**
#### Setup a stand-alone proxy server with custom server logic
This example shows how you can proxy a request using your own HTTP server
and also you can put your own logic to handle the request.
```js
var http = require('http'),
httpProxy = require('http-proxy');
//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});
//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http.createServer(function(req, res) {
// You can define here your custom logic to handle the request
// and then proxy the request.
proxy.web(req, res, { target: 'http://127.0.0.1:5050' });
});
console.log("listening on port 5050")
server.listen(5050);
```
**[Back to top](#table-of-contents)**
#### Setup a stand-alone proxy server with proxy request header re-writing
This example shows how you can proxy a request using your own HTTP server that
modifies the outgoing proxy request by adding a special header.
```js
var http = require('http'),
httpProxy = require('http-proxy');
//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});
// To modify the proxy connection before data is sent, you can listen
// for the 'proxyReq' event. When the event is fired, you will receive
// the following arguments:
// (http.ClientRequest proxyReq, http.IncomingMessage req,
// http.ServerResponse res, Object options). This mechanism is useful when
// you need to modify the proxy request before the proxy connection
// is made to the target.
//
proxy.on('proxyReq', function(proxyReq, req, res, options) {
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
});
var server = http.createServer(function(req, res) {
// You can define here your custom logic to handle the request
// and then proxy the request.
proxy.web(req, res, {
target: 'http://127.0.0.1:5050'
});
});
console.log("listening on port 5050")
server.listen(5050);
```
**[Back to top](#table-of-contents)**
#### Modify a response from a proxied server
Sometimes when you have received a HTML/XML document from the server of origin you would like to modify it before forwarding it on.
[Harmon](https://github.com/No9/harmon) allows you to do this in a streaming style so as to keep the pressure on the proxy to a minimum.
**[Back to top](#table-of-contents)**
#### Setup a stand-alone proxy server with latency
```js
var http = require('http'),
httpProxy = require('http-proxy');
//
// Create a proxy server with latency
//
var proxy = httpProxy.createProxyServer();
//
// Create your server that makes an operation that waits a while
// and then proxies the request
//
http.createServer(function (req, res) {
// This simulates an operation that takes 500ms to execute
setTimeout(function () {
proxy.web(req, res, {
target: 'http://localhost:9008'
});
}, 500);
}).listen(8008);
//
// Create your target server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9008);
```
**[Back to top](#table-of-contents)**
#### Using HTTPS
You can activate the validation of a secure SSL certificate to the target connection (avoid self-signed certs), just set `secure: true` in the options.
##### HTTPS -> HTTP
```js
//
// Create the HTTPS proxy server in front of a HTTP server
//
httpProxy.createServer({
target: {
host: 'localhost',
port: 9009
},
ssl: {
key: fs.readFileSync('valid-ssl-key.pem', 'utf8'),
cert: fs.readFileSync('valid-ssl-cert.pem', 'utf8')
}
}).listen(8009);
```
##### HTTPS -> HTTPS
```js
//
// Create the proxy server listening on port 443
//
httpProxy.createServer({
ssl: {
key: fs.readFileSync('valid-ssl-key.pem', 'utf8'),
cert: fs.readFileSync('valid-ssl-cert.pem', 'utf8')
},
target: 'https://localhost:9010',
secure: true // Depends on your needs, could be false.
}).listen(443);
```
##### HTTP -> HTTPS (using a PKCS12 client certificate)
```js
//
// Create an HTTP proxy server with an HTTPS target
//
httpProxy.createProxyServer({
target: {
protocol: 'https:',
host: 'my-domain-name',
port: 443,
pfx: fs.readFileSync('path/to/certificate.p12'),
passphrase: 'password',
},
changeOrigin: true,
}).listen(8000);
```
**[Back to top](#table-of-contents)**
#### Proxying WebSockets
You can activate the websocket support for the proxy using `ws:true` in the options.
```js
//
// Create a proxy server for websockets
//
httpProxy.createServer({
target: 'ws://localhost:9014',
ws: true
}).listen(8014);
```
Also you can proxy the websocket requests just calling the `ws(req, socket, head)` method.
```js
//
// Setup our server to proxy standard HTTP requests
//
var proxy = new httpProxy.createProxyServer({
target: {
host: 'localhost',
port: 9015
}
});
var proxyServer = http.createServer(function (req, res) {
proxy.web(req, res);
});
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
proxy.ws(req, socket, head);
});
proxyServer.listen(8015);
```
**[Back to top](#table-of-contents)**
### Options
`httpProxy.createProxyServer` supports the following options:
* **target**: url string to be parsed with the url module
* **forward**: url string to be parsed with the url module
* **agent**: object to be passed to http(s).request (see Node's [https agent](http://nodejs.org/api/https.html#https_class_https_agent) and [http agent](http://nodejs.org/api/http.html#http_class_http_agent) objects)
* **ssl**: object to be passed to https.createServer()
* **ws**: true/false, if you want to proxy websockets
* **xfwd**: true/false, adds x-forward headers
* **secure**: true/false, if you want to verify the SSL Certs
* **toProxy**: true/false, passes the absolute URL as the `path` (useful for proxying to proxies)
* **prependPath**: true/false, Default: true - specify whether you want to prepend the target's path to the proxy path
* **ignorePath**: true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request (note: you will have to append / manually if required).
* **localAddress**: Local interface string to bind for outgoing connections
* **changeOrigin**: true/false, Default: false - changes the origin of the host header to the target URL
* **preserveHeaderKeyCase**: true/false, Default: false - specify whether you want to keep letter case of response header key
* **auth**: Basic authentication i.e. 'user:password' to compute an Authorization header.
* **hostRewrite**: rewrites the location hostname on (201/301/302/307/308) redirects.
* **autoRewrite**: rewrites the location host/port on (201/301/302/307/308) redirects based on requested host/port. Default: false.
* **protocolRewrite**: rewrites the location protocol on (201/301/302/307/308) redirects to 'http' or 'https'. Default: null.
* **cookieDomainRewrite**: rewrites domain of `set-cookie` headers. Possible values:
* `false` (default): disable cookie rewriting
* String: new domain, for example `cookieDomainRewrite: "new.domain"`. To remove the domain, use `cookieDomainRewrite: ""`.
* Object: mapping of domains to new domains, use `"*"` to match all domains.
For example keep one domain unchanged, rewrite one domain and remove other domains:
```
cookieDomainRewrite: {
"unchanged.domain": "unchanged.domain",
"old.domain": "new.domain",
"*": ""
}
```
* **cookiePathRewrite**: rewrites path of `set-cookie` headers. Possible values:
* `false` (default): disable cookie rewriting
* String: new path, for example `cookiePathRewrite: "/newPath/"`. To remove the path, use `cookiePathRewrite: ""`. To set path to root use `cookiePathRewrite: "/"`.
* Object: mapping of paths to new paths, use `"*"` to match all paths.
For example, to keep one path unchanged, rewrite one path and remove other paths:
```
cookiePathRewrite: {
"/unchanged.path/": "/unchanged.path/",
"/old.path/": "/new.path/",
"*": ""
}
```
* **headers**: object with extra headers to be added to target requests.
* **proxyTimeout**: timeout (in millis) for outgoing proxy requests
* **timeout**: timeout (in millis) for incoming requests
* **followRedirects**: true/false, Default: false - specify whether you want to follow redirects
* **selfHandleResponse** true/false, if set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the `proxyRes` event
* **buffer**: stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called 'req.rawbody' you could restream this field in the buffer option:
```
'use strict';
const streamify = require('stream-array');
const HttpProxy = require('http-proxy');
const proxy = new HttpProxy();
module.exports = (req, res, next) => {
proxy.web(req, res, {
target: 'http://localhost:4003/',
buffer: streamify(req.rawBody)
}, next);
};
```
**NOTE:**
`options.ws` and `options.ssl` are optional.
`options.target` and `options.forward` cannot both be missing
If you are using the `proxyServer.listen` method, the following options are also applicable:
* **ssl**: object to be passed to https.createServer()
* **ws**: true/false, if you want to proxy websockets
### Installing npm (node package manager)
<pre>
curl http://npmjs.org/install.sh | sh
</pre>
**[Back to top](#table-of-contents)**
### Installing node-http-proxy
<pre>
npm install http-proxy
</pre>
### Listening for proxy events
### How to setup a basic proxy server
<pre>
var http = require('http'),
httpProxy = require('http-proxy');
* `error`: The error event is emitted if the request to the target fail. **We do not do any error handling of messages passed between client and proxy, and messages passed between proxy and target, so it is recommended that you listen on errors and handle them.**
* `proxyReq`: This event is emitted before the data is sent. It gives you a chance to alter the proxyReq request object. Applies to "web" connections
* `proxyReqWs`: This event is emitted before the data is sent. It gives you a chance to alter the proxyReq request object. Applies to "websocket" connections
* `proxyRes`: This event is emitted if the request to the target got a response.
* `open`: This event is emitted once the proxy websocket was created and piped into the target websocket.
* `close`: This event is emitted once the proxy websocket was closed.
* (DEPRECATED) `proxySocket`: Deprecated in favor of `open`.
httpProxy.createServer(9000, 'localhost').listen(8000);
```js
var httpProxy = require('http-proxy');
// Error example
//
// Http Proxy Server with bad target
//
var proxy = httpProxy.createServer({
target:'http://localhost:9005'
});
http.createServer(function (req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
</pre>
proxy.listen(8005);
see the [demo](http://github.com/nodejitsu/node-http-proxy/blob/master/demo.js) for further examples.
//
// Listen for the `error` event on `proxy`.
proxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
### How to setup a proxy server with custom server logic
<pre>
var http = require('http'),
httpProxy = require('http-proxy');
res.end('Something went wrong. And we are reporting a custom error message.');
});
// create a proxy server with custom application logic
httpProxy.createServer(function (req, res, proxyRequest) {
// Put your custom server logic here
proxyRequest(9000, 'localhost');
}).listen(8000);
//
// Listen for the `proxyRes` event on `proxy`.
//
proxy.on('proxyRes', function (proxyRes, req, res) {
console.log('RAW Response from the target', JSON.stringify(proxyRes.headers, true, 2));
});
http.createServer(function (req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('request successfully proxied: ' + req.url +'\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
</pre>
//
// Listen for the `open` event on `proxy`.
//
proxy.on('open', function (proxySocket) {
// listen for messages coming FROM the target here
proxySocket.on('data', hybiParseAndLogMessage);
});
### How to proxy requests with latent operations (IO, etc.)
//
// Listen for the `close` event on `proxy`.
//
proxy.on('close', function (res, socket, head) {
// view disconnected websocket connections
console.log('Client disconnected');
});
```
node-http-proxy supports event buffering, that means if an event (like 'data', or 'end') is raised by the incoming request before you have a chance to perform your custom server logic, those events will be captured and re-raised when you later proxy the request. Here's a simple example:
**[Back to top](#table-of-contents)**
<pre>
httpProxy.createServer(function (req, res, proxyRequest) {
setTimeout(function () {
proxyRequest(port, server);
}, latency);
}).listen(8081);
</pre>
### Shutdown
### Why doesn't node-http-proxy have more advanced features like x, y, or z?
* When testing or running server within another program it may be necessary to close the proxy.
* This will stop the proxy from accepting new connections.
If you have a suggestion for a feature currently not supported, feel free to open a [support issue](http://github.com/nodejitsu/node-http-proxy/issues). node-http-proxy is designed to just proxy http requests from one server to another, but we will be soon releasing many other complimentary projects that can be used in conjunction with node-http-proxy.
```js
var proxy = new httpProxy.createProxyServer({
target: {
host: 'localhost',
port: 1337
}
});
proxy.close();
```
**[Back to top](#table-of-contents)**
### Miscellaneous
If you want to handle your own response after receiving the `proxyRes`, you can do
so with `selfHandleResponse`. As you can see below, if you use this option, you
are able to intercept and read the `proxyRes` but you must also make sure to
reply to the `res` itself otherwise the original client will never receive any
data.
### Modify response
```js
var option = {
target: target,
selfHandleResponse : true
};
proxy.on('proxyRes', function (proxyRes, req, res) {
var body = [];
proxyRes.on('data', function (chunk) {
body.push(chunk);
});
proxyRes.on('end', function () {
body = Buffer.concat(body).toString();
console.log("res from proxied server:", body);
res.end("my response to cli");
});
});
proxy.web(req, res, option);
```
#### ProxyTable API
A proxy table API is available through this add-on [module](https://github.com/donasaur/http-proxy-rules), which lets you define a set of rules to translate matching routes to target routes that the reverse proxy will talk to.
#### Test
```
$ npm test
```
#### Logo
Logo created by [Diego Pasquali](http://dribbble.com/diegopq)
**[Back to top](#table-of-contents)**
### Contributing and Issues
* Read carefully our [Code Of Conduct](https://github.com/http-party/node-http-proxy/blob/master/CODE_OF_CONDUCT.md)
* Search on Google/Github
* If you can't find anything, open an issue
* If you feel comfortable about fixing the issue, fork the repo
* Commit to your local branch (which must be different from `master`)
* Submit your Pull Request (be sure to include tests and update documentation)
**[Back to top](#table-of-contents)**
<br/>
### License
(The MIT License)
Copyright (c) 2010 Charlie Robbins, Mikeal Rogers & Marak Squires
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.
[0]:http://nodejitsu.com "nodejitsu.com"
>The MIT License (MIT)
>
>Copyright (c) 2010 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
>
>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.

97
UPGRADING.md Normal file
View File

@ -0,0 +1,97 @@
Looking to upgrade from `http-proxy@0.x.x` to `http-proxy@1.0`? You've come to the right place!
`http-proxy@1.0` is a from-scratch implementation of `http-proxy` and, as such
brings some breaking changes to APIs.
## Server creation
Available through `.createServer()` or `.createProxyServer()`.
```javascript
httpProxy.createServer({
target:'http://localhost:9003'
}).listen(8003);
```
Check the [README.md](https://github.com/http-party/node-http-proxy/blob/caronte/README.md) for a more detailed explanation of the parameters.
## Proxying
Web proxying is done by calling the `.web()` method on a Proxy instance. You can check among some use cases in the [examples folder](https://github.com/http-party/node-http-proxy/tree/caronte/examples/http)
```javascript
//
// Create a HTTP Proxy server with a HTTPS target
//
httpProxy.createProxyServer({
target: 'https://google.com',
agent : https.globalAgent,
headers: {
host: 'google.com'
}
}).listen(8011);
```
Websockets are proxied by the `.ws()` method. The [examples folder](https://github.com/http-party/node-http-proxy/tree/caronte/examples/websocket) again provides a lot of useful snippets!
```javascript
var proxy = new httpProxy.createProxyServer({
target: {
host: 'localhost',
port: 9015
}
});
var proxyServer = http.createServer(function (req, res) {
proxy.web(req, res);
});
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
proxy.ws(req, socket, head);
});
```
## Error Handling
It is possible to listen globally on the `error` event on the server. In alternative, a
callback passed to `.web()` or `.ws()` as last parameter is also accepted.
```javascript
var proxy = httpProxy.createServer({
target:'http://localhost:9005'
});
//
// Tell the proxy to listen on port 8000
//
proxy.listen(8005);
//
// Listen for the `error` event on `proxy`.
proxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong. And we are reporting a custom error message.');
});
```
## Dropped
Since the API was rewritten to be extremely flexible we decided to drop some features
which were in the core and delegate them to eventual "userland" modules.
- Middleware API
- ProxyTable API
### Middleware API
The new API makes it really easy to implement code that behaves like the old Middleware API. You can check some examples [here](https://github.com/http-party/node-http-proxy/tree/caronte/examples/middleware)
### ProxyTable API
See this [link](https://github.com/donasaur/http-proxy-rules/) for an add-on proxy rules module that you can use to simulate the old ProxyTable API.

37
benchmark/README.md Normal file
View File

@ -0,0 +1,37 @@
# Benchmarking `node-http-proxy`
The long-term goal of these scripts and documentation is to provide a consistent and well understood benchmarking process for `node-http-proxy` so that performance does not degrade over time. They were initially created to compare the performance of `v0.10.3` and `v1.0.0` (which was a significant rewrite).
## Pre-requisites
All benchmarking shall be done with [wrk](https://github.com/wg/wrk) which _is the same tool used for performance testing by the node.js core team._ **Make sure you have `wrk` installed before continuing**.
```
$ wrk
Usage: wrk <options> <url>
Options:
-c, --connections <N> Connections to keep open
-d, --duration <T> Duration of test
-t, --threads <N> Number of threads to use
-s, --script <S> Load Lua script file
-H, --header <H> Add header to request
--latency Print latency statistics
--timeout <T> Socket/request timeout
-v, --version Print version details
Numeric arguments may include a SI unit (1k, 1M, 1G)
Time arguments may include a time unit (2s, 2m, 2h)
```
## Benchmarks
1. [Simple HTTP benchmark](#simple-http)
### Simple HTTP
_This benchmark requires three terminals running:_
1. **A proxy server:** `node benchmark/scripts/proxy.js`
2. **A target server:** `node benchmark/scripts/hello.js`
3. **A wrk process:** `wrk -c 20 -d5m -t 2 http://127.0.0.1:8000`

View File

@ -0,0 +1,3 @@
require('http').createServer(function(req, res) {
res.end('Hello world!');
}).listen(9000);

View File

@ -0,0 +1,6 @@
var http = require('http'),
httpProxy = require('../../');
//
// Create your proxy server
//
httpProxy.createProxyServer({ target: 'http://localhost:9000' }).listen(8000);

View File

@ -0,0 +1,88 @@
var crypto = require('crypto'),
WebSocket = require('ws'),
async = require('async'),
httpProxy = require('../../');
var SERVER_PORT = 8415,
PROXY_PORT = 8514;
var testSets = [
{
size: 1024 * 1024, // 1 MB
count: 128 // 128 MB
},
{
size: 1024, // 1 KB,
count: 1024 // 1 MB
},
{
size: 128, // 128 B
count: 1024 * 8 // 1 MB
}
];
testSets.forEach(function (set) {
set.buffer = new Buffer(crypto.randomBytes(set.size));
set.buffers = [];
for (var i = 0; i < set.count; i++) {
set.buffers.push(set.buffer);
}
});
function runSet(set, callback) {
function runAgainst(port, callback) {
function send(sock) {
sock.send(set.buffers[got++]);
if (got === set.count) {
t = new Date() - t;
server.close();
proxy.close();
callback(null, t);
}
}
var server = new WebSocket.Server({ port: SERVER_PORT }),
proxy = httpProxy.createServer(SERVER_PORT, 'localhost').listen(PROXY_PORT),
client = new WebSocket('ws://localhost:' + port),
got = 0,
t = new Date();
server.on('connection', function (ws) {
send(ws);
ws.on('message', function (msg) {
send(ws);
});
});
client.on('message', function () {
send(client);
});
}
async.series({
server: async.apply(runAgainst, SERVER_PORT),
proxy: async.apply(runAgainst, PROXY_PORT)
}, function (err, results) {
if (err) {
throw err;
}
var mb = (set.size * set.count) / (1024 * 1024);
console.log(set.size / (1024) + ' KB * ' + set.count + ' (' + mb + ' MB)');
Object.keys(results).forEach(function (key) {
var t = results[key],
throughput = mb / (t / 1000);
console.log(' ' + key + ' took ' + t + ' ms (' + throughput + ' MB/s)');
});
callback();
});
}
async.forEachLimit(testSets, 1, runSet);

View File

@ -1,3 +0,0 @@
Benchmarks are being run on a development laptop using apache ab (everything running locally, on one machine)
These benchmarks should not be considered very accurate, or indicative of actual results. There are numerous factors that could cause these numbers to be inaccurate. These benchmarks should only be considered a very basic baseline to determine changes in performance as we iterate on this project.

View File

@ -1,56 +0,0 @@
[Marak@Maraks-MacBook-Pro ~/dev/zalgo.js]$ ab -c 50 -n 1000 -k http://127.0.0.1:9000/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software:
Server Hostname: 127.0.0.1
Server Port: 9000
Document Path: /
Document Length: 149 bytes
Concurrency Level: 50
Time taken for tests: 0.178 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 0
Total transferred: 213213 bytes
HTML transferred: 149149 bytes
Requests per second: 5627.84 [#/sec] (mean)
Time per request: 8.884 [ms] (mean)
Time per request: 0.178 [ms] (mean, across all concurrent requests)
Transfer rate: 1171.81 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 0.9 1 5
Processing: 3 8 2.6 7 17
Waiting: 1 7 2.4 7 17
Total: 5 9 2.4 8 17
Percentage of the requests served within a certain time (ms)
50% 8
66% 9
75% 9
80% 10
90% 13
95% 14
98% 15
99% 16
100% 17 (longest request)

View File

@ -1,56 +0,0 @@
[Marak@Maraks-MacBook-Pro ~]$ ab -c 5 -n 1000 http://127.0.0.1:8000/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software:
Server Hostname: 127.0.0.1
Server Port: 8000
Document Path: /
Document Length: 155 bytes
Concurrency Level: 5
Time taken for tests: 0.602 seconds
Complete requests: 1000
Failed requests: 5
(Connect: 0, Receive: 0, Length: 5, Exceptions: 0)
Write errors: 0
Total transferred: 247030 bytes
HTML transferred: 155030 bytes
Requests per second: 1660.64 [#/sec] (mean)
Time per request: 3.011 [ms] (mean)
Time per request: 0.602 [ms] (mean, across all concurrent requests)
Transfer rate: 400.61 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 2 3 0.8 3 10
Waiting: 2 3 0.8 3 10
Total: 2 3 0.8 3 10
Percentage of the requests served within a certain time (ms)
50% 3
66% 3
75% 3
80% 3
90% 3
95% 4
98% 5
99% 9
100% 10 (longest request)

10
codecov.yml Normal file
View File

@ -0,0 +1,10 @@
coverage:
parsers:
javascript:
enable_partials: yes
status:
project:
default:
target: "70%"
patch:
enabled: false

61
demo.js
View File

@ -1,61 +0,0 @@
/*
demo.js: http proxy for node.js
Copyright (c) 2010 Charlie Robbins & Marak Squires http://github.com/nodejitsu/node-http-proxy
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.
*/
var sys = require('sys'),
colors = require('colors')
http = require('http'),
httpProxy = require('./lib/node-http-proxy');
// ascii art from http://github.com/marak/asciimo
var welcome = '\
# # ##### ##### ##### ##### ##### #### # # # # \n\
# # # # # # # # # # # # # # # # \n\
###### # # # # ##### # # # # # # ## # \n\
# # # # ##### ##### ##### # # ## # \n\
# # # # # # # # # # # # # \n\
# # # # # # # # #### # # # \n';
sys.puts(welcome.rainbow.bold);
/****** basic http proxy server ******/
httpProxy.createServer(9000, 'localhost').listen(8000);
sys.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8000'.yellow);
/****** http proxy server with latency******/
httpProxy.createServer(function (req, res, proxyRequest){
setTimeout(function(){
proxyRequest(9000, 'localhost', req, res);
}, 2000)
}).listen(8001);
sys.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8001 '.yellow + 'with latency'.magenta.underline );
/****** regular http server ******/
http.createServer(function (req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
sys.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9000 '.yellow);

BIN
doc/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -0,0 +1,83 @@
/*
simple-balancer.js: Example of a simple round robin balancer for websockets
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var http = require('http'),
httpProxy = require('../../lib/http-proxy');
//
// A simple round-robin load balancing strategy.
//
// First, list the servers you want to use in your rotation.
//
var addresses = [
{
host: 'ws1.0.0.0',
port: 80
},
{
host: 'ws2.0.0.0',
port: 80
}
];
//
// Create a HttpProxy object for each target
//
var proxies = addresses.map(function (target) {
return new httpProxy.createProxyServer({
target: target
});
});
//
// Get the proxy at the front of the array, put it at the end and return it
// If you want a fancier balancer, put your code here
//
function nextProxy() {
var proxy = proxies.shift();
proxies.push(proxy);
return proxy;
}
//
// Get the 'next' proxy and send the http request
//
var server = http.createServer(function (req, res) {
nextProxy().web(req, res);
});
//
// Get the 'next' proxy and send the upgrade request
//
server.on('upgrade', function (req, socket, head) {
nextProxy().ws(req, socket, head);
});
server.listen(8001);

View File

@ -0,0 +1,64 @@
/*
simple-balancer.js: Example of a simple round robin balancer
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var http = require('http'),
httpProxy = require('../../lib/http-proxy');
//
// A simple round-robin load balancing strategy.
//
// First, list the servers you want to use in your rotation.
//
var addresses = [
{
host: 'ws1.0.0.0',
port: 80
},
{
host: 'ws2.0.0.0',
port: 80
}
];
var proxy = httpProxy.createServer();
http.createServer(function (req, res) {
//
// On each request, get the first location from the list...
//
var target = { target: addresses.shift() };
//
// ...then proxy to the server whose 'turn' it is...
//
console.log('balancing request to: ', target);
proxy.web(req, res, target);
//
// ...and then the server you just used becomes the last item in the list.
//
addresses.push(target.target);
}).listen(8021);
// Rinse; repeat; enjoy.

64
examples/helpers/store.js Normal file
View File

@ -0,0 +1,64 @@
//
// just to make these example a little bit interesting,
// make a little key value store with an http interface
// (see couchdb for a grown-up version of this)
//
// API:
// GET /
// retrive list of keys
//
// GET /[url]
// retrive object stored at [url]
// will respond with 404 if there is nothing stored at [url]
//
// POST /[url]
//
// JSON.parse the body and store it under [url]
// will respond 400 (bad request) if body is not valid json.
//
// TODO: cached map-reduce views and auto-magic sharding.
//
var Store = module.exports = function Store () {
this.store = {};
};
Store.prototype = {
get: function (key) {
return this.store[key]
},
set: function (key, value) {
return this.store[key] = value
},
handler:function () {
var store = this
return function (req, res) {
function send (obj, status) {
res.writeHead(200 || status,{'Content-Type': 'application/json'})
res.write(JSON.stringify(obj) + '\n')
res.end()
}
var url = req.url.split('?').shift()
if (url === '/') {
console.log('get index')
return send(Object.keys(store.store))
} else if (req.method == 'GET') {
var obj = store.get (url)
send(obj || {error: 'not_found', url: url}, obj ? 200 : 404)
} else {
//post: buffer body, and parse.
var body = '', obj
req.on('data', function (c) { body += c})
req.on('end', function (c) {
try {
obj = JSON.parse(body)
} catch (err) {
return send (err, 400)
}
store.set(url, obj)
send({ok: true})
})
}
}
}
}

View File

@ -0,0 +1,60 @@
/*
basic-proxy.js: Basic example of proxying over HTTP
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
httpProxy = require('../../lib/http-proxy');
var welcome = [
'# # ##### ##### ##### ##### ##### #### # # # #',
'# # # # # # # # # # # # # # # # ',
'###### # # # # ##### # # # # # # ## # ',
'# # # # ##### ##### ##### # # ## # ',
'# # # # # # # # # # # # # ',
'# # # # # # # # #### # # # '
].join('\n');
util.puts(welcome.rainbow.bold);
//
// Basic Http Proxy Server
//
httpProxy.createServer({
target:'http://localhost:9003'
}).listen(8003);
//
// Target Http Server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9003);
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8003'.yellow);
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9003 '.yellow);

View File

@ -0,0 +1,68 @@
/*
concurrent-proxy.js: check levelof concurrency through proxy.
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
httpProxy = require('../../lib/http-proxy');
//
// Basic Http Proxy Server
//
httpProxy.createServer({
target:'http://localhost:9004'
}).listen(8004);
//
// Target Http Server
//
// to check apparent problems with concurrent connections
// make a server which only responds when there is a given nubmer on connections
//
var connections = [],
go;
http.createServer(function (req, res) {
connections.push(function () {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
});
process.stdout.write(connections.length + ', ');
if (connections.length > 110 || go) {
go = true;
while (connections.length) {
connections.shift()();
}
}
}).listen(9004);
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8004'.yellow);
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9004 '.yellow);

View File

@ -0,0 +1,55 @@
/*
custom-proxy-error.js: Example of using the custom `proxyError` event.
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
httpProxy = require('../../lib/http-proxy');
//
// Http Proxy Server with bad target
//
var proxy = httpProxy.createServer({
target:'http://localhost:9005'
});
//
// Tell the proxy to listen on port 8000
//
proxy.listen(8005);
//
// Listen for the `error` event on `proxy`.
proxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong. And we are reporting a custom error message.');
});
util.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8005 '.yellow + 'with custom error message'.magenta.underline);

View File

@ -0,0 +1,63 @@
/*
error-handling.js: Example of handle erros for HTTP and WebSockets
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
httpProxy = require('../../lib/http-proxy');
//
// HTTP Proxy Server
//
var proxy = httpProxy.createProxyServer({target:'http://localhost:9000', ws:true});
//
// Example of error handling
//
function requestHandler(req, res) {
// Pass a callback to the web proxy method
// and catch the error there.
proxy.web(req, res, function (err) {
// Now you can get the err
// and handle it by your self
// if (err) throw err;
res.writeHead(502);
res.end("There was an error proxying your request");
});
// In a websocket request case
req.on('upgrade', function (req, socket, head) {
proxy.ws(req, socket, head, function (err) {
// Now you can get the err
// and handle it by your self
// if (err) throw err;
socket.close();
})
})
}
http.createServer(requestHandler).listen(8000);
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8000'.yellow);

View File

@ -0,0 +1,67 @@
/*
forward-and-target-proxy.js: Example of proxying over HTTP with additional forward proxy
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
httpProxy = require('../../lib/http-proxy');
//
// Setup proxy server with forwarding
//
httpProxy.createServer({
target: {
port: 9006,
host: 'localhost'
},
forward: {
port: 9007,
host: 'localhost'
}
}).listen(8006);
//
// Target Http Server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9006);
//
// Target Http Forwarding Server
//
http.createServer(function (req, res) {
util.puts('Receiving forward for: ' + req.url);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully forwarded to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9007);
util.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8006 '.yellow + 'with forward proxy'.magenta.underline);
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9006 '.yellow);
util.puts('http forward server '.blue + 'started '.green.bold + 'on port '.blue + '9007 '.yellow);

View File

@ -0,0 +1,53 @@
/*
forward-proxy.js: Example of proxying over HTTP with additional forward proxy
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
httpProxy = require('../../lib/http-proxy');
//
// Setup proxy server with forwarding
//
httpProxy.createServer({
forward: {
port: 9019,
host: 'localhost'
}
}).listen(8019);
//
// Target Http Forwarding Server
//
http.createServer(function (req, res) {
util.puts('Receiving forward for: ' + req.url);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully forwarded to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9019);
util.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8019 '.yellow + 'with forward proxy'.magenta.underline);
util.puts('http forward server '.blue + 'started '.green.bold + 'on port '.blue + '9019 '.yellow);

View File

@ -0,0 +1,54 @@
/*
latent-proxy.js: Example of proxying over HTTP with latency
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
httpProxy = require('../../lib/http-proxy');
//
// Http Proxy Server with Latency
//
var proxy = httpProxy.createProxyServer();
http.createServer(function (req, res) {
setTimeout(function () {
proxy.web(req, res, {
target: 'http://localhost:9008'
});
}, 500);
}).listen(8008);
//
// Target Http Server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9008);
util.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8008 '.yellow + 'with latency'.magenta.underline);
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9008 '.yellow);

View File

@ -0,0 +1,26 @@
var httpProxy = require('../../lib/http-proxy');
var Agent = require('agentkeepalive');
var agent = new Agent({
maxSockets: 100,
keepAlive: true,
maxFreeSockets: 10,
keepAliveMsecs:1000,
timeout: 60000,
keepAliveTimeout: 30000 // free socket keepalive for 30 seconds
});
var proxy = httpProxy.createProxy({ target: 'http://whatever.com', agent: agent });
//
// Modify headers of the response before it gets sent
// So that we handle the NLTM authentication response
//
proxy.on('proxyRes', function (proxyRes) {
var key = 'www-authenticate';
proxyRes.headers[key] = proxyRes.headers[key] && proxyRes.headers[key].split(',');
});
require('http').createServer(function (req, res) {
proxy.web(req, res);
}).listen(3000);

View File

@ -0,0 +1,46 @@
/*
proxy-http-to-https.js: Basic example of proxying over HTTP to a target HTTPS server
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var https = require('https'),
http = require('http'),
util = require('util'),
path = require('path'),
fs = require('fs'),
colors = require('colors'),
httpProxy = require('../../lib/http-proxy');
//
// Create a HTTP Proxy server with a HTTPS target
//
httpProxy.createProxyServer({
target: 'https://google.com',
agent : https.globalAgent,
headers: {
host: 'google.com'
}
}).listen(8011);
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8011'.yellow);

View File

@ -0,0 +1,60 @@
/*
proxy-https-to-http.js: Basic example of proxying over HTTPS to a target HTTP server
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var https = require('https'),
http = require('http'),
util = require('util'),
path = require('path'),
fs = require('fs'),
colors = require('colors'),
httpProxy = require('../../lib/http-proxy'),
fixturesDir = path.join(__dirname, '..', '..', 'test', 'fixtures');
//
// Create the target HTTP server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('hello http over https\n');
res.end();
}).listen(9009);
//
// Create the HTTPS proxy server listening on port 8000
//
httpProxy.createServer({
target: {
host: 'localhost',
port: 9009
},
ssl: {
key: fs.readFileSync(path.join(fixturesDir, 'agent2-key.pem'), 'utf8'),
cert: fs.readFileSync(path.join(fixturesDir, 'agent2-cert.pem'), 'utf8')
}
}).listen(8009);
util.puts('https proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8009'.yellow);
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9009 '.yellow);

View File

@ -0,0 +1,59 @@
/*
proxy-https-to-https.js: Basic example of proxying over HTTPS to a target HTTPS server
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var https = require('https'),
http = require('http'),
util = require('util'),
fs = require('fs'),
path = require('path'),
colors = require('colors'),
httpProxy = require('../../lib/http-proxy'),
fixturesDir = path.join(__dirname, '..', '..', 'test', 'fixtures'),
httpsOpts = {
key: fs.readFileSync(path.join(fixturesDir, 'agent2-key.pem'), 'utf8'),
cert: fs.readFileSync(path.join(fixturesDir, 'agent2-cert.pem'), 'utf8')
};
//
// Create the target HTTPS server
//
https.createServer(httpsOpts, function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('hello https\n');
res.end();
}).listen(9010);
//
// Create the proxy server listening on port 8010
//
httpProxy.createServer({
ssl: httpsOpts,
target: 'https://localhost:9010',
secure: false
}).listen(8010);
util.puts('https proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8010'.yellow);
util.puts('https server '.blue + 'started '.green.bold + 'on port '.blue + '9010 '.yellow);

View File

@ -0,0 +1,55 @@
/*
reverse-proxy.js: Example of reverse proxying (with HTTPS support)
Copyright (c) 2015 Alberto Pose <albertopose@gmail.com>
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.
*/
var http = require('http'),
net = require('net'),
httpProxy = require('../../lib/http-proxy'),
url = require('url'),
util = require('util');
var proxy = httpProxy.createServer();
var server = http.createServer(function (req, res) {
util.puts('Receiving reverse proxy request for:' + req.url);
var parsedUrl = url.parse(req.url);
var target = parsedUrl.protocol + '//' + parsedUrl.hostname;
proxy.web(req, res, {target: target, secure: false});
}).listen(8213);
server.on('connect', function (req, socket) {
util.puts('Receiving reverse proxy request for:' + req.url);
var serverUrl = url.parse('https://' + req.url);
var srvSocket = net.connect(serverUrl.port, serverUrl.hostname, function() {
socket.write('HTTP/1.1 200 Connection Established\r\n' +
'Proxy-agent: Node-Proxy\r\n' +
'\r\n');
srvSocket.pipe(socket);
socket.pipe(srvSocket);
});
});
// Test with:
// curl -vv -x http://127.0.0.1:8213 https://www.google.com
// curl -vv -x http://127.0.0.1:8213 http://www.google.com

67
examples/http/sse.js Normal file
View File

@ -0,0 +1,67 @@
/*
sse.js: Basic example of proxying over HTTP
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
httpProxy = require('../../lib/http-proxy'),
SSE = require('sse');
//
// Basic Http Proxy Server
//
var proxy = new httpProxy.createProxyServer();
http.createServer(function (req, res) {
proxy.web(req, res, {
target: 'http://localhost:9003'
});
}).listen(8003);
//
// Target Http Server
//
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
});
//
// Use SSE
//
var sse = new SSE(server, {path: '/'});
sse.on('connection', function(client) {
var count = 0;
setInterval(function(){
client.send('message #' + count++);
}, 1500);
});
server.listen(9003);
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8003'.yellow);
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9003 '.yellow);

View File

@ -0,0 +1,54 @@
/*
standalone-proxy.js: Example of proxying over HTTP with a standalone HTTP server.
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
httpProxy = require('../../lib/http-proxy');
//
// Http Server with proxyRequest Handler and Latency
//
var proxy = new httpProxy.createProxyServer();
http.createServer(function (req, res) {
setTimeout(function () {
proxy.web(req, res, {
target: 'http://localhost:9002'
});
}, 200);
}).listen(8002);
//
// Target Http Server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9002);
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '8002 '.yellow + 'with proxy.web() handler'.cyan.underline + ' and latency'.magenta);
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9002 '.yellow);

View File

@ -0,0 +1,108 @@
/*
bodyDecoder-middleware.js: Basic example of `connect.bodyParser()` middleware in node-http-proxy
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var http = require('http'),
connect = require('connect'),
request = require('request'),
colors = require('colors'),
util = require('util'),
queryString = require('querystring'),
bodyParser = require('body-parser'),
httpProxy = require('../../lib/http-proxy'),
proxy = httpProxy.createProxyServer({});
//restream parsed body before proxying
proxy.on('proxyReq', function(proxyReq, req, res, options) {
if (!req.body || !Object.keys(req.body).length) {
return;
}
var contentType = proxyReq.getHeader('Content-Type');
var bodyData;
if (contentType === 'application/json') {
bodyData = JSON.stringify(req.body);
}
if (contentType === 'application/x-www-form-urlencoded') {
bodyData = queryString.stringify(req.body);
}
if (bodyData) {
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
proxyReq.write(bodyData);
}
});
//
// Basic Http Proxy Server
//
var app = connect()
.use(bodyParser.json())//json parser
.use(bodyParser.urlencoded())//urlencoded parser
.use(function(req, res){
// modify body here,
// eg: req.body = {a: 1}.
console.log('proxy body:',req.body)
proxy.web(req, res, {
target: 'http://127.0.0.1:9013'
})
});
http.createServer(app).listen(8013, function(){
console.log('proxy linsten 8013');
});
//
// Target Http Server
//
var app1 = connect()
.use(bodyParser.json())
.use(function(req, res){
console.log('app1:',req.body)
res.end('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
});
http.createServer(app1).listen(9013, function(){
//request to 8013 to proxy
request.post({//
url: 'http://127.0.0.1:8013',
json: {content: 123, type: "greeting from json request"}
},function(err, res,data){
console.log('return for json request:' ,err, data)
})
// application/x-www-form-urlencoded request
request.post({//
url: 'http://127.0.0.1:8013',
form: {content: 123, type: "greeting from urlencoded request"}
},function(err, res,data){
console.log('return for urlencoded request:' ,err, data)
})
});

View File

@ -0,0 +1,65 @@
/*
gzip-middleware.js: Basic example of `connect-gzip` middleware in node-http-proxy
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
connect = require('connect'),
httpProxy = require('../../lib/http-proxy');
//
// Basic Connect App
//
connect.createServer(
connect.compress({
// Pass to connect.compress() the options
// that you need, just for show the example
// we use threshold to 1
threshold: 1
}),
function (req, res) {
proxy.web(req, res);
}
).listen(8012);
//
// Basic Http Proxy Server
//
var proxy = httpProxy.createProxyServer({
target: 'http://localhost:9012'
});
//
// Target Http Server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9012);
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8012'.yellow);
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9012 '.yellow);

View File

@ -0,0 +1,69 @@
/*
modifyBody-middleware.js: Example of middleware which modifies response
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
colors = require('colors'),
http = require('http'),
connect = require('connect'),
app = connect(),
httpProxy = require('../../lib/http-proxy');
//
// Basic Connect App
//
app.use(function (req, res, next) {
var _write = res.write;
res.write = function (data) {
_write.call(res, data.toString().replace("Ruby", "http-party"));
}
next();
});
app.use(function (req, res) {
proxy.web(req, res)
});
http.createServer(app).listen(8013);
//
// Basic Http Proxy Server
//
var proxy = httpProxy.createProxyServer({
target: 'http://localhost:9013'
});
//
// Target Http Server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, I love Ruby\n');
}).listen(9013);
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8013'.yellow);
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9013 '.yellow);

14
examples/package.json Normal file
View File

@ -0,0 +1,14 @@
{
"name": "http-proxy-examples",
"description": "packages required to run the examples",
"version": "0.0.0",
"dependencies": {
"agentkeepalive": "^4.0.0",
"colors": "~1.3.0",
"connect-restreamer": "~1.0.0",
"request": "~2.88.0",
"socket.io": "~0.9.16",
"socket.io-client": "~0.9.16",
"sse": "0.0.8"
}
}

View File

@ -0,0 +1,91 @@
/*
standalone-websocket-proxy.js: Example of proxying websockets over HTTP with a standalone HTTP server.
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
http = require('http'),
colors = require('colors'),
httpProxy = require('../../lib/http-proxy');
try {
var io = require('socket.io'),
client = require('socket.io-client');
}
catch (ex) {
console.error('Socket.io is required for this example:');
console.error('npm ' + 'install'.green);
process.exit(1);
}
//
// Create the target HTTP server and setup
// socket.io on it.
//
var server = io.listen(9016);
server.sockets.on('connection', function (client) {
util.debug('Got websocket connection');
client.on('message', function (msg) {
util.debug('Got message from client: ' + msg);
});
client.send('from server');
});
//
// Setup our server to proxy standard HTTP requests
//
var proxy = new httpProxy.createProxyServer({
target: {
host: 'localhost',
port: 9016
}
});
var proxyServer = http.createServer(function (req, res) {
proxy.web(req, res);
});
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
setTimeout(function () {
proxy.ws(req, socket, head);
}, 1000);
});
proxyServer.listen(8016);
//
// Setup the socket.io client against our proxy
//
var ws = client.connect('ws://localhost:8016');
ws.on('message', function (msg) {
util.debug('Got message: ' + msg);
ws.send('I am the client');
});

View File

@ -0,0 +1,88 @@
/*
standalone-websocket-proxy.js: Example of proxying websockets over HTTP with a standalone HTTP server.
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
http = require('http'),
colors = require('colors'),
httpProxy = require('../../lib/http-proxy');
try {
var io = require('socket.io'),
client = require('socket.io-client');
}
catch (ex) {
console.error('Socket.io is required for this example:');
console.error('npm ' + 'install'.green);
process.exit(1);
}
//
// Create the target HTTP server and setup
// socket.io on it.
//
var server = io.listen(9015);
server.sockets.on('connection', function (client) {
util.debug('Got websocket connection');
client.on('message', function (msg) {
util.debug('Got message from client: ' + msg);
});
client.send('from server');
});
//
// Setup our server to proxy standard HTTP requests
//
var proxy = new httpProxy.createProxyServer({
target: {
host: 'localhost',
port: 9015
}
});
var proxyServer = http.createServer(function (req, res) {
proxy.web(req, res);
});
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
proxy.ws(req, socket, head);
});
proxyServer.listen(8015);
//
// Setup the socket.io client against our proxy
//
var ws = client.connect('ws://localhost:8015');
ws.on('message', function (msg) {
util.debug('Got message: ' + msg);
ws.send('I am the client');
});

View File

@ -0,0 +1,70 @@
/*
web-socket-proxy.js: Example of proxying over HTTP and WebSockets.
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
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.
*/
var util = require('util'),
http = require('http'),
colors = require('colors'),
httpProxy = require('../../lib/http-proxy');
try {
var io = require('socket.io'),
client = require('socket.io-client');
}
catch (ex) {
console.error('Socket.io is required for this example:');
console.error('npm ' + 'install'.green);
process.exit(1);
}
//
// Create the target HTTP server and setup
// socket.io on it.
//
var server = io.listen(9014);
server.sockets.on('connection', function (client) {
util.debug('Got websocket connection');
client.on('message', function (msg) {
util.debug('Got message from client: ' + msg);
});
client.send('from server');
});
//
// Create a proxy server with node-http-proxy
//
httpProxy.createServer({ target: 'ws://localhost:9014', ws: true }).listen(8014);
//
// Setup the socket.io client against our proxy
//
var ws = client.connect('ws://localhost:8014');
ws.on('message', function (msg) {
util.debug('Got message: ' + msg);
ws.send('I am the client');
});

13
index.js Normal file
View File

@ -0,0 +1,13 @@
/*!
* Caron dimonio, con occhi di bragia
* loro accennando, tutte le raccoglie;
* batte col remo qualunque sadagia
*
* Charon the demon, with the eyes of glede,
* Beckoning to them, collects them all together,
* Beats with his oar whoever lags behind
*
* Dante - The Divine Comedy (Canto III)
*/
module.exports = require('./lib/http-proxy');

66
lib/http-proxy.js Normal file
View File

@ -0,0 +1,66 @@
// Use explicit /index.js to help browserify negociation in require '/lib/http-proxy' (!)
var ProxyServer = require('./http-proxy/index.js').Server;
/**
* Creates the proxy server.
*
* Examples:
*
* httpProxy.createProxyServer({ .. }, 8000)
* // => '{ web: [Function], ws: [Function] ... }'
*
* @param {Object} Options Config object passed to the proxy
*
* @return {Object} Proxy Proxy object with handlers for `ws` and `web` requests
*
* @api public
*/
function createProxyServer(options) {
/*
* `options` is needed and it must have the following layout:
*
* {
* target : <url string to be parsed with the url module>
* forward: <url string to be parsed with the url module>
* agent : <object to be passed to http(s).request>
* ssl : <object to be passed to https.createServer()>
* ws : <true/false, if you want to proxy websockets>
* xfwd : <true/false, adds x-forward headers>
* secure : <true/false, verify SSL certificate>
* toProxy: <true/false, explicitly specify if we are proxying to another proxy>
* prependPath: <true/false, Default: true - specify whether you want to prepend the target's path to the proxy path>
* ignorePath: <true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request>
* localAddress : <Local interface string to bind for outgoing connections>
* changeOrigin: <true/false, Default: false - changes the origin of the host header to the target URL>
* preserveHeaderKeyCase: <true/false, Default: false - specify whether you want to keep letter case of response header key >
* auth : Basic authentication i.e. 'user:password' to compute an Authorization header.
* hostRewrite: rewrites the location hostname on (201/301/302/307/308) redirects, Default: null.
* autoRewrite: rewrites the location host/port on (201/301/302/307/308) redirects based on requested host/port. Default: false.
* protocolRewrite: rewrites the location protocol on (201/301/302/307/308) redirects to 'http' or 'https'. Default: null.
* }
*
* NOTE: `options.ws` and `options.ssl` are optional.
* `options.target and `options.forward` cannot be
* both missing
* }
*/
return new ProxyServer(options);
}
ProxyServer.createProxyServer = createProxyServer;
ProxyServer.createServer = createProxyServer;
ProxyServer.createProxy = createProxyServer;
/**
* Export the proxy "Server" as the main export.
*/
module.exports = ProxyServer;

248
lib/http-proxy/common.js Normal file
View File

@ -0,0 +1,248 @@
var common = exports,
url = require('url'),
extend = require('util')._extend,
required = require('requires-port');
var upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i,
isSSL = /^https|wss/;
/**
* Simple Regex for testing if protocol is https
*/
common.isSSL = isSSL;
/**
* Copies the right headers from `options` and `req` to
* `outgoing` which is then used to fire the proxied
* request.
*
* Examples:
*
* common.setupOutgoing(outgoing, options, req)
* // => { host: ..., hostname: ...}
*
* @param {Object} Outgoing Base object to be filled with required properties
* @param {Object} Options Config object passed to the proxy
* @param {ClientRequest} Req Request Object
* @param {String} Forward String to select forward or target
* 
* @return {Object} Outgoing Object with all required properties set
*
* @api private
*/
common.setupOutgoing = function(outgoing, options, req, forward) {
outgoing.port = options[forward || 'target'].port ||
(isSSL.test(options[forward || 'target'].protocol) ? 443 : 80);
['host', 'hostname', 'socketPath', 'pfx', 'key',
'passphrase', 'cert', 'ca', 'ciphers', 'secureProtocol'].forEach(
function(e) { outgoing[e] = options[forward || 'target'][e]; }
);
outgoing.method = options.method || req.method;
outgoing.headers = extend({}, req.headers);
if (options.headers){
extend(outgoing.headers, options.headers);
}
if (options.auth) {
outgoing.auth = options.auth;
}
if (options.ca) {
outgoing.ca = options.ca;
}
if (isSSL.test(options[forward || 'target'].protocol)) {
outgoing.rejectUnauthorized = (typeof options.secure === "undefined") ? true : options.secure;
}
outgoing.agent = options.agent || false;
outgoing.localAddress = options.localAddress;
//
// Remark: If we are false and not upgrading, set the connection: close. This is the right thing to do
// as node core doesn't handle this COMPLETELY properly yet.
//
if (!outgoing.agent) {
outgoing.headers = outgoing.headers || {};
if (typeof outgoing.headers.connection !== 'string'
|| !upgradeHeader.test(outgoing.headers.connection)
) { outgoing.headers.connection = 'close'; }
}
// the final path is target path + relative path requested by user:
var target = options[forward || 'target'];
var targetPath = target && options.prependPath !== false
? (target.path || '')
: '';
//
// Remark: Can we somehow not use url.parse as a perf optimization?
//
var outgoingPath = !options.toProxy
? (url.parse(req.url).path || '')
: req.url;
//
// Remark: ignorePath will just straight up ignore whatever the request's
// path is. This can be labeled as FOOT-GUN material if you do not know what
// you are doing and are using conflicting options.
//
outgoingPath = !options.ignorePath ? outgoingPath : '';
outgoing.path = common.urlJoin(targetPath, outgoingPath);
if (options.changeOrigin) {
outgoing.headers.host =
required(outgoing.port, options[forward || 'target'].protocol) && !hasPort(outgoing.host)
? outgoing.host + ':' + outgoing.port
: outgoing.host;
}
return outgoing;
};
/**
* Set the proper configuration for sockets,
* set no delay and set keep alive, also set
* the timeout to 0.
*
* Examples:
*
* common.setupSocket(socket)
* // => Socket
*
* @param {Socket} Socket instance to setup
* 
* @return {Socket} Return the configured socket.
*
* @api private
*/
common.setupSocket = function(socket) {
socket.setTimeout(0);
socket.setNoDelay(true);
socket.setKeepAlive(true, 0);
return socket;
};
/**
* Get the port number from the host. Or guess it based on the connection type.
*
* @param {Request} req Incoming HTTP request.
*
* @return {String} The port number.
*
* @api private
*/
common.getPort = function(req) {
var res = req.headers.host ? req.headers.host.match(/:(\d+)/) : '';
return res ?
res[1] :
common.hasEncryptedConnection(req) ? '443' : '80';
};
/**
* Check if the request has an encrypted connection.
*
* @param {Request} req Incoming HTTP request.
*
* @return {Boolean} Whether the connection is encrypted or not.
*
* @api private
*/
common.hasEncryptedConnection = function(req) {
return Boolean(req.connection.encrypted || req.connection.pair);
};
/**
* OS-agnostic join (doesn't break on URLs like path.join does on Windows)>
*
* @return {String} The generated path.
*
* @api private
*/
common.urlJoin = function() {
//
// We do not want to mess with the query string. All we want to touch is the path.
//
var args = Array.prototype.slice.call(arguments),
lastIndex = args.length - 1,
last = args[lastIndex],
lastSegs = last.split('?'),
retSegs;
args[lastIndex] = lastSegs.shift();
//
// Join all strings, but remove empty strings so we don't get extra slashes from
// joining e.g. ['', 'am']
//
retSegs = [
args.filter(Boolean).join('/')
.replace(/\/+/g, '/')
.replace('http:/', 'http://')
.replace('https:/', 'https://')
];
// Only join the query string if it exists so we don't have trailing a '?'
// on every request
// Handle case where there could be multiple ? in the URL.
retSegs.push.apply(retSegs, lastSegs);
return retSegs.join('?')
};
/**
* Rewrites or removes the domain of a cookie header
*
* @param {String|Array} Header
* @param {Object} Config, mapping of domain to rewritten domain.
* '*' key to match any domain, null value to remove the domain.
*
* @api private
*/
common.rewriteCookieProperty = function rewriteCookieProperty(header, config, property) {
if (Array.isArray(header)) {
return header.map(function (headerElement) {
return rewriteCookieProperty(headerElement, config, property);
});
}
return header.replace(new RegExp("(;\\s*" + property + "=)([^;]+)", 'i'), function(match, prefix, previousValue) {
var newValue;
if (previousValue in config) {
newValue = config[previousValue];
} else if ('*' in config) {
newValue = config['*'];
} else {
//no match, return previous value
return match;
}
if (newValue) {
//replace value
return prefix + newValue;
} else {
//remove value
return '';
}
});
};
/**
* Check the host and see if it potentially has a port in it (keep it simple)
*
* @returns {Boolean} Whether we have one or not
*
* @api private
*/
function hasPort(host) {
return !!~host.indexOf(':');
};

185
lib/http-proxy/index.js Normal file
View File

@ -0,0 +1,185 @@
var httpProxy = module.exports,
extend = require('util')._extend,
parse_url = require('url').parse,
EE3 = require('eventemitter3'),
http = require('http'),
https = require('https'),
web = require('./passes/web-incoming'),
ws = require('./passes/ws-incoming');
httpProxy.Server = ProxyServer;
/**
* Returns a function that creates the loader for
* either `ws` or `web`'s passes.
*
* Examples:
*
* httpProxy.createRightProxy('ws')
* // => [Function]
*
* @param {String} Type Either 'ws' or 'web'
* 
* @return {Function} Loader Function that when called returns an iterator for the right passes
*
* @api private
*/
function createRightProxy(type) {
return function(options) {
return function(req, res /*, [head], [opts] */) {
var passes = (type === 'ws') ? this.wsPasses : this.webPasses,
args = [].slice.call(arguments),
cntr = args.length - 1,
head, cbl;
/* optional args parse begin */
if(typeof args[cntr] === 'function') {
cbl = args[cntr];
cntr--;
}
var requestOptions = options;
if(
!(args[cntr] instanceof Buffer) &&
args[cntr] !== res
) {
//Copy global options
requestOptions = extend({}, options);
//Overwrite with request options
extend(requestOptions, args[cntr]);
cntr--;
}
if(args[cntr] instanceof Buffer) {
head = args[cntr];
}
/* optional args parse end */
['target', 'forward'].forEach(function(e) {
if (typeof requestOptions[e] === 'string')
requestOptions[e] = parse_url(requestOptions[e]);
});
if (!requestOptions.target && !requestOptions.forward) {
return this.emit('error', new Error('Must provide a proper URL as target'));
}
for(var i=0; i < passes.length; i++) {
/**
* Call of passes functions
* pass(req, res, options, head)
*
* In WebSockets case the `res` variable
* refer to the connection socket
* pass(req, socket, options, head)
*/
if(passes[i](req, res, requestOptions, head, this, cbl)) { // passes can return a truthy value to halt the loop
break;
}
}
};
};
}
httpProxy.createRightProxy = createRightProxy;
function ProxyServer(options) {
EE3.call(this);
options = options || {};
options.prependPath = options.prependPath === false ? false : true;
this.web = this.proxyRequest = createRightProxy('web')(options);
this.ws = this.proxyWebsocketRequest = createRightProxy('ws')(options);
this.options = options;
this.webPasses = Object.keys(web).map(function(pass) {
return web[pass];
});
this.wsPasses = Object.keys(ws).map(function(pass) {
return ws[pass];
});
this.on('error', this.onError, this);
}
require('util').inherits(ProxyServer, EE3);
ProxyServer.prototype.onError = function (err) {
//
// Remark: Replicate node core behavior using EE3
// so we force people to handle their own errors
//
if(this.listeners('error').length === 1) {
throw err;
}
};
ProxyServer.prototype.listen = function(port, hostname) {
var self = this,
closure = function(req, res) { self.web(req, res); };
this._server = this.options.ssl ?
https.createServer(this.options.ssl, closure) :
http.createServer(closure);
if(this.options.ws) {
this._server.on('upgrade', function(req, socket, head) { self.ws(req, socket, head); });
}
this._server.listen(port, hostname);
return this;
};
ProxyServer.prototype.close = function(callback) {
var self = this;
if (this._server) {
this._server.close(done);
}
// Wrap callback to nullify server after all open connections are closed.
function done() {
self._server = null;
if (callback) {
callback.apply(null, arguments);
}
};
};
ProxyServer.prototype.before = function(type, passName, callback) {
if (type !== 'ws' && type !== 'web') {
throw new Error('type must be `web` or `ws`');
}
var passes = (type === 'ws') ? this.wsPasses : this.webPasses,
i = false;
passes.forEach(function(v, idx) {
if(v.name === passName) i = idx;
})
if(i === false) throw new Error('No such pass');
passes.splice(i, 0, callback);
};
ProxyServer.prototype.after = function(type, passName, callback) {
if (type !== 'ws' && type !== 'web') {
throw new Error('type must be `web` or `ws`');
}
var passes = (type === 'ws') ? this.wsPasses : this.webPasses,
i = false;
passes.forEach(function(v, idx) {
if(v.name === passName) i = idx;
})
if(i === false) throw new Error('No such pass');
passes.splice(i++, 0, callback);
};

View File

@ -0,0 +1,194 @@
var httpNative = require('http'),
httpsNative = require('https'),
web_o = require('./web-outgoing'),
common = require('../common'),
followRedirects = require('follow-redirects');
web_o = Object.keys(web_o).map(function(pass) {
return web_o[pass];
});
var nativeAgents = { http: httpNative, https: httpsNative };
/*!
* Array of passes.
*
* A `pass` is just a function that is executed on `req, res, options`
* so that you can easily add new checks while still keeping the base
* flexible.
*/
module.exports = {
/**
* Sets `content-length` to '0' if request is of DELETE type.
*
* @param {ClientRequest} Req Request object
* @param {IncomingMessage} Res Response object
* @param {Object} Options Config object passed to the proxy
*
* @api private
*/
deleteLength: function deleteLength(req, res, options) {
if((req.method === 'DELETE' || req.method === 'OPTIONS')
&& !req.headers['content-length']) {
req.headers['content-length'] = '0';
delete req.headers['transfer-encoding'];
}
},
/**
* Sets timeout in request socket if it was specified in options.
*
* @param {ClientRequest} Req Request object
* @param {IncomingMessage} Res Response object
* @param {Object} Options Config object passed to the proxy
*
* @api private
*/
timeout: function timeout(req, res, options) {
if(options.timeout) {
req.socket.setTimeout(options.timeout);
}
},
/**
* Sets `x-forwarded-*` headers if specified in config.
*
* @param {ClientRequest} Req Request object
* @param {IncomingMessage} Res Response object
* @param {Object} Options Config object passed to the proxy
*
* @api private
*/
XHeaders: function XHeaders(req, res, options) {
if(!options.xfwd) return;
var encrypted = req.isSpdy || common.hasEncryptedConnection(req);
var values = {
for : req.connection.remoteAddress || req.socket.remoteAddress,
port : common.getPort(req),
proto: encrypted ? 'https' : 'http'
};
['for', 'port', 'proto'].forEach(function(header) {
req.headers['x-forwarded-' + header] =
(req.headers['x-forwarded-' + header] || '') +
(req.headers['x-forwarded-' + header] ? ',' : '') +
values[header];
});
req.headers['x-forwarded-host'] = req.headers['x-forwarded-host'] || req.headers['host'] || '';
},
/**
* Does the actual proxying. If `forward` is enabled fires up
* a ForwardStream, same happens for ProxyStream. The request
* just dies otherwise.
*
* @param {ClientRequest} Req Request object
* @param {IncomingMessage} Res Response object
* @param {Object} Options Config object passed to the proxy
*
* @api private
*/
stream: function stream(req, res, options, _, server, clb) {
// And we begin!
server.emit('start', req, res, options.target || options.forward);
var agents = options.followRedirects ? followRedirects : nativeAgents;
var http = agents.http;
var https = agents.https;
if(options.forward) {
// If forward enable, so just pipe the request
var forwardReq = (options.forward.protocol === 'https:' ? https : http).request(
common.setupOutgoing(options.ssl || {}, options, req, 'forward')
);
// error handler (e.g. ECONNRESET, ECONNREFUSED)
// Handle errors on incoming request as well as it makes sense to
var forwardError = createErrorHandler(forwardReq, options.forward);
req.on('error', forwardError);
forwardReq.on('error', forwardError);
(options.buffer || req).pipe(forwardReq);
if(!options.target) { return res.end(); }
}
// Request initalization
var proxyReq = (options.target.protocol === 'https:' ? https : http).request(
common.setupOutgoing(options.ssl || {}, options, req)
);
// Enable developers to modify the proxyReq before headers are sent
proxyReq.on('socket', function(socket) {
if(server && !proxyReq.getHeader('expect')) {
server.emit('proxyReq', proxyReq, req, res, options);
}
});
// allow outgoing socket to timeout so that we could
// show an error page at the initial request
if(options.proxyTimeout) {
proxyReq.setTimeout(options.proxyTimeout, function() {
proxyReq.abort();
});
}
// Ensure we abort proxy if request is aborted
req.on('aborted', function () {
proxyReq.abort();
});
// handle errors in proxy and incoming request, just like for forward proxy
var proxyError = createErrorHandler(proxyReq, options.target);
req.on('error', proxyError);
proxyReq.on('error', proxyError);
function createErrorHandler(proxyReq, url) {
return function proxyError(err) {
if (req.socket.destroyed && err.code === 'ECONNRESET') {
server.emit('econnreset', err, req, res, url);
return proxyReq.abort();
}
if (clb) {
clb(err, req, res, url);
} else {
server.emit('error', err, req, res, url);
}
}
}
(options.buffer || req).pipe(proxyReq);
proxyReq.on('response', function(proxyRes) {
if(server) { server.emit('proxyRes', proxyRes, req, res); }
if(!res.headersSent && !options.selfHandleResponse) {
for(var i=0; i < web_o.length; i++) {
if(web_o[i](req, res, proxyRes, options)) { break; }
}
}
if (!res.finished) {
// Allow us to listen when the proxy has completed
proxyRes.on('end', function () {
if (server) server.emit('end', req, res, proxyRes);
});
// We pipe to the response unless its expected to be handled by the user
if (!options.selfHandleResponse) proxyRes.pipe(res);
} else {
if (server) server.emit('end', req, res, proxyRes);
}
});
}
};

View File

@ -0,0 +1,147 @@
var url = require('url'),
common = require('../common');
var redirectRegex = /^201|30(1|2|7|8)$/;
/*!
* Array of passes.
*
* A `pass` is just a function that is executed on `req, res, options`
* so that you can easily add new checks while still keeping the base
* flexible.
*/
module.exports = { // <--
/**
* If is a HTTP 1.0 request, remove chunk headers
*
* @param {ClientRequest} Req Request object
* @param {IncomingMessage} Res Response object
* @param {proxyResponse} Res Response object from the proxy request
*
* @api private
*/
removeChunked: function removeChunked(req, res, proxyRes) {
if (req.httpVersion === '1.0') {
delete proxyRes.headers['transfer-encoding'];
}
},
/**
* If is a HTTP 1.0 request, set the correct connection header
* or if connection header not present, then use `keep-alive`
*
* @param {ClientRequest} Req Request object
* @param {IncomingMessage} Res Response object
* @param {proxyResponse} Res Response object from the proxy request
*
* @api private
*/
setConnection: function setConnection(req, res, proxyRes) {
if (req.httpVersion === '1.0') {
proxyRes.headers.connection = req.headers.connection || 'close';
} else if (req.httpVersion !== '2.0' && !proxyRes.headers.connection) {
proxyRes.headers.connection = req.headers.connection || 'keep-alive';
}
},
setRedirectHostRewrite: function setRedirectHostRewrite(req, res, proxyRes, options) {
if ((options.hostRewrite || options.autoRewrite || options.protocolRewrite)
&& proxyRes.headers['location']
&& redirectRegex.test(proxyRes.statusCode)) {
var target = url.parse(options.target);
var u = url.parse(proxyRes.headers['location']);
// make sure the redirected host matches the target host before rewriting
if (target.host != u.host) {
return;
}
if (options.hostRewrite) {
u.host = options.hostRewrite;
} else if (options.autoRewrite) {
u.host = req.headers['host'];
}
if (options.protocolRewrite) {
u.protocol = options.protocolRewrite;
}
proxyRes.headers['location'] = u.format();
}
},
/**
* Copy headers from proxyResponse to response
* set each header in response object.
*
* @param {ClientRequest} Req Request object
* @param {IncomingMessage} Res Response object
* @param {proxyResponse} Res Response object from the proxy request
* @param {Object} Options options.cookieDomainRewrite: Config to rewrite cookie domain
*
* @api private
*/
writeHeaders: function writeHeaders(req, res, proxyRes, options) {
var rewriteCookieDomainConfig = options.cookieDomainRewrite,
rewriteCookiePathConfig = options.cookiePathRewrite,
preserveHeaderKeyCase = options.preserveHeaderKeyCase,
rawHeaderKeyMap,
setHeader = function(key, header) {
if (header == undefined) return;
if (rewriteCookieDomainConfig && key.toLowerCase() === 'set-cookie') {
header = common.rewriteCookieProperty(header, rewriteCookieDomainConfig, 'domain');
}
if (rewriteCookiePathConfig && key.toLowerCase() === 'set-cookie') {
header = common.rewriteCookieProperty(header, rewriteCookiePathConfig, 'path');
}
res.setHeader(String(key).trim(), header);
};
if (typeof rewriteCookieDomainConfig === 'string') { //also test for ''
rewriteCookieDomainConfig = { '*': rewriteCookieDomainConfig };
}
if (typeof rewriteCookiePathConfig === 'string') { //also test for ''
rewriteCookiePathConfig = { '*': rewriteCookiePathConfig };
}
// message.rawHeaders is added in: v0.11.6
// https://nodejs.org/api/http.html#http_message_rawheaders
if (preserveHeaderKeyCase && proxyRes.rawHeaders != undefined) {
rawHeaderKeyMap = {};
for (var i = 0; i < proxyRes.rawHeaders.length; i += 2) {
var key = proxyRes.rawHeaders[i];
rawHeaderKeyMap[key.toLowerCase()] = key;
}
}
Object.keys(proxyRes.headers).forEach(function(key) {
var header = proxyRes.headers[key];
if (preserveHeaderKeyCase && rawHeaderKeyMap) {
key = rawHeaderKeyMap[key] || key;
}
setHeader(key, header);
});
},
/**
* Set the statusCode from the proxyResponse
*
* @param {ClientRequest} Req Request object
* @param {IncomingMessage} Res Response object
* @param {proxyResponse} Res Response object from the proxy request
*
* @api private
*/
writeStatusCode: function writeStatusCode(req, res, proxyRes) {
// From Node.js docs: response.writeHead(statusCode[, statusMessage][, headers])
if(proxyRes.statusMessage) {
res.statusCode = proxyRes.statusCode;
res.statusMessage = proxyRes.statusMessage;
} else {
res.statusCode = proxyRes.statusCode;
}
}
};

View File

@ -0,0 +1,162 @@
var http = require('http'),
https = require('https'),
common = require('../common');
/*!
* Array of passes.
*
* A `pass` is just a function that is executed on `req, socket, options`
* so that you can easily add new checks while still keeping the base
* flexible.
*/
/*
* Websockets Passes
*
*/
module.exports = {
/**
* WebSocket requests must have the `GET` method and
* the `upgrade:websocket` header
*
* @param {ClientRequest} Req Request object
* @param {Socket} Websocket
*
* @api private
*/
checkMethodAndHeader : function checkMethodAndHeader(req, socket) {
if (req.method !== 'GET' || !req.headers.upgrade) {
socket.destroy();
return true;
}
if (req.headers.upgrade.toLowerCase() !== 'websocket') {
socket.destroy();
return true;
}
},
/**
* Sets `x-forwarded-*` headers if specified in config.
*
* @param {ClientRequest} Req Request object
* @param {Socket} Websocket
* @param {Object} Options Config object passed to the proxy
*
* @api private
*/
XHeaders : function XHeaders(req, socket, options) {
if(!options.xfwd) return;
var values = {
for : req.connection.remoteAddress || req.socket.remoteAddress,
port : common.getPort(req),
proto: common.hasEncryptedConnection(req) ? 'wss' : 'ws'
};
['for', 'port', 'proto'].forEach(function(header) {
req.headers['x-forwarded-' + header] =
(req.headers['x-forwarded-' + header] || '') +
(req.headers['x-forwarded-' + header] ? ',' : '') +
values[header];
});
},
/**
* Does the actual proxying. Make the request and upgrade it
* send the Switching Protocols request and pipe the sockets.
*
* @param {ClientRequest} Req Request object
* @param {Socket} Websocket
* @param {Object} Options Config object passed to the proxy
*
* @api private
*/
stream : function stream(req, socket, options, head, server, clb) {
var createHttpHeader = function(line, headers) {
return Object.keys(headers).reduce(function (head, key) {
var value = headers[key];
if (!Array.isArray(value)) {
head.push(key + ': ' + value);
return head;
}
for (var i = 0; i < value.length; i++) {
head.push(key + ': ' + value[i]);
}
return head;
}, [line])
.join('\r\n') + '\r\n\r\n';
}
common.setupSocket(socket);
if (head && head.length) socket.unshift(head);
var proxyReq = (common.isSSL.test(options.target.protocol) ? https : http).request(
common.setupOutgoing(options.ssl || {}, options, req)
);
// Enable developers to modify the proxyReq before headers are sent
if (server) { server.emit('proxyReqWs', proxyReq, req, socket, options, head); }
// Error Handler
proxyReq.on('error', onOutgoingError);
proxyReq.on('response', function (res) {
// if upgrade event isn't going to happen, close the socket
if (!res.upgrade) {
socket.write(createHttpHeader('HTTP/' + res.httpVersion + ' ' + res.statusCode + ' ' + res.statusMessage, res.headers));
res.pipe(socket);
}
});
proxyReq.on('upgrade', function(proxyRes, proxySocket, proxyHead) {
proxySocket.on('error', onOutgoingError);
// Allow us to listen when the websocket has completed
proxySocket.on('end', function () {
server.emit('close', proxyRes, proxySocket, proxyHead);
});
// The pipe below will end proxySocket if socket closes cleanly, but not
// if it errors (eg, vanishes from the net and starts returning
// EHOSTUNREACH). We need to do that explicitly.
socket.on('error', function () {
proxySocket.end();
});
common.setupSocket(proxySocket);
if (proxyHead && proxyHead.length) proxySocket.unshift(proxyHead);
//
// Remark: Handle writing the headers to the socket when switching protocols
// Also handles when a header is an array
//
socket.write(createHttpHeader('HTTP/1.1 101 Switching Protocols', proxyRes.headers));
proxySocket.pipe(socket).pipe(proxySocket);
server.emit('open', proxySocket);
server.emit('proxySocket', proxySocket); //DEPRECATED.
});
return proxyReq.end(); // XXX: CHECK IF THIS IS THIS CORRECT
function onOutgoingError(err) {
if (clb) {
clb(err, req, socket);
} else {
server.emit('error', err, req, socket);
}
socket.end();
}
}
};

View File

@ -1,139 +0,0 @@
/*
node-http-proxy.js: http proxy for node.js with pooling and event buffering
Copyright (c) 2010 Mikeal Rogers, Charlie Robbins
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.
*/
var sys = require('sys'),
http = require('http'),
pool = require('pool'),
url = require('url'),
events = require('events'),
min = 0,
max = 100;
// Setup the PoolManager
var manager = pool.createPoolManager();
manager.setMinClients(min);
manager.setMaxClients(max);
exports.createServer = function () {
var args, action, port, host;
args = Array.prototype.slice.call(arguments);
action = typeof args[args.length - 1] === 'function' && args.pop();
if (args[0]) port = args[0];
if (args[1]) host = args[1];
var proxy = createProxy();
proxy.on('route', function (req, res, callback) {
var uri = url.parse(req.url);
if (action) {
action(req, res, callback);
}
else {
port = port ? port : uri.port ? uri.port : 80;
host = host ? host : uri.hostname;
callback(port, host);
}
});
return proxy;
};
exports.setMin = function (value) {
min = value;
manager.setMinClients(min);
};
exports.setMax = function (value) {
max = value;
manager.setMaxClients(max);
}
var createProxy = function () {
var server = http.createServer(function (req, res) {
var buffers = [],
b = function (chunk) { buffers.push(chunk) },
e = function () { e = false };
req.on('data', b);
req.on('end', e);
server.emit('route', req, res, function (port, hostname) {
var p = manager.getPool(port, hostname);
p.request(req.method, req.url, req.headers, function (reverse_proxy) {
var data = '';
reverse_proxy.on('error', function (err) {
res.writeHead(500, {'Content-Type': 'text/plain'});
if(req.method !== 'HEAD') {
res.write('An error has occurred: ' + sys.puts(JSON.stringify(err)));
}
res.end();
});
buffers.forEach(function (c) {
data += c;
reverse_proxy.write(c);
});
buffers = null;
req.removeListener('data', b);
sys.pump(req, reverse_proxy);
if (e) {
req.removeListener('end', e);
req.addListener('end', function () { reverse_proxy.end() });
}
else {
reverse_proxy.end();
}
// Add a listener for the reverse_proxy response event
reverse_proxy.addListener('response', function (response) {
if (response.headers.connection) {
if (req.headers.connection) response.headers.connection = req.headers.connection;
else response.headers.connection = 'close';
}
// These two listeners are for testability and observation
// of what's passed back from the target server
response.addListener('data', function (chunk) {
data += chunk;
});
response.addListener('end', function() {
server.emit('proxy', null, data);
});
// Set the response headers of the client response
res.writeHead(response.statusCode, response.headers);
sys.pump(response, res);
});
});
});
})
return server;
};

2028
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,41 @@
{
"name": "http-proxy",
"description": "A full-featured http reverse proxy for node.js",
"version": "0.2.0",
"author": "Charlie Robbins <charlie.robbins@gmail.com>",
"contributors": [
{ "name": "Mikeal Rogers", "email": "mikeal.rogers@gmail.com" },
{ "name": "Marak Squires", "email": "marak.squires@gmail.com" },
],
"version": "1.18.1",
"repository": {
"type": "git",
"url": "http://github.com/nodejitsu/node-http-proxy.git"
"type": "git",
"url": "https://github.com/http-party/node-http-proxy.git"
},
"keywords": ["reverse", "proxy", "http"],
"description": "HTTP proxying for the masses",
"author": "Charlie Robbins <charlie.robbins@gmail.com>",
"maintainers": [
"jcrugzz <jcrugzz@gmail.com>"
],
"main": "index.js",
"dependencies": {
"colors": ">= 0.3.0",
"pool": ">= 0.4.1"
"eventemitter3": "^4.0.0",
"requires-port": "^1.0.0",
"follow-redirects": "^1.0.0"
},
"main": "./lib/node-http-proxy",
"scripts": { "test": "vows" },
"engines": { "node": ">= 0.2.0" }
}
"devDependencies": {
"async": "^3.0.0",
"auto-changelog": "^1.15.0",
"concat-stream": "^2.0.0",
"expect.js": "~0.3.1",
"mocha": "^3.5.3",
"nyc": "^14.0.0",
"semver": "^5.0.3",
"socket.io": "^2.1.0",
"socket.io-client": "^2.1.0",
"sse": "0.0.8",
"ws": "^3.0.0"
},
"scripts": {
"mocha": "mocha test/*-test.js",
"test": "nyc --reporter=text --reporter=lcov npm run mocha",
"version": "auto-changelog -p && git add CHANGELOG.md"
},
"engines": {
"node": ">=8.0.0"
},
"license": "MIT"
}

19
renovate.json Normal file
View File

@ -0,0 +1,19 @@
{
"platform": "github",
"autodiscover": false,
"requireConfig": true,
"ignoreNpmrcFile": true,
"rangeStrategy": "replace",
"packageRules": [
{
"packagePatterns": [
"*"
],
"minor": {
"groupName": "all non-major dependencies",
"groupSlug": "all-minor-patch"
}
}
],
"commitMessagePrefix": "[dist]"
}

71
test/examples-test.js Normal file
View File

@ -0,0 +1,71 @@
/*
examples-test.js: Test to run all the examples
Copyright (c) 2013 - 2016 Charlie Robbins, Jarrett Cruger & the Contributors.
*/
var path = require('path'),
fs = require('fs'),
spawn = require('child_process').spawn,
expect = require('expect.js'),
async = require('async');
var rootDir = path.join(__dirname, '..'),
examplesDir = path.join(rootDir, 'examples');
describe.skip('http-proxy examples', function () {
describe('Before testing examples', function () {
// Set a timeout to avoid this error
this.timeout(30 * 1000);
it('should have installed dependencies', function (done) {
async.waterfall([
//
// 1. Read files in examples dir
//
async.apply(fs.readdir, examplesDir),
//
// 2. If node_modules exists, continue. Otherwise
// exec `npm` to install them
//
function checkNodeModules(files, next) {
if (files.indexOf('node_modules') !== -1) {
return next();
}
console.log('Warning: installing dependencies, this operation could take a while');
var child = spawn('npm', ['install', '-f'], {
cwd: examplesDir
});
child.on('exit', function (code) {
return code
? next(new Error('npm install exited with non-zero exit code'))
: next();
});
},
//
// 3. Read files in examples dir again to ensure the install
// worked as expected.
//
async.apply(fs.readdir, examplesDir),
], done);
})
});
describe('Requiring all the examples', function () {
it('should have no errors', function (done) {
async.each(['balancer', 'http', 'middleware', 'websocket'], function (dir, cb) {
var name = 'examples/' + dir,
files = fs.readdirSync(path.join(rootDir, 'examples', dir));
async.each(files, function (file, callback) {
var example;
expect(function () { example = require(path.join(examplesDir, dir, file)); }).to.not.throwException();
expect(example).to.be.an('object');
callback();
}, cb);
}, done);
})
})
})

25
test/fixtures/agent2-cert.pem vendored Normal file
View File

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEIDCCAggCCQChRDh/XiBF+zANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJ1
czETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEeMBwGA1UE
AwwVRHVtbXkgSW50ZXJtZWRpYXRlIENBMB4XDTE4MDYyMjIwMzEwNFoXDTMyMDIy
OTIwMzEwNFowUDELMAkGA1UEBhMCdXMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAO
BgNVBAcMB1NlYXR0bGUxGjAYBgNVBAMMEWR1bW15LmV4YW1wbGUuY29tMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvSQq3d8AeZMTvtqZ13jWCckikyXJ
SACvkGCQUCJqOceESbg6IHdRzQdoccE4P3sbvNsf9BlbdJKM+neCxabqKaU1PPje
4P0tHT57t6yJrMuUh9NxEz3Bgh1srNHVS7saKvwHmcKm79jc+wxlioPmEQvQagjn
y7oTkyLt0sn4LGxBjrcv2JoHOC9f1pxX7l47MaiN0/ctRau7Nr3PFn+pkB4Yf6Z0
VyicVJbaUSz39Qo4HQWl1L2hiBP3CS1oKs2Yk0O1aOCMExWrhZQan+ZgHqL1rhgm
kPpw2/zwwPt5Vf9CSakvHwg198EXuTTXtkzYduuIJAm8yp969iEIiG2xTwIDAQAB
MA0GCSqGSIb3DQEBCwUAA4ICAQBnMSIo+kujkeXPh+iErFBmNtu/7EA+i/QnFPbN
lSLngclYYBJAGQI+DhirJI8ghDi6vmlHB2THewDaOJXEKvC1czE8064wioIcA9HJ
l3QJ3YYOFRctYdSHBU4TWdJbPgkLWDzYP5smjOfw8nDdr4WO/5jh9qRFcFpTFmQf
DyU3xgWLsQnNK3qXLdJjWG75pEhHR+7TGo+Ob/RUho/1RX/P89Ux7/oVbzdKqqFu
SErXAsjEIEFzWOM2uDOt6hrxDF6q+8/zudwQNEo422poEcTT9tDEFxMQ391CzZRi
nozBm4igRn1f5S3YZzLI6VEUns0s76BNy2CzvFWn40DziTqNBExAMfFFj76wiMsX
6fTIdcvkaTBa0S9SZB0vN99qahBdcG17rt4RssMHVRH1Wn7NXMwe476L0yXZ6gO7
Z4uNAPxgaI3BRP75EPfslLutCLZ+BC4Zzu6MY0Salbpfl0Go462EhsKCxvYhE2Dg
T477pICLfETZfA499Fd1tOaIsoLCrILAia/+Yd76uf94MuXUIqykDng/4H7xCc47
BZhNFJiPC6XHaXzN7NYSEUNX9VOwY8ncxKwtP6TXga96PdMUy/p98KIM8RZlDoxB
Xy9dcZBFNn/zrqjW7R0CCWCUriDIFSmEP0wDZ91YYa6BVuJMb5uL/USkTLpjZS4/
HNGvug==
-----END CERTIFICATE-----

27
test/fixtures/agent2-key.pem vendored Normal file
View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAvSQq3d8AeZMTvtqZ13jWCckikyXJSACvkGCQUCJqOceESbg6
IHdRzQdoccE4P3sbvNsf9BlbdJKM+neCxabqKaU1PPje4P0tHT57t6yJrMuUh9Nx
Ez3Bgh1srNHVS7saKvwHmcKm79jc+wxlioPmEQvQagjny7oTkyLt0sn4LGxBjrcv
2JoHOC9f1pxX7l47MaiN0/ctRau7Nr3PFn+pkB4Yf6Z0VyicVJbaUSz39Qo4HQWl
1L2hiBP3CS1oKs2Yk0O1aOCMExWrhZQan+ZgHqL1rhgmkPpw2/zwwPt5Vf9CSakv
Hwg198EXuTTXtkzYduuIJAm8yp969iEIiG2xTwIDAQABAoIBAGPIw/C/qJF7HYyv
6T+7GTiaa2o0IiehbP3/Y8NTFLWc49a8obXlHTvMr7Zr2I/tE+ojtIzkH9K1SjkN
eelqsNj9tsOPDI6oIvftsflpxkxqLtclnt8m0oMhoObf4OaONDT/N8dP4SBiSdsM
ZDmacnMFx5NZVWiup4sVf2CYexx7qks9FhyN2K5PArCQ4S9LHjFhSJVH4DSEpv7E
Ykbp30rhpqV7wSwjgUsm8ZYvI2NOlmffzLSiPdt3vy2K5Q25S/MVEAicg83rfDgK
6EluHjeygRI1xU6DJ0hU7tnU7zE9KURoHPUycO3BKzZnzUH26AA36I58Pu4fXWw/
Cgmbv2ECgYEA+og9E4ziKCEi3p8gqjIfwTRgWZxDLjEzooB/K0UhEearn/xiX29A
FiSzEHKfCB4uSrw5OENg2ckDs8uy08Qmxx7xFXL7AtufAl5fIYaWa0sNSqCaIk7p
ebbUmPcaYhKiLzIEd1EYEL38sXVZ62wvSVMRSWvEMq44g1qnoRlDa/8CgYEAwUTt
talYNwVmR9ZdkVEWm9ZxirdzoM6NaM6u4Tf34ygptpapdmIFSUhfq4iOiEnRGNg/
tuNqhNCIb3LNpJbhRPEzqN7E7qiF/mp7AcJgbuxLZBm12QuLuJdG3nrisKPFXcY1
lA4A7CFmNgH3E4THFfgwzyDXsBOxVLXleTqn+rECgYEA9up1P6J3dtOJuV2d5P/3
ugRz/X173LfTSxJXw36jZDAy8D/feG19/RT4gnplcKvGNhQiVOhbOOnbw0U8n2fQ
TCmbs+cZqyxnH/+AxNsPvvk+RVHZ93xMsY/XIldP4l65B8jFDA+Zp06IESI2mEeM
pzi+bd1Phh+dRSCA2865W2MCgYEAlxYsgmQ1WyX0dFpHYU+zzfXRYzDQyrhOYc2Z
duVK+yCto1iad7pfCY/zgmRJkI+sT7DV9kJIRjXDQuTLkEyHJF8vFGe6KhxCS8aw
DIsI2g4NTd6vg1J8UryoIUqNpqsQoqNNxUVBQVdG0ReuMGsPO8R/W50AIFz0txVP
o/rP0LECgYEA7e/mOwCnR+ovmS/CAksmos3oIqvkRkXNKpKe513FVmp3TpTU38ex
cBkFNU3hEO31FyrX1hGIKp3N5mHYSQ1lyODHM6teHW0OLWWTwIe8rIGvR2jfRLe0
bbkdj40atYVkfeFmpz9uHHG24CUYxJdPc360jbXTVp4i3q8zqgL5aMY=
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,397 @@
var common = require('../lib/http-proxy/common'),
url = require('url'),
expect = require('expect.js');
describe('lib/http-proxy/common.js', function () {
describe('#setupOutgoing', function () {
it('should setup the correct headers', function () {
var outgoing = {};
common.setupOutgoing(outgoing,
{
agent : '?',
target: {
host : 'hey',
hostname : 'how',
socketPath: 'are',
port : 'you',
},
headers: {'fizz': 'bang', 'overwritten':true},
localAddress: 'local.address',
auth:'username:pass'
},
{
method : 'i',
url : 'am',
headers : {'pro':'xy','overwritten':false}
});
expect(outgoing.host).to.eql('hey');
expect(outgoing.hostname).to.eql('how');
expect(outgoing.socketPath).to.eql('are');
expect(outgoing.port).to.eql('you');
expect(outgoing.agent).to.eql('?');
expect(outgoing.method).to.eql('i');
expect(outgoing.path).to.eql('am');
expect(outgoing.headers.pro).to.eql('xy');
expect(outgoing.headers.fizz).to.eql('bang');
expect(outgoing.headers.overwritten).to.eql(true);
expect(outgoing.localAddress).to.eql('local.address');
expect(outgoing.auth).to.eql('username:pass');
});
it('should not override agentless upgrade header', function () {
var outgoing = {};
common.setupOutgoing(outgoing,
{
agent: undefined,
target: {
host : 'hey',
hostname : 'how',
socketPath: 'are',
port : 'you',
},
headers: {'connection': 'upgrade'},
},
{
method : 'i',
url : 'am',
headers : {'pro':'xy','overwritten':false}
});
expect(outgoing.headers.connection).to.eql('upgrade');
});
it('should not override agentless connection: contains upgrade', function () {
var outgoing = {};
common.setupOutgoing(outgoing,
{
agent: undefined,
target: {
host : 'hey',
hostname : 'how',
socketPath: 'are',
port : 'you',
},
headers: {'connection': 'keep-alive, upgrade'}, // this is what Firefox sets
},
{
method : 'i',
url : 'am',
headers : {'pro':'xy','overwritten':false}
});
expect(outgoing.headers.connection).to.eql('keep-alive, upgrade');
});
it('should override agentless connection: contains improper upgrade', function () {
// sanity check on upgrade regex
var outgoing = {};
common.setupOutgoing(outgoing,
{
agent: undefined,
target: {
host : 'hey',
hostname : 'how',
socketPath: 'are',
port : 'you',
},
headers: {'connection': 'keep-alive, not upgrade'},
},
{
method : 'i',
url : 'am',
headers : {'pro':'xy','overwritten':false}
});
expect(outgoing.headers.connection).to.eql('close');
});
it('should override agentless non-upgrade header to close', function () {
var outgoing = {};
common.setupOutgoing(outgoing,
{
agent: undefined,
target: {
host : 'hey',
hostname : 'how',
socketPath: 'are',
port : 'you',
},
headers: {'connection': 'xyz'},
},
{
method : 'i',
url : 'am',
headers : {'pro':'xy','overwritten':false}
});
expect(outgoing.headers.connection).to.eql('close');
});
it('should set the agent to false if none is given', function () {
var outgoing = {};
common.setupOutgoing(outgoing, {target:
'http://localhost'
}, { url: '/' });
expect(outgoing.agent).to.eql(false);
});
it('set the port according to the protocol', function () {
var outgoing = {};
common.setupOutgoing(outgoing,
{
agent : '?',
target: {
host : 'how',
hostname : 'are',
socketPath: 'you',
protocol: 'https:'
}
},
{
method : 'i',
url : 'am',
headers : {pro:'xy'}
});
expect(outgoing.host).to.eql('how');
expect(outgoing.hostname).to.eql('are');
expect(outgoing.socketPath).to.eql('you');
expect(outgoing.agent).to.eql('?');
expect(outgoing.method).to.eql('i');
expect(outgoing.path).to.eql('am');
expect(outgoing.headers.pro).to.eql('xy');
expect(outgoing.port).to.eql(443);
});
it('should keep the original target path in the outgoing path', function(){
var outgoing = {};
common.setupOutgoing(outgoing, {target:
{ path: 'some-path' }
}, { url : 'am' });
expect(outgoing.path).to.eql('some-path/am');
});
it('should keep the original forward path in the outgoing path', function(){
var outgoing = {};
common.setupOutgoing(outgoing, {
target: {},
forward: {
path: 'some-path'
}
}, {
url : 'am'
}, 'forward');
expect(outgoing.path).to.eql('some-path/am');
});
it('should properly detect https/wss protocol without the colon', function () {
var outgoing = {};
common.setupOutgoing(outgoing, {
target: {
protocol: 'https',
host: 'whatever.com'
}
}, { url: '/' });
expect(outgoing.port).to.eql(443);
});
it('should not prepend the target path to the outgoing path with prependPath = false', function () {
var outgoing = {};
common.setupOutgoing(outgoing, {
target: { path: 'hellothere' },
prependPath: false
}, { url: 'hi' });
expect(outgoing.path).to.eql('hi');
})
it('should properly join paths', function () {
var outgoing = {};
common.setupOutgoing(outgoing, {
target: { path: '/forward' },
}, { url: '/static/path' });
expect(outgoing.path).to.eql('/forward/static/path');
})
it('should not modify the query string', function () {
var outgoing = {};
common.setupOutgoing(outgoing, {
target: { path: '/forward' },
}, { url: '/?foo=bar//&target=http://foobar.com/?a=1%26b=2&other=2' });
expect(outgoing.path).to.eql('/forward/?foo=bar//&target=http://foobar.com/?a=1%26b=2&other=2');
})
//
// This is the proper failing test case for the common.join problem
//
it('should correctly format the toProxy URL', function () {
var outgoing = {};
var google = 'https://google.com'
common.setupOutgoing(outgoing, {
target: url.parse('http://sometarget.com:80'),
toProxy: true,
}, { url: google });
expect(outgoing.path).to.eql('/' + google);
});
it('should not replace :\ to :\\ when no https word before', function () {
var outgoing = {};
var google = 'https://google.com:/join/join.js'
common.setupOutgoing(outgoing, {
target: url.parse('http://sometarget.com:80'),
toProxy: true,
}, { url: google });
expect(outgoing.path).to.eql('/' + google);
});
it('should not replace :\ to :\\ when no http word before', function () {
var outgoing = {};
var google = 'http://google.com:/join/join.js'
common.setupOutgoing(outgoing, {
target: url.parse('http://sometarget.com:80'),
toProxy: true,
}, { url: google });
expect(outgoing.path).to.eql('/' + google);
});
describe('when using ignorePath', function () {
it('should ignore the path of the `req.url` passed in but use the target path', function () {
var outgoing = {};
var myEndpoint = 'https://whatever.com/some/crazy/path/whoooo';
common.setupOutgoing(outgoing, {
target: url.parse(myEndpoint),
ignorePath: true
}, { url: '/more/crazy/pathness' });
expect(outgoing.path).to.eql('/some/crazy/path/whoooo');
});
it('and prependPath: false, it should ignore path of target and incoming request', function () {
var outgoing = {};
var myEndpoint = 'https://whatever.com/some/crazy/path/whoooo';
common.setupOutgoing(outgoing, {
target: url.parse(myEndpoint),
ignorePath: true,
prependPath: false
}, { url: '/more/crazy/pathness' });
expect(outgoing.path).to.eql('');
});
});
describe('when using changeOrigin', function () {
it('should correctly set the port to the host when it is a non-standard port using url.parse', function () {
var outgoing = {};
var myEndpoint = 'https://myCouch.com:6984';
common.setupOutgoing(outgoing, {
target: url.parse(myEndpoint),
changeOrigin: true
}, { url: '/' });
expect(outgoing.headers.host).to.eql('mycouch.com:6984');
});
it('should correctly set the port to the host when it is a non-standard port when setting host and port manually (which ignores port)', function () {
var outgoing = {};
common.setupOutgoing(outgoing, {
target: {
protocol: 'https:',
host: 'mycouch.com',
port: 6984
},
changeOrigin: true
}, { url: '/' });
expect(outgoing.headers.host).to.eql('mycouch.com:6984');
})
});
it('should pass through https client parameters', function () {
var outgoing = {};
common.setupOutgoing(outgoing,
{
agent : '?',
target: {
host : 'how',
hostname : 'are',
socketPath: 'you',
protocol: 'https:',
pfx: 'my-pfx',
key: 'my-key',
passphrase: 'my-passphrase',
cert: 'my-cert',
ca: 'my-ca',
ciphers: 'my-ciphers',
secureProtocol: 'my-secure-protocol'
}
},
{
method : 'i',
url : 'am'
});
expect(outgoing.pfx).eql('my-pfx');
expect(outgoing.key).eql('my-key');
expect(outgoing.passphrase).eql('my-passphrase');
expect(outgoing.cert).eql('my-cert');
expect(outgoing.ca).eql('my-ca');
expect(outgoing.ciphers).eql('my-ciphers');
expect(outgoing.secureProtocol).eql('my-secure-protocol');
});
it('should handle overriding the `method` of the http request', function () {
var outgoing = {};
common.setupOutgoing(outgoing, {
target: url.parse('https://whooooo.com'),
method: 'POST' ,
}, { method: 'GET', url: '' });
expect(outgoing.method).eql('POST');
});
// url.parse('').path => null
it('should not pass null as last arg to #urlJoin', function(){
var outgoing = {};
common.setupOutgoing(outgoing, {target:
{ path: '' }
}, { url : '' });
expect(outgoing.path).to.be('');
});
});
describe('#setupSocket', function () {
it('should setup a socket', function () {
var socketConfig = {
timeout: null,
nodelay: false,
keepalive: false
},
stubSocket = {
setTimeout: function (num) {
socketConfig.timeout = num;
},
setNoDelay: function (bol) {
socketConfig.nodelay = bol;
},
setKeepAlive: function (bol) {
socketConfig.keepalive = bol;
}
}
returnValue = common.setupSocket(stubSocket);
expect(socketConfig.timeout).to.eql(0);
expect(socketConfig.nodelay).to.eql(true);
expect(socketConfig.keepalive).to.eql(true);
});
});
});

View File

@ -0,0 +1,536 @@
var webPasses = require('../lib/http-proxy/passes/web-incoming'),
httpProxy = require('../lib/http-proxy'),
expect = require('expect.js'),
concat = require('concat-stream'),
async = require('async'),
url = require('url'),
http = require('http');
describe('lib/http-proxy/passes/web.js', function() {
describe('#deleteLength', function() {
it('should change `content-length` for DELETE requests', function() {
var stubRequest = {
method: 'DELETE',
headers: {}
};
webPasses.deleteLength(stubRequest, {}, {});
expect(stubRequest.headers['content-length']).to.eql('0');
});
it('should change `content-length` for OPTIONS requests', function() {
var stubRequest = {
method: 'OPTIONS',
headers: {}
};
webPasses.deleteLength(stubRequest, {}, {});
expect(stubRequest.headers['content-length']).to.eql('0');
});
it('should remove `transfer-encoding` from empty DELETE requests', function() {
var stubRequest = {
method: 'DELETE',
headers: {
'transfer-encoding': 'chunked'
}
};
webPasses.deleteLength(stubRequest, {}, {});
expect(stubRequest.headers['content-length']).to.eql('0');
expect(stubRequest.headers).to.not.have.key('transfer-encoding');
});
});
describe('#timeout', function() {
it('should set timeout on the socket', function() {
var done = false, stubRequest = {
socket: {
setTimeout: function(value) { done = value; }
}
}
webPasses.timeout(stubRequest, {}, { timeout: 5000});
expect(done).to.eql(5000);
});
});
describe('#XHeaders', function () {
var stubRequest = {
connection: {
remoteAddress: '192.168.1.2',
remotePort: '8080'
},
headers: {
host: '192.168.1.2:8080'
}
}
it('set the correct x-forwarded-* headers', function () {
webPasses.XHeaders(stubRequest, {}, { xfwd: true });
expect(stubRequest.headers['x-forwarded-for']).to.be('192.168.1.2');
expect(stubRequest.headers['x-forwarded-port']).to.be('8080');
expect(stubRequest.headers['x-forwarded-proto']).to.be('http');
});
});
});
describe('#createProxyServer.web() using own http server', function () {
it('should proxy the request using the web proxy handler', function (done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:8080'
});
function requestHandler(req, res) {
proxy.web(req, res);
}
var proxyServer = http.createServer(requestHandler);
var source = http.createServer(function(req, res) {
source.close();
proxyServer.close();
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql('8081');
done();
});
proxyServer.listen('8081');
source.listen('8080');
http.request('http://127.0.0.1:8081', function() {}).end();
});
it('should detect a proxyReq event and modify headers', function (done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:8080',
});
proxy.on('proxyReq', function(proxyReq, req, res, options) {
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
});
function requestHandler(req, res) {
proxy.web(req, res);
}
var proxyServer = http.createServer(requestHandler);
var source = http.createServer(function(req, res) {
source.close();
proxyServer.close();
expect(req.headers['x-special-proxy-header']).to.eql('foobar');
done();
});
proxyServer.listen('8081');
source.listen('8080');
http.request('http://127.0.0.1:8081', function() {}).end();
});
it('should skip proxyReq event when handling a request with header "expect: 100-continue" [https://www.npmjs.com/advisories/1486]', function (done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:8080',
});
proxy.on('proxyReq', function(proxyReq, req, res, options) {
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
});
function requestHandler(req, res) {
proxy.web(req, res);
}
var proxyServer = http.createServer(requestHandler);
var source = http.createServer(function(req, res) {
source.close();
proxyServer.close();
expect(req.headers['x-special-proxy-header']).to.not.eql('foobar');
done();
});
proxyServer.listen('8081');
source.listen('8080');
const postData = ''.padStart(1025, 'x');
const postOptions = {
hostname: '127.0.0.1',
port: 8081,
path: '/',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData),
'expect': '100-continue'
}
};
const req = http.request(postOptions, function() {});
req.write(postData);
req.end();
});
it('should proxy the request and handle error via callback', function(done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:8080'
});
var proxyServer = http.createServer(requestHandler);
function requestHandler(req, res) {
proxy.web(req, res, function (err) {
proxyServer.close();
expect(err).to.be.an(Error);
expect(err.code).to.be('ECONNREFUSED');
done();
});
}
proxyServer.listen('8082');
http.request({
hostname: '127.0.0.1',
port: '8082',
method: 'GET',
}, function() {}).end();
});
it('should proxy the request and handle error via event listener', function(done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:8080'
});
var proxyServer = http.createServer(requestHandler);
function requestHandler(req, res) {
proxy.once('error', function (err, errReq, errRes) {
proxyServer.close();
expect(err).to.be.an(Error);
expect(errReq).to.be.equal(req);
expect(errRes).to.be.equal(res);
expect(err.code).to.be('ECONNREFUSED');
done();
});
proxy.web(req, res);
}
proxyServer.listen('8083');
http.request({
hostname: '127.0.0.1',
port: '8083',
method: 'GET',
}, function() {}).end();
});
it('should forward the request and handle error via event listener', function(done) {
var proxy = httpProxy.createProxyServer({
forward: 'http://127.0.0.1:8080'
});
var proxyServer = http.createServer(requestHandler);
function requestHandler(req, res) {
proxy.once('error', function (err, errReq, errRes) {
proxyServer.close();
expect(err).to.be.an(Error);
expect(errReq).to.be.equal(req);
expect(errRes).to.be.equal(res);
expect(err.code).to.be('ECONNREFUSED');
done();
});
proxy.web(req, res);
}
proxyServer.listen('8083');
http.request({
hostname: '127.0.0.1',
port: '8083',
method: 'GET',
}, function() {}).end();
});
it('should proxy the request and handle timeout error (proxyTimeout)', function(done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:45000',
proxyTimeout: 100
});
require('net').createServer().listen(45000);
var proxyServer = http.createServer(requestHandler);
var started = new Date().getTime();
function requestHandler(req, res) {
proxy.once('error', function (err, errReq, errRes) {
proxyServer.close();
expect(err).to.be.an(Error);
expect(errReq).to.be.equal(req);
expect(errRes).to.be.equal(res);
expect(new Date().getTime() - started).to.be.greaterThan(99);
expect(err.code).to.be('ECONNRESET');
done();
});
proxy.web(req, res);
}
proxyServer.listen('8084');
http.request({
hostname: '127.0.0.1',
port: '8084',
method: 'GET',
}, function() {}).end();
});
it('should proxy the request and handle timeout error', function(done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:45001',
timeout: 100
});
require('net').createServer().listen(45001);
var proxyServer = http.createServer(requestHandler);
var cnt = 0;
var doneOne = function() {
cnt += 1;
if(cnt === 2) done();
}
var started = new Date().getTime();
function requestHandler(req, res) {
proxy.once('econnreset', function (err, errReq, errRes) {
proxyServer.close();
expect(err).to.be.an(Error);
expect(errReq).to.be.equal(req);
expect(errRes).to.be.equal(res);
expect(err.code).to.be('ECONNRESET');
doneOne();
});
proxy.web(req, res);
}
proxyServer.listen('8085');
var req = http.request({
hostname: '127.0.0.1',
port: '8085',
method: 'GET',
}, function() {});
req.on('error', function(err) {
expect(err).to.be.an(Error);
expect(err.code).to.be('ECONNRESET');
expect(new Date().getTime() - started).to.be.greaterThan(99);
doneOne();
});
req.end();
});
it('should proxy the request and provide a proxyRes event with the request and response parameters', function(done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:8080'
});
function requestHandler(req, res) {
proxy.once('proxyRes', function (proxyRes, pReq, pRes) {
source.close();
proxyServer.close();
expect(pReq).to.be.equal(req);
expect(pRes).to.be.equal(res);
done();
});
proxy.web(req, res);
}
var proxyServer = http.createServer(requestHandler);
var source = http.createServer(function(req, res) {
res.end('Response');
});
proxyServer.listen('8086');
source.listen('8080');
http.request('http://127.0.0.1:8086', function() {}).end();
});
it('should proxy the request and provide and respond to manual user response when using modifyResponse', function(done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:8080',
selfHandleResponse: true
});
function requestHandler(req, res) {
proxy.once('proxyRes', function (proxyRes, pReq, pRes) {
proxyRes.pipe(concat(function (body) {
expect(body.toString('utf8')).eql('Response');
pRes.end(Buffer.from('my-custom-response'));
}))
});
proxy.web(req, res);
}
var proxyServer = http.createServer(requestHandler);
var source = http.createServer(function(req, res) {
res.end('Response');
});
async.parallel([
next => proxyServer.listen(8086, next),
next => source.listen(8080, next)
], function (err) {
http.get('http://127.0.0.1:8086', function(res) {
res.pipe(concat(function(body) {
expect(body.toString('utf8')).eql('my-custom-response');
source.close();
proxyServer.close();
done();
}));
}).once('error', done);
})
});
it('should proxy the request and handle changeOrigin option', function (done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:8080',
changeOrigin: true
});
function requestHandler(req, res) {
proxy.web(req, res);
}
var proxyServer = http.createServer(requestHandler);
var source = http.createServer(function(req, res) {
source.close();
proxyServer.close();
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql('8080');
done();
});
proxyServer.listen('8081');
source.listen('8080');
http.request('http://127.0.0.1:8081', function() {}).end();
});
it('should proxy the request with the Authorization header set', function (done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:8080',
auth: 'user:pass'
});
function requestHandler(req, res) {
proxy.web(req, res);
}
var proxyServer = http.createServer(requestHandler);
var source = http.createServer(function(req, res) {
source.close();
proxyServer.close();
var auth = new Buffer(req.headers.authorization.split(' ')[1], 'base64');
expect(req.method).to.eql('GET');
expect(auth.toString()).to.eql('user:pass');
done();
});
proxyServer.listen('8081');
source.listen('8080');
http.request('http://127.0.0.1:8081', function() {}).end();
});
it('should proxy requests to multiple servers with different options', function (done) {
var proxy = httpProxy.createProxyServer();
// proxies to two servers depending on url, rewriting the url as well
// http://127.0.0.1:8080/s1/ -> http://127.0.0.1:8081/
// http://127.0.0.1:8080/ -> http://127.0.0.1:8082/
function requestHandler(req, res) {
if (req.url.indexOf('/s1/') === 0) {
proxy.web(req, res, {
ignorePath: true,
target: 'http://127.0.0.1:8081' + req.url.substring(3)
});
} else {
proxy.web(req, res, {
target: 'http://127.0.0.1:8082'
});
}
}
var proxyServer = http.createServer(requestHandler);
var source1 = http.createServer(function(req, res) {
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql('8080');
expect(req.url).to.eql('/test1');
});
var source2 = http.createServer(function(req, res) {
source1.close();
source2.close();
proxyServer.close();
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql('8080');
expect(req.url).to.eql('/test2');
done();
});
proxyServer.listen('8080');
source1.listen('8081');
source2.listen('8082');
http.request('http://127.0.0.1:8080/s1/test1', function() {}).end();
http.request('http://127.0.0.1:8080/test2', function() {}).end();
});
});
describe('#followRedirects', function () {
it('should proxy the request follow redirects', function (done) {
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:8080',
followRedirects: true
});
function requestHandler(req, res) {
proxy.web(req, res);
}
var proxyServer = http.createServer(requestHandler);
var source = http.createServer(function(req, res) {
if (url.parse(req.url).pathname === '/redirect') {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
}
res.writeHead(301, { 'Location': '/redirect' });
res.end();
});
proxyServer.listen('8081');
source.listen('8080');
http.request('http://127.0.0.1:8081', function(res) {
source.close();
proxyServer.close();
expect(res.statusCode).to.eql(200);
done();
}).end();
});
});

View File

@ -0,0 +1,423 @@
var httpProxy = require('../lib/http-proxy/passes/web-outgoing'),
expect = require('expect.js');
describe('lib/http-proxy/passes/web-outgoing.js', function () {
describe('#setRedirectHostRewrite', function () {
beforeEach(function() {
this.req = {
headers: {
host: 'ext-auto.com'
}
};
this.proxyRes = {
statusCode: 301,
headers: {
location: 'http://backend.com/'
}
};
this.options = {
target: 'http://backend.com'
};
});
context('rewrites location host with hostRewrite', function() {
beforeEach(function() {
this.options.hostRewrite = 'ext-manual.com';
});
[201, 301, 302, 307, 308].forEach(function(code) {
it('on ' + code, function() {
this.proxyRes.statusCode = code;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://ext-manual.com/');
});
});
it('not on 200', function() {
this.proxyRes.statusCode = 200;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://backend.com/');
});
it('not when hostRewrite is unset', function() {
delete this.options.hostRewrite;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://backend.com/');
});
it('takes precedence over autoRewrite', function() {
this.options.autoRewrite = true;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://ext-manual.com/');
});
it('not when the redirected location does not match target host', function() {
this.proxyRes.statusCode = 302;
this.proxyRes.headers.location = 'http://some-other/';
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://some-other/');
});
it('not when the redirected location does not match target port', function() {
this.proxyRes.statusCode = 302;
this.proxyRes.headers.location = 'http://backend.com:8080/';
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://backend.com:8080/');
});
});
context('rewrites location host with autoRewrite', function() {
beforeEach(function() {
this.options.autoRewrite = true;
});
[201, 301, 302, 307, 308].forEach(function(code) {
it('on ' + code, function() {
this.proxyRes.statusCode = code;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://ext-auto.com/');
});
});
it('not on 200', function() {
this.proxyRes.statusCode = 200;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://backend.com/');
});
it('not when autoRewrite is unset', function() {
delete this.options.autoRewrite;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://backend.com/');
});
it('not when the redirected location does not match target host', function() {
this.proxyRes.statusCode = 302;
this.proxyRes.headers.location = 'http://some-other/';
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://some-other/');
});
it('not when the redirected location does not match target port', function() {
this.proxyRes.statusCode = 302;
this.proxyRes.headers.location = 'http://backend.com:8080/';
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://backend.com:8080/');
});
});
context('rewrites location protocol with protocolRewrite', function() {
beforeEach(function() {
this.options.protocolRewrite = 'https';
});
[201, 301, 302, 307, 308].forEach(function(code) {
it('on ' + code, function() {
this.proxyRes.statusCode = code;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('https://backend.com/');
});
});
it('not on 200', function() {
this.proxyRes.statusCode = 200;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://backend.com/');
});
it('not when protocolRewrite is unset', function() {
delete this.options.protocolRewrite;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://backend.com/');
});
it('works together with hostRewrite', function() {
this.options.hostRewrite = 'ext-manual.com';
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('https://ext-manual.com/');
});
it('works together with autoRewrite', function() {
this.options.autoRewrite = true;
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('https://ext-auto.com/');
});
});
});
describe('#setConnection', function () {
it('set the right connection with 1.0 - `close`', function() {
var proxyRes = { headers: {} };
httpProxy.setConnection({
httpVersion: '1.0',
headers: {
connection: null
}
}, {}, proxyRes);
expect(proxyRes.headers.connection).to.eql('close');
});
it('set the right connection with 1.0 - req.connection', function() {
var proxyRes = { headers: {} };
httpProxy.setConnection({
httpVersion: '1.0',
headers: {
connection: 'hey'
}
}, {}, proxyRes);
expect(proxyRes.headers.connection).to.eql('hey');
});
it('set the right connection - req.connection', function() {
var proxyRes = { headers: {} };
httpProxy.setConnection({
httpVersion: null,
headers: {
connection: 'hola'
}
}, {}, proxyRes);
expect(proxyRes.headers.connection).to.eql('hola');
});
it('set the right connection - `keep-alive`', function() {
var proxyRes = { headers: {} };
httpProxy.setConnection({
httpVersion: null,
headers: {
connection: null
}
}, {}, proxyRes);
expect(proxyRes.headers.connection).to.eql('keep-alive');
});
it('don`t set connection with 2.0 if exist', function() {
var proxyRes = { headers: {} };
httpProxy.setConnection({
httpVersion: '2.0',
headers: {
connection: 'namstey'
}
}, {}, proxyRes);
expect(proxyRes.headers.connection).to.eql(undefined);
});
it('don`t set connection with 2.0 if doesn`t exist', function() {
var proxyRes = { headers: {} };
httpProxy.setConnection({
httpVersion: '2.0',
headers: {}
}, {}, proxyRes);
expect(proxyRes.headers.connection).to.eql(undefined);
})
});
describe('#writeStatusCode', function () {
it('should write status code', function() {
var res = {
writeHead: function(n) {
expect(n).to.eql(200);
}
};
httpProxy.writeStatusCode({}, res, { statusCode: 200 });
});
});
describe('#writeHeaders', function() {
beforeEach(function() {
this.proxyRes = {
headers: {
hey: 'hello',
how: 'are you?',
'set-cookie': [
'hello; domain=my.domain; path=/',
'there; domain=my.domain; path=/'
]
}
};
this.rawProxyRes = {
headers: {
hey: 'hello',
how: 'are you?',
'set-cookie': [
'hello; domain=my.domain; path=/',
'there; domain=my.domain; path=/'
]
},
rawHeaders: [
'Hey', 'hello',
'How', 'are you?',
'Set-Cookie', 'hello; domain=my.domain; path=/',
'Set-Cookie', 'there; domain=my.domain; path=/'
]
};
this.res = {
setHeader: function(k, v) {
// https://nodejs.org/api/http.html#http_message_headers
// Header names are lower-cased
this.headers[k.toLowerCase()] = v;
},
headers: {}
};
});
it('writes headers', function() {
var options = {};
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
expect(this.res.headers.hey).to.eql('hello');
expect(this.res.headers.how).to.eql('are you?');
expect(this.res.headers).to.have.key('set-cookie');
expect(this.res.headers['set-cookie']).to.be.an(Array);
expect(this.res.headers['set-cookie']).to.have.length(2);
});
it('writes raw headers', function() {
var options = {};
httpProxy.writeHeaders({}, this.res, this.rawProxyRes, options);
expect(this.res.headers.hey).to.eql('hello');
expect(this.res.headers.how).to.eql('are you?');
expect(this.res.headers).to.have.key('set-cookie');
expect(this.res.headers['set-cookie']).to.be.an(Array);
expect(this.res.headers['set-cookie']).to.have.length(2);
});
it('rewrites path', function() {
var options = {
cookiePathRewrite: '/dummyPath'
};
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
expect(this.res.headers['set-cookie'])
.to.contain('hello; domain=my.domain; path=/dummyPath');
});
it('does not rewrite path', function() {
var options = {};
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
expect(this.res.headers['set-cookie'])
.to.contain('hello; domain=my.domain; path=/');
});
it('removes path', function() {
var options = {
cookiePathRewrite: ''
};
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
expect(this.res.headers['set-cookie'])
.to.contain('hello; domain=my.domain');
});
it('does not rewrite domain', function() {
var options = {};
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
expect(this.res.headers['set-cookie'])
.to.contain('hello; domain=my.domain; path=/');
});
it('rewrites domain', function() {
var options = {
cookieDomainRewrite: 'my.new.domain'
};
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
expect(this.res.headers['set-cookie'])
.to.contain('hello; domain=my.new.domain; path=/');
});
it('removes domain', function() {
var options = {
cookieDomainRewrite: ''
};
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
expect(this.res.headers['set-cookie'])
.to.contain('hello; path=/');
});
it('rewrites headers with advanced configuration', function() {
var options = {
cookieDomainRewrite: {
'*': '',
'my.old.domain': 'my.new.domain',
'my.special.domain': 'my.special.domain'
}
};
this.proxyRes.headers['set-cookie'] = [
'hello-on-my.domain; domain=my.domain; path=/',
'hello-on-my.old.domain; domain=my.old.domain; path=/',
'hello-on-my.special.domain; domain=my.special.domain; path=/'
];
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
expect(this.res.headers['set-cookie'])
.to.contain('hello-on-my.domain; path=/');
expect(this.res.headers['set-cookie'])
.to.contain('hello-on-my.old.domain; domain=my.new.domain; path=/');
expect(this.res.headers['set-cookie'])
.to.contain('hello-on-my.special.domain; domain=my.special.domain; path=/');
});
it('rewrites raw headers with advanced configuration', function() {
var options = {
cookieDomainRewrite: {
'*': '',
'my.old.domain': 'my.new.domain',
'my.special.domain': 'my.special.domain'
}
};
this.rawProxyRes.headers['set-cookie'] = [
'hello-on-my.domain; domain=my.domain; path=/',
'hello-on-my.old.domain; domain=my.old.domain; path=/',
'hello-on-my.special.domain; domain=my.special.domain; path=/'
];
this.rawProxyRes.rawHeaders = this.rawProxyRes.rawHeaders.concat([
'Set-Cookie',
'hello-on-my.domain; domain=my.domain; path=/',
'Set-Cookie',
'hello-on-my.old.domain; domain=my.old.domain; path=/',
'Set-Cookie',
'hello-on-my.special.domain; domain=my.special.domain; path=/'
]);
httpProxy.writeHeaders({}, this.res, this.rawProxyRes, options);
expect(this.res.headers['set-cookie'])
.to.contain('hello-on-my.domain; path=/');
expect(this.res.headers['set-cookie'])
.to.contain('hello-on-my.old.domain; domain=my.new.domain; path=/');
expect(this.res.headers['set-cookie'])
.to.contain('hello-on-my.special.domain; domain=my.special.domain; path=/');
});
});
describe('#removeChunked', function() {
var proxyRes = {
headers: {
'transfer-encoding': 'hello'
}
};
httpProxy.removeChunked({ httpVersion: '1.0' }, {}, proxyRes);
expect(proxyRes.headers['transfer-encoding']).to.eql(undefined);
});
});

View File

@ -0,0 +1,120 @@
var httpProxy = require('../lib/http-proxy/passes/ws-incoming'),
expect = require('expect.js');
describe('lib/http-proxy/passes/ws-incoming.js', function () {
describe('#checkMethodAndHeader', function () {
it('should drop non-GET connections', function () {
var destroyCalled = false,
stubRequest = {
method: 'DELETE',
headers: {}
},
stubSocket = {
destroy: function () {
// Simulate Socket.destroy() method when call
destroyCalled = true;
}
}
returnValue = httpProxy.checkMethodAndHeader(stubRequest, stubSocket);
expect(returnValue).to.be(true);
expect(destroyCalled).to.be(true);
})
it('should drop connections when no upgrade header', function () {
var destroyCalled = false,
stubRequest = {
method: 'GET',
headers: {}
},
stubSocket = {
destroy: function () {
// Simulate Socket.destroy() method when call
destroyCalled = true;
}
}
returnValue = httpProxy.checkMethodAndHeader(stubRequest, stubSocket);
expect(returnValue).to.be(true);
expect(destroyCalled).to.be(true);
})
it('should drop connections when upgrade header is different of `websocket`', function () {
var destroyCalled = false,
stubRequest = {
method: 'GET',
headers: {
upgrade: 'anotherprotocol'
}
},
stubSocket = {
destroy: function () {
// Simulate Socket.destroy() method when call
destroyCalled = true;
}
}
returnValue = httpProxy.checkMethodAndHeader(stubRequest, stubSocket);
expect(returnValue).to.be(true);
expect(destroyCalled).to.be(true);
})
it('should return nothing when all is ok', function () {
var destroyCalled = false,
stubRequest = {
method: 'GET',
headers: {
upgrade: 'websocket'
}
},
stubSocket = {
destroy: function () {
// Simulate Socket.destroy() method when call
destroyCalled = true;
}
}
returnValue = httpProxy.checkMethodAndHeader(stubRequest, stubSocket);
expect(returnValue).to.be(undefined);
expect(destroyCalled).to.be(false);
})
});
describe('#XHeaders', function () {
it('return if no forward request', function () {
var returnValue = httpProxy.XHeaders({}, {}, {});
expect(returnValue).to.be(undefined);
});
it('set the correct x-forwarded-* headers from req.connection', function () {
var stubRequest = {
connection: {
remoteAddress: '192.168.1.2',
remotePort: '8080'
},
headers: {
host: '192.168.1.2:8080'
}
}
httpProxy.XHeaders(stubRequest, {}, { xfwd: true });
expect(stubRequest.headers['x-forwarded-for']).to.be('192.168.1.2');
expect(stubRequest.headers['x-forwarded-port']).to.be('8080');
expect(stubRequest.headers['x-forwarded-proto']).to.be('ws');
});
it('set the correct x-forwarded-* headers from req.socket', function () {
var stubRequest = {
socket: {
remoteAddress: '192.168.1.3',
remotePort: '8181'
},
connection: {
pair: true
},
headers: {
host: '192.168.1.3:8181'
}
};
httpProxy.XHeaders(stubRequest, {}, { xfwd: true });
expect(stubRequest.headers['x-forwarded-for']).to.be('192.168.1.3');
expect(stubRequest.headers['x-forwarded-port']).to.be('8181');
expect(stubRequest.headers['x-forwarded-proto']).to.be('wss');
});
});
});

639
test/lib-http-proxy-test.js Normal file
View File

@ -0,0 +1,639 @@
var httpProxy = require('../lib/http-proxy'),
expect = require('expect.js'),
http = require('http'),
net = require('net'),
ws = require('ws'),
io = require('socket.io'),
SSE = require('sse'),
ioClient = require('socket.io-client');
//
// Expose a port number generator.
// thanks to @3rd-Eden
//
var initialPort = 1024, gen = {};
Object.defineProperty(gen, 'port', {
get: function get() {
return initialPort++;
}
});
describe('lib/http-proxy.js', function() {
describe('#createProxyServer', function() {
it.skip('should throw without options', function() {
var error;
try {
httpProxy.createProxyServer();
} catch(e) {
error = e;
}
expect(error).to.be.an(Error);
})
it('should return an object otherwise', function() {
var obj = httpProxy.createProxyServer({
target: 'http://www.google.com:80'
});
expect(obj.web).to.be.a(Function);
expect(obj.ws).to.be.a(Function);
expect(obj.listen).to.be.a(Function);
});
});
describe('#createProxyServer with forward options and using web-incoming passes', function () {
it('should pipe the request using web-incoming#stream method', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
forward: 'http://127.0.0.1:' + ports.source
}).listen(ports.proxy);
var source = http.createServer(function(req, res) {
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql(ports.proxy);
source.close();
proxy.close();
done();
});
source.listen(ports.source);
http.request('http://127.0.0.1:' + ports.proxy, function() {}).end();
})
});
describe('#createProxyServer using the web-incoming passes', function () {
it('should proxy sse', function(done){
var ports = { source: gen.port, proxy: gen.port },
proxy = httpProxy.createProxyServer({
target: 'http://localhost:' + ports.source,
}),
proxyServer = proxy.listen(ports.proxy),
source = http.createServer(),
sse = new SSE(source, {path: '/'});
sse.on('connection', function(client) {
client.send('Hello over SSE');
client.close();
});
source.listen(ports.source);
var options = {
hostname: 'localhost',
port: ports.proxy,
};
var req = http.request(options, function(res) {
var streamData = '';
res.on('data', function (chunk) {
streamData += chunk.toString('utf8');
});
res.on('end', function (chunk) {
expect(streamData).to.equal(':ok\n\ndata: Hello over SSE\n\n');
source.close();
proxy.close();
done();
});
}).end();
});
it('should make the request on pipe and finish it', function(done) {
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:' + ports.source
}).listen(ports.proxy);
var source = http.createServer(function(req, res) {
expect(req.method).to.eql('POST');
expect(req.headers['x-forwarded-for']).to.eql('127.0.0.1');
expect(req.headers.host.split(':')[1]).to.eql(ports.proxy);
source.close();
proxy.close();
done();
});
source.listen(ports.source);
http.request({
hostname: '127.0.0.1',
port: ports.proxy,
method: 'POST',
headers: {
'x-forwarded-for': '127.0.0.1'
}
}, function() {}).end();
});
});
describe('#createProxyServer using the web-incoming passes', function () {
it('should make the request, handle response and finish it', function(done) {
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:' + ports.source,
preserveHeaderKeyCase: true
}).listen(ports.proxy);
var source = http.createServer(function(req, res) {
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql(ports.proxy);
res.writeHead(200, {'Content-Type': 'text/plain'})
res.end('Hello from ' + source.address().port);
});
source.listen(ports.source);
http.request({
hostname: '127.0.0.1',
port: ports.proxy,
method: 'GET'
}, function(res) {
expect(res.statusCode).to.eql(200);
expect(res.headers['content-type']).to.eql('text/plain');
if (res.rawHeaders != undefined) {
expect(res.rawHeaders.indexOf('Content-Type')).not.to.eql(-1);
expect(res.rawHeaders.indexOf('text/plain')).not.to.eql(-1);
}
res.on('data', function (data) {
expect(data.toString()).to.eql('Hello from ' + ports.source);
});
res.on('end', function () {
source.close();
proxy.close();
done();
});
}).end();
});
});
describe('#createProxyServer() method with error response', function () {
it('should make the request and emit the error event', function(done) {
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:' + ports.source
});
proxy.on('error', function (err) {
expect(err).to.be.an(Error);
expect(err.code).to.be('ECONNREFUSED');
proxy.close();
done();
})
proxy.listen(ports.proxy);
http.request({
hostname: '127.0.0.1',
port: ports.proxy,
method: 'GET',
}, function() {}).end();
});
});
describe('#createProxyServer setting the correct timeout value', function () {
it('should hang up the socket at the timeout', function (done) {
this.timeout(30);
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:' + ports.source,
timeout: 3
}).listen(ports.proxy);
proxy.on('error', function (e) {
expect(e).to.be.an(Error);
expect(e.code).to.be.eql('ECONNRESET');
});
var source = http.createServer(function(req, res) {
setTimeout(function () {
res.end('At this point the socket should be closed');
}, 5)
});
source.listen(ports.source);
var testReq = http.request({
hostname: '127.0.0.1',
port: ports.proxy,
method: 'GET',
}, function() {});
testReq.on('error', function (e) {
expect(e).to.be.an(Error);
expect(e.code).to.be.eql('ECONNRESET');
proxy.close();
source.close();
done();
});
testReq.end();
});
});
describe('#createProxyServer with xfwd option', function () {
it('should not throw on empty http host header', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
forward: 'http://127.0.0.1:' + ports.source,
xfwd: true
}).listen(ports.proxy);
var source = http.createServer(function(req, res) {
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql(ports.source);
source.close();
proxy.close();
done();
});
source.listen(ports.source);
var socket = net.connect({port: ports.proxy}, function()
{
socket.write('GET / HTTP/1.0\r\n\r\n');
});
// handle errors
socket.on('error', function()
{
expect.fail('Unexpected socket error');
});
socket.on('data', function(data)
{
socket.end();
});
socket.on('end', function()
{
expect('Socket to finish').to.be.ok();
});
// http.request('http://127.0.0.1:' + ports.proxy, function() {}).end();
})
});
// describe('#createProxyServer using the web-incoming passes', function () {
// it('should emit events correctly', function(done) {
// var proxy = httpProxy.createProxyServer({
// target: 'http://127.0.0.1:8080'
// }),
// proxyServer = proxy.listen('8081'),
// source = http.createServer(function(req, res) {
// expect(req.method).to.eql('GET');
// expect(req.headers.host.split(':')[1]).to.eql('8081');
// res.writeHead(200, {'Content-Type': 'text/plain'})
// res.end('Hello from ' + source.address().port);
// }),
// events = [];
// source.listen('8080');
// proxy.ee.on('http-proxy:**', function (uno, dos, tres) {
// events.push(this.event);
// })
// http.request({
// hostname: '127.0.0.1',
// port: '8081',
// method: 'GET',
// }, function(res) {
// expect(res.statusCode).to.eql(200);
// res.on('data', function (data) {
// expect(data.toString()).to.eql('Hello from 8080');
// });
// res.on('end', function () {
// expect(events).to.contain('http-proxy:outgoing:web:begin');
// expect(events).to.contain('http-proxy:outgoing:web:end');
// source.close();
// proxyServer.close();
// done();
// });
// }).end();
// });
// });
describe('#createProxyServer using the ws-incoming passes', function () {
it('should proxy the websockets stream', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
target: 'ws://127.0.0.1:' + ports.source,
ws: true
}),
proxyServer = proxy.listen(ports.proxy),
destiny = new ws.Server({ port: ports.source }, function () {
var client = new ws('ws://127.0.0.1:' + ports.proxy);
client.on('open', function () {
client.send('hello there');
});
client.on('message', function (msg) {
expect(msg).to.be('Hello over websockets');
client.close();
proxyServer.close();
destiny.close();
done();
});
});
destiny.on('connection', function (socket) {
socket.on('message', function (msg) {
expect(msg).to.be('hello there');
socket.send('Hello over websockets');
});
});
});
it('should emit error on proxy error', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
// note: we don't ever listen on this port
target: 'ws://127.0.0.1:' + ports.source,
ws: true
}),
proxyServer = proxy.listen(ports.proxy),
client = new ws('ws://127.0.0.1:' + ports.proxy);
client.on('open', function () {
client.send('hello there');
});
var count = 0;
function maybe_done () {
count += 1;
if (count === 2) done();
}
client.on('error', function (err) {
expect(err).to.be.an(Error);
expect(err.code).to.be('ECONNRESET');
maybe_done();
});
proxy.on('error', function (err) {
expect(err).to.be.an(Error);
expect(err.code).to.be('ECONNREFUSED');
proxyServer.close();
maybe_done();
});
});
it('should close client socket if upstream is closed before upgrade', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var server = http.createServer();
server.on('upgrade', function (req, socket, head) {
var response = [
'HTTP/1.1 404 Not Found',
'Content-type: text/html',
'',
''
];
socket.write(response.join('\r\n'));
socket.end();
});
server.listen(ports.source);
var proxy = httpProxy.createProxyServer({
// note: we don't ever listen on this port
target: 'ws://127.0.0.1:' + ports.source,
ws: true
}),
proxyServer = proxy.listen(ports.proxy),
client = new ws('ws://127.0.0.1:' + ports.proxy);
client.on('open', function () {
client.send('hello there');
});
client.on('error', function (err) {
expect(err).to.be.an(Error);
proxyServer.close();
done();
});
});
it('should proxy a socket.io stream', function (done) {
var ports = { source: gen.port, proxy: gen.port },
proxy = httpProxy.createProxyServer({
target: 'ws://127.0.0.1:' + ports.source,
ws: true
}),
proxyServer = proxy.listen(ports.proxy),
server = http.createServer(),
destiny = io.listen(server);
function startSocketIo() {
var client = ioClient.connect('ws://127.0.0.1:' + ports.proxy);
client.on('connect', function () {
client.emit('incoming', 'hello there');
});
client.on('outgoing', function (data) {
expect(data).to.be('Hello over websockets');
proxyServer.close();
server.close();
done();
});
}
server.listen(ports.source);
server.on('listening', startSocketIo);
destiny.sockets.on('connection', function (socket) {
socket.on('incoming', function (msg) {
expect(msg).to.be('hello there');
socket.emit('outgoing', 'Hello over websockets');
});
})
});
it('should emit open and close events when socket.io client connects and disconnects', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
target: 'ws://127.0.0.1:' + ports.source,
ws: true
});
var proxyServer = proxy.listen(ports.proxy);
var server = http.createServer();
var destiny = io.listen(server);
function startSocketIo() {
var client = ioClient.connect('ws://127.0.0.1:' + ports.proxy, {rejectUnauthorized: null});
client.on('connect', function () {
client.disconnect();
});
}
var count = 0;
proxyServer.on('open', function() {
count += 1;
});
proxyServer.on('close', function() {
proxyServer.close();
server.close();
destiny.close();
if (count == 1) { done(); }
});
server.listen(ports.source);
server.on('listening', startSocketIo);
});
it('should pass all set-cookie headers to client', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
target: 'ws://127.0.0.1:' + ports.source,
ws: true
}),
proxyServer = proxy.listen(ports.proxy),
destiny = new ws.Server({ port: ports.source }, function () {
var key = new Buffer(Math.random().toString()).toString('base64');
var requestOptions = {
port: ports.proxy,
host: '127.0.0.1',
headers: {
'Connection': 'Upgrade',
'Upgrade': 'websocket',
'Host': 'ws://127.0.0.1',
'Sec-WebSocket-Version': 13,
'Sec-WebSocket-Key': key
}
};
var req = http.request(requestOptions);
req.on('upgrade', function (res, socket, upgradeHead) {
expect(res.headers['set-cookie'].length).to.be(2);
done();
});
req.end();
});
destiny.on('headers', function (headers) {
headers.push('Set-Cookie: test1=test1');
headers.push('Set-Cookie: test2=test2');
});
});
it('should detect a proxyReq event and modify headers', function (done) {
var ports = { source: gen.port, proxy: gen.port },
proxy,
proxyServer,
destiny;
proxy = httpProxy.createProxyServer({
target: 'ws://127.0.0.1:' + ports.source,
ws: true
});
proxy.on('proxyReqWs', function(proxyReq, req, socket, options, head) {
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
});
proxyServer = proxy.listen(ports.proxy);
destiny = new ws.Server({ port: ports.source }, function () {
var client = new ws('ws://127.0.0.1:' + ports.proxy);
client.on('open', function () {
client.send('hello there');
});
client.on('message', function (msg) {
expect(msg).to.be('Hello over websockets');
client.close();
proxyServer.close();
destiny.close();
done();
});
});
destiny.on('connection', function (socket, upgradeReq) {
expect(upgradeReq.headers['x-special-proxy-header']).to.eql('foobar');
socket.on('message', function (msg) {
expect(msg).to.be('hello there');
socket.send('Hello over websockets');
});
});
});
it('should forward frames with single frame payload (including on node 4.x)', function (done) {
var payload = Array(65529).join('0');
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
target: 'ws://127.0.0.1:' + ports.source,
ws: true
}),
proxyServer = proxy.listen(ports.proxy),
destiny = new ws.Server({ port: ports.source }, function () {
var client = new ws('ws://127.0.0.1:' + ports.proxy);
client.on('open', function () {
client.send(payload);
});
client.on('message', function (msg) {
expect(msg).to.be('Hello over websockets');
client.close();
proxyServer.close();
destiny.close();
done();
});
});
destiny.on('connection', function (socket) {
socket.on('message', function (msg) {
expect(msg).to.be(payload);
socket.send('Hello over websockets');
});
});
});
it('should forward continuation frames with big payload (including on node 4.x)', function (done) {
var payload = Array(65530).join('0');
var ports = { source: gen.port, proxy: gen.port };
var proxy = httpProxy.createProxyServer({
target: 'ws://127.0.0.1:' + ports.source,
ws: true
}),
proxyServer = proxy.listen(ports.proxy),
destiny = new ws.Server({ port: ports.source }, function () {
var client = new ws('ws://127.0.0.1:' + ports.proxy);
client.on('open', function () {
client.send(payload);
});
client.on('message', function (msg) {
expect(msg).to.be('Hello over websockets');
client.close();
proxyServer.close();
destiny.close();
done();
});
});
destiny.on('connection', function (socket) {
socket.on('message', function (msg) {
expect(msg).to.be(payload);
socket.send('Hello over websockets');
});
});
});
});
});

View File

@ -0,0 +1,233 @@
var httpProxy = require('../lib/http-proxy'),
semver = require('semver'),
expect = require('expect.js'),
http = require('http')
https = require('https'),
path = require('path'),
fs = require('fs');
//
// Expose a port number generator.
// thanks to @3rd-Eden
//
var initialPort = 1024, gen = {};
Object.defineProperty(gen, 'port', {
get: function get() {
return initialPort++;
}
});
describe('lib/http-proxy.js', function() {
describe('HTTPS #createProxyServer', function() {
describe('HTTPS to HTTP', function () {
it('should proxy the request en send back the response', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var source = http.createServer(function(req, res) {
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql(ports.proxy);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello from ' + ports.source);
});
source.listen(ports.source);
var proxy = httpProxy.createProxyServer({
target: 'http://127.0.0.1:' + ports.source,
ssl: {
key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')),
cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')),
ciphers: 'AES128-GCM-SHA256',
}
}).listen(ports.proxy);
https.request({
host: 'localhost',
port: ports.proxy,
path: '/',
method: 'GET',
rejectUnauthorized: false
}, function(res) {
expect(res.statusCode).to.eql(200);
res.on('data', function (data) {
expect(data.toString()).to.eql('Hello from ' + ports.source);
});
res.on('end', function () {
source.close();
proxy.close();
done();
})
}).end();
})
});
describe('HTTP to HTTPS', function () {
it('should proxy the request en send back the response', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var source = https.createServer({
key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')),
cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')),
ciphers: 'AES128-GCM-SHA256',
}, function (req, res) {
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql(ports.proxy);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello from ' + ports.source);
});
source.listen(ports.source);
var proxy = httpProxy.createProxyServer({
target: 'https://127.0.0.1:' + ports.source,
// Allow to use SSL self signed
secure: false
}).listen(ports.proxy);
http.request({
hostname: '127.0.0.1',
port: ports.proxy,
method: 'GET'
}, function(res) {
expect(res.statusCode).to.eql(200);
res.on('data', function (data) {
expect(data.toString()).to.eql('Hello from ' + ports.source);
});
res.on('end', function () {
source.close();
proxy.close();
done();
});
}).end();
})
})
describe('HTTPS to HTTPS', function () {
it('should proxy the request en send back the response', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var source = https.createServer({
key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')),
cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')),
ciphers: 'AES128-GCM-SHA256',
}, function(req, res) {
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql(ports.proxy);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello from ' + ports.source);
});
source.listen(ports.source);
var proxy = httpProxy.createProxyServer({
target: 'https://127.0.0.1:' + ports.source,
ssl: {
key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')),
cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')),
ciphers: 'AES128-GCM-SHA256',
},
secure: false
}).listen(ports.proxy);
https.request({
host: 'localhost',
port: ports.proxy,
path: '/',
method: 'GET',
rejectUnauthorized: false
}, function(res) {
expect(res.statusCode).to.eql(200);
res.on('data', function (data) {
expect(data.toString()).to.eql('Hello from ' + ports.source);
});
res.on('end', function () {
source.close();
proxy.close();
done();
})
}).end();
})
});
describe('HTTPS not allow SSL self signed', function () {
it('should fail with error', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var source = https.createServer({
key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')),
cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')),
ciphers: 'AES128-GCM-SHA256',
}).listen(ports.source);
var proxy = httpProxy.createProxyServer({
target: 'https://127.0.0.1:' + ports.source,
secure: true
});
proxy.listen(ports.proxy);
proxy.on('error', function (err, req, res) {
expect(err).to.be.an(Error);
if (semver.gt(process.versions.node, '0.12.0')) {
expect(err.toString()).to.be('Error: unable to verify the first certificate')
} else {
expect(err.toString()).to.be('Error: DEPTH_ZERO_SELF_SIGNED_CERT')
}
done();
})
http.request({
hostname: '127.0.0.1',
port: ports.proxy,
method: 'GET'
}).end();
})
})
describe('HTTPS to HTTP using own server', function () {
it('should proxy the request en send back the response', function (done) {
var ports = { source: gen.port, proxy: gen.port };
var source = http.createServer(function(req, res) {
expect(req.method).to.eql('GET');
expect(req.headers.host.split(':')[1]).to.eql(ports.proxy);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello from ' + ports.source);
});
source.listen(ports.source);
var proxy = httpProxy.createServer({
agent: new http.Agent({ maxSockets: 2 })
});
var ownServer = https.createServer({
key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')),
cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')),
ciphers: 'AES128-GCM-SHA256',
}, function (req, res) {
proxy.web(req, res, {
target: 'http://127.0.0.1:' + ports.source
})
}).listen(ports.proxy);
https.request({
host: 'localhost',
port: ports.proxy,
path: '/',
method: 'GET',
rejectUnauthorized: false
}, function(res) {
expect(res.statusCode).to.eql(200);
res.on('data', function (data) {
expect(data.toString()).to.eql('Hello from ' + ports.source);
});
res.on('end', function () {
source.close();
ownServer.close();
done();
})
}).end();
})
})
});
});

View File

@ -1,147 +0,0 @@
/*
node-http-proxy-test.js: http proxy for node.js
Copyright (c) 2010 Charlie Robbins & Marak Squires http://github.com/nodejitsu/node-http-proxy
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.
*/
var vows = require('vows'),
sys = require('sys'),
assert = require('assert'),
http = require('http');
var httpProxy = require('./../lib/node-http-proxy');
var testServers = {};
//
// Creates the reverse proxy server
//
var startProxyServer = function (port, server) {
var proxyServer = httpProxy.createServer(port, server);
proxyServer.listen(8080);
return proxyServer;
};
//
// Creates the reverse proxy server with a specified latency
//
var startLatentProxyServer = function (port, server, latency) {
// Initialize the nodeProxy and start proxying the request
var proxyServer = httpProxy.createServer(function (req, res, proxy) {
setTimeout(function () {
proxy(port, server);
}, latency);
});
proxyServer.listen(8081);
return proxyServer;
};
//
// Creates the 'hellonode' server
//
var startTargetServer = function (port) {
var targetServer = http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('hello world')
res.end();
});
targetServer.listen(port);
return targetServer;
};
//
// The default test bootstrapper with no latency
//
var startTest = function (port) {
var proxyServer = startProxyServer(port, 'localhost'),
targetServer = startTargetServer(port);
testServers.noLatency = [];
testServers.noLatency.push(proxyServer);
testServers.noLatency.push(targetServer);
return proxyServer;
};
//
// The test bootstrapper with some latency
//
var startTestWithLatency = function (port) {
var proxyServer = startLatentProxyServer(port, 'localhost', 2000),
targetServer = startTargetServer(port);
testServers.latency = [];
testServers.latency.push(proxyServer);
testServers.latency.push(targetServer);
return proxyServer;
};
//var proxy = startTest(8082);
//var latent = startTestWithLatency(8083);
vows.describe('node-http-proxy').addBatch({
"A node-http-proxy": {
"when instantiated directly": {
"and an incoming request is proxied to the helloNode server" : {
"with no latency" : {
topic: function () {
var proxyServer = startTest(8082);
proxyServer.on('proxy', this.callback);
var client = http.createClient(8080, 'localhost');
var request = client.request('GET', '/');
request.end();
},
teardown: function () {
},
"it should received 'hello world'": function (err, body) {
assert.equal(body, 'hello world');
testServers.noLatency.forEach(function (server) {
server.close();
});
}
},
"with latency": {
topic: function () {
var proxyServer = startTestWithLatency(8083);
proxyServer.on('proxy', this.callback);
var client = http.createClient(8081, 'localhost');
var request = client.request('GET', '/');
request.end();
},
teardown: function () {
},
"it should receive 'hello world'": function (err, body) {
assert.equal(body, 'hello world');
testServers.latency.forEach(function (server) {
server.close();
});
}
}
}
}
}
}).export(module);