mirror of
https://github.com/http-party/node-http-proxy.git
synced 2025-12-08 20:59:18 +00:00
[dist] Remove out-dated docco docs
This commit is contained in:
parent
36226daa2e
commit
2d75510d82
@ -1,90 +0,0 @@
|
||||
<!DOCTYPE html> <html> <head> <title>balancing-proxy.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To … <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="balancing-proxy.html"> balancing-proxy.html </a> <a class="source" href="node-http-proxy.html"> node-http-proxy.html </a> <a class="source" href="proxy-table.html"> proxy-table.html </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> balancing-proxy.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">¶</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/*</span>
|
||||
<span class="cm"> balancing-proxy.js: Transparent Load-Balancing Optimized HTTP Proxy </span>
|
||||
|
||||
<span class="cm"> Copyright (c) 2011 Charlie Robbins </span>
|
||||
|
||||
<span class="cm"> Permission is hereby granted, free of charge, to any person obtaining</span>
|
||||
<span class="cm"> a copy of this software and associated documentation files (the</span>
|
||||
<span class="cm"> "Software"), to deal in the Software without restriction, including</span>
|
||||
<span class="cm"> without limitation the rights to use, copy, modify, merge, publish,</span>
|
||||
<span class="cm"> distribute, sublicense, and/or sell copies of the Software, and to</span>
|
||||
<span class="cm"> permit persons to whom the Software is furnished to do so, subject to</span>
|
||||
<span class="cm"> the following conditions:</span>
|
||||
|
||||
<span class="cm"> The above copyright notice and this permission notice shall be</span>
|
||||
<span class="cm"> included in all copies or substantial portions of the Software.</span>
|
||||
|
||||
<span class="cm"> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,</span>
|
||||
<span class="cm"> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF</span>
|
||||
<span class="cm"> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND</span>
|
||||
<span class="cm"> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE</span>
|
||||
<span class="cm"> LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION</span>
|
||||
<span class="cm"> OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION</span>
|
||||
<span class="cm"> WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</span>
|
||||
|
||||
<span class="cm">*/</span>
|
||||
|
||||
<span class="kd">var</span> <span class="nx">net</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'net'</span><span class="p">),</span>
|
||||
<span class="nx">HTTPParser</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">binding</span><span class="p">(</span><span class="s1">'http_parser'</span><span class="p">).</span><span class="nx">HTTPParser</span><span class="p">,</span>
|
||||
<span class="nx">streams</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'morestreams'</span><span class="p">);</span>
|
||||
|
||||
<span class="nx">exports</span><span class="p">.</span><span class="nx">createServer</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">),</span>
|
||||
<span class="nx">callback</span> <span class="o">=</span> <span class="k">typeof</span> <span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">===</span> <span class="s1">'function'</span> <span class="o">&&</span> <span class="nx">args</span><span class="p">.</span><span class="nx">shift</span><span class="p">(),</span>
|
||||
<span class="nx">options</span> <span class="o">=</span> <span class="p">{},</span> <span class="nx">port</span><span class="p">,</span> <span class="nx">host</span><span class="p">,</span> <span class="nx">server</span><span class="p">;</span>
|
||||
|
||||
<span class="nx">server</span> <span class="o">=</span> <span class="nx">net</span><span class="p">.</span><span class="nx">createServer</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">socket</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">buffer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">streams</span><span class="p">.</span><span class="nx">BufferedStream</span><span class="p">(),</span>
|
||||
<span class="nx">parser</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">HTTPParser</span><span class="p">(</span><span class="s1">'request'</span><span class="p">);</span>
|
||||
|
||||
<span class="nx">parser</span><span class="p">.</span><span class="nx">onHeaderField</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">len</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">slice</span> <span class="o">=</span> <span class="nx">b</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">,</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">start</span> <span class="o">+</span> <span class="nx">len</span><span class="p">).</span><span class="nx">toLowerCase</span><span class="p">();</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">parser</span><span class="p">.</span><span class="nx">value</span> <span class="o">!=</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">require</span><span class="p">(</span><span class="s1">'eyes'</span><span class="p">).</span><span class="nx">inspect</span><span class="p">(</span><span class="nx">parser</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="nx">parser</span><span class="p">.</span><span class="nx">field</span><span class="p">);</span>
|
||||
<span class="nx">parser</span><span class="p">.</span><span class="nx">field</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
||||
<span class="nx">parser</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">parser</span><span class="p">.</span><span class="nx">field</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">parser</span><span class="p">.</span><span class="nx">field</span> <span class="o">+=</span> <span class="nx">slice</span><span class="p">;</span>
|
||||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
||||
<span class="nx">parser</span><span class="p">.</span><span class="nx">field</span> <span class="o">=</span> <span class="nx">slice</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="nx">parser</span><span class="p">.</span><span class="nx">onHeaderValue</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">len</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">slice</span> <span class="o">=</span> <span class="nx">b</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">,</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">start</span> <span class="o">+</span> <span class="nx">len</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">parser</span><span class="p">.</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">parser</span><span class="p">.</span><span class="nx">value</span> <span class="o">+=</span> <span class="nx">slice</span><span class="p">;</span>
|
||||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
||||
<span class="nx">parser</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">slice</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="nx">parser</span><span class="p">.</span><span class="nx">socket</span> <span class="o">=</span> <span class="nx">socket</span><span class="p">;</span>
|
||||
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">ondata</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">d</span><span class="p">,</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">end</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">ret</span> <span class="o">=</span> <span class="nx">parser</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span><span class="nx">d</span><span class="p">,</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">end</span> <span class="o">-</span> <span class="nx">start</span><span class="p">);</span>
|
||||
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">ret</span><span class="p">);</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">onend</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">ret</span> <span class="o">=</span> <span class="nx">parser</span><span class="p">.</span><span class="nx">finish</span><span class="p">();</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">ret</span> <span class="k">instanceof</span> <span class="nb">Error</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">destroy</span><span class="p">(</span><span class="nx">ret</span><span class="p">);</span>
|
||||
<span class="k">return</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">socket</span><span class="p">.</span><span class="nx">writable</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="s1">'hello world'</span><span class="p">);</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="p">});</span>
|
||||
|
||||
<span class="k">return</span> <span class="nx">server</span><span class="p">;</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
|
||||
194
docs/docco.css
194
docs/docco.css
@ -1,194 +0,0 @@
|
||||
/*--------------------- Layout and Typography ----------------------------*/
|
||||
body {
|
||||
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
color: #252519;
|
||||
margin: 0; padding: 0;
|
||||
}
|
||||
a {
|
||||
color: #261a3b;
|
||||
}
|
||||
a:visited {
|
||||
color: #261a3b;
|
||||
}
|
||||
p {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
h4, h5, h6 {
|
||||
color: #333;
|
||||
margin: 6px 0 6px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
h2, h3 {
|
||||
margin-bottom: 0;
|
||||
color: #000;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 15px;
|
||||
color: #000;
|
||||
}
|
||||
#container {
|
||||
position: relative;
|
||||
}
|
||||
#background {
|
||||
position: fixed;
|
||||
top: 0; left: 525px; right: 0; bottom: 0;
|
||||
background: #f5f5ff;
|
||||
border-left: 1px solid #e5e5ee;
|
||||
z-index: -1;
|
||||
}
|
||||
#jump_to, #jump_page {
|
||||
background: white;
|
||||
-webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
|
||||
-webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
|
||||
font: 10px Arial;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
#jump_to, #jump_wrapper {
|
||||
position: fixed;
|
||||
right: 0; top: 0;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
#jump_wrapper {
|
||||
padding: 0;
|
||||
display: none;
|
||||
}
|
||||
#jump_to:hover #jump_wrapper {
|
||||
display: block;
|
||||
}
|
||||
#jump_page {
|
||||
padding: 5px 0 3px;
|
||||
margin: 0 0 25px 25px;
|
||||
}
|
||||
#jump_page .source {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
text-decoration: none;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
#jump_page .source:hover {
|
||||
background: #f5f5ff;
|
||||
}
|
||||
#jump_page .source:first-child {
|
||||
}
|
||||
table td {
|
||||
border: 0;
|
||||
outline: 0;
|
||||
}
|
||||
td.docs, th.docs {
|
||||
max-width: 450px;
|
||||
min-width: 450px;
|
||||
min-height: 5px;
|
||||
padding: 10px 25px 1px 50px;
|
||||
overflow-x: hidden;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
.docs pre {
|
||||
margin: 15px 0 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
.docs p tt, .docs p code {
|
||||
background: #f8f8ff;
|
||||
border: 1px solid #dedede;
|
||||
font-size: 12px;
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
.pilwrap {
|
||||
position: relative;
|
||||
}
|
||||
.pilcrow {
|
||||
font: 12px Arial;
|
||||
text-decoration: none;
|
||||
color: #454545;
|
||||
position: absolute;
|
||||
top: 3px; left: -20px;
|
||||
padding: 1px 2px;
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
}
|
||||
td.docs:hover .pilcrow {
|
||||
opacity: 1;
|
||||
}
|
||||
td.code, th.code {
|
||||
padding: 14px 15px 16px 25px;
|
||||
width: 100%;
|
||||
vertical-align: top;
|
||||
background: #f5f5ff;
|
||||
border-left: 1px solid #e5e5ee;
|
||||
}
|
||||
pre, tt, code {
|
||||
font-size: 12px; line-height: 18px;
|
||||
font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
|
||||
margin: 0; padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------- Syntax Highlighting -----------------------------*/
|
||||
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
|
||||
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
|
||||
body .hll { background-color: #ffffcc }
|
||||
body .c { color: #408080; font-style: italic } /* Comment */
|
||||
body .err { border: 1px solid #FF0000 } /* Error */
|
||||
body .k { color: #954121 } /* Keyword */
|
||||
body .o { color: #666666 } /* Operator */
|
||||
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||
body .cp { color: #BC7A00 } /* Comment.Preproc */
|
||||
body .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||
body .cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||
body .gd { color: #A00000 } /* Generic.Deleted */
|
||||
body .ge { font-style: italic } /* Generic.Emph */
|
||||
body .gr { color: #FF0000 } /* Generic.Error */
|
||||
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
body .gi { color: #00A000 } /* Generic.Inserted */
|
||||
body .go { color: #808080 } /* Generic.Output */
|
||||
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
body .gs { font-weight: bold } /* Generic.Strong */
|
||||
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
body .gt { color: #0040D0 } /* Generic.Traceback */
|
||||
body .kc { color: #954121 } /* Keyword.Constant */
|
||||
body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
|
||||
body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
|
||||
body .kp { color: #954121 } /* Keyword.Pseudo */
|
||||
body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
|
||||
body .kt { color: #B00040 } /* Keyword.Type */
|
||||
body .m { color: #666666 } /* Literal.Number */
|
||||
body .s { color: #219161 } /* Literal.String */
|
||||
body .na { color: #7D9029 } /* Name.Attribute */
|
||||
body .nb { color: #954121 } /* Name.Builtin */
|
||||
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
body .no { color: #880000 } /* Name.Constant */
|
||||
body .nd { color: #AA22FF } /* Name.Decorator */
|
||||
body .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||
body .nf { color: #0000FF } /* Name.Function */
|
||||
body .nl { color: #A0A000 } /* Name.Label */
|
||||
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
body .nt { color: #954121; font-weight: bold } /* Name.Tag */
|
||||
body .nv { color: #19469D } /* Name.Variable */
|
||||
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
body .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
body .mf { color: #666666 } /* Literal.Number.Float */
|
||||
body .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
body .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
body .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
body .sb { color: #219161 } /* Literal.String.Backtick */
|
||||
body .sc { color: #219161 } /* Literal.String.Char */
|
||||
body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
|
||||
body .s2 { color: #219161 } /* Literal.String.Double */
|
||||
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||
body .sh { color: #219161 } /* Literal.String.Heredoc */
|
||||
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||
body .sx { color: #954121 } /* Literal.String.Other */
|
||||
body .sr { color: #BB6688 } /* Literal.String.Regex */
|
||||
body .s1 { color: #219161 } /* Literal.String.Single */
|
||||
body .ss { color: #19469D } /* Literal.String.Symbol */
|
||||
body .bp { color: #954121 } /* Name.Builtin.Pseudo */
|
||||
body .vc { color: #19469D } /* Name.Variable.Class */
|
||||
body .vg { color: #19469D } /* Name.Variable.Global */
|
||||
body .vi { color: #19469D } /* Name.Variable.Instance */
|
||||
body .il { color: #666666 } /* Literal.Number.Integer.Long */
|
||||
@ -1,591 +0,0 @@
|
||||
<!DOCTYPE html> <html> <head> <title>node-http-proxy.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To … <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="node-http-proxy.html"> node-http-proxy.html </a> <a class="source" href="proxy-table.html"> proxy-table.html </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> node-http-proxy.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">¶</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/*</span>
|
||||
<span class="cm"> node-http-proxy.js: http proxy for node.js</span>
|
||||
|
||||
<span class="cm"> Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Marak Squires, Fedor Indutny </span>
|
||||
|
||||
<span class="cm"> Permission is hereby granted, free of charge, to any person obtaining</span>
|
||||
<span class="cm"> a copy of this software and associated documentation files (the</span>
|
||||
<span class="cm"> "Software"), to deal in the Software without restriction, including</span>
|
||||
<span class="cm"> without limitation the rights to use, copy, modify, merge, publish,</span>
|
||||
<span class="cm"> distribute, sublicense, and/or sell copies of the Software, and to</span>
|
||||
<span class="cm"> permit persons to whom the Software is furnished to do so, subject to</span>
|
||||
<span class="cm"> the following conditions:</span>
|
||||
|
||||
<span class="cm"> The above copyright notice and this permission notice shall be</span>
|
||||
<span class="cm"> included in all copies or substantial portions of the Software.</span>
|
||||
|
||||
<span class="cm"> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,</span>
|
||||
<span class="cm"> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF</span>
|
||||
<span class="cm"> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND</span>
|
||||
<span class="cm"> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE</span>
|
||||
<span class="cm"> LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION</span>
|
||||
<span class="cm"> OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION</span>
|
||||
<span class="cm"> WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</span>
|
||||
|
||||
<span class="cm">*/</span>
|
||||
|
||||
<span class="kd">var</span> <span class="nx">util</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'util'</span><span class="p">),</span>
|
||||
<span class="nx">http</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'http'</span><span class="p">),</span>
|
||||
<span class="nx">https</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'https'</span><span class="p">),</span>
|
||||
<span class="nx">events</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'events'</span><span class="p">),</span>
|
||||
<span class="nx">ProxyTable</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'./proxy-table'</span><span class="p">).</span><span class="nx">ProxyTable</span><span class="p">,</span>
|
||||
<span class="nx">maxSockets</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">¶</a> </div> <h3>Version 0.5.7 // 5/19/2011</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nx">exports</span><span class="p">.</span><span class="nx">version</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">];</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">¶</a> </div> <p>Track our own list of agents internal to <code>node-http-proxy</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">_agents</span> <span class="o">=</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">¶</a> </div> <h3>function _getAgent (host, port, secure)</h3>
|
||||
|
||||
<h4>@host {string} Host of the agent to get</h4>
|
||||
|
||||
<h4>@port {number} Port of the agent to get</h4>
|
||||
|
||||
<h4>@secure {boolean} Value indicating whether or not to use HTTPS</h4>
|
||||
|
||||
<p>Retreives an agent from the <code>http</code> or <code>https</code> module
|
||||
and sets the <code>maxSockets</code> property appropriately.</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">_getAgent</span> <span class="p">(</span><span class="nx">host</span><span class="p">,</span> <span class="nx">port</span><span class="p">,</span> <span class="nx">secure</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">Agent</span><span class="p">,</span> <span class="nx">id</span> <span class="o">=</span> <span class="p">[</span><span class="nx">host</span><span class="p">,</span> <span class="nx">port</span><span class="p">].</span><span class="nx">join</span><span class="p">(</span><span class="s1">':'</span><span class="p">);</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">port</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">port</span> <span class="o">=</span> <span class="nx">secure</span> <span class="o">?</span> <span class="mi">443</span> <span class="o">:</span> <span class="mi">80</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_agents</span><span class="p">[</span><span class="nx">id</span><span class="p">])</span> <span class="p">{</span>
|
||||
<span class="nx">Agent</span> <span class="o">=</span> <span class="nx">secure</span> <span class="o">?</span> <span class="nx">https</span><span class="p">.</span><span class="nx">Agent</span> <span class="o">:</span> <span class="nx">http</span><span class="p">.</span><span class="nx">Agent</span><span class="p">;</span>
|
||||
|
||||
<span class="nx">_agents</span><span class="p">[</span><span class="nx">id</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Agent</span><span class="p">({</span>
|
||||
<span class="nx">host</span><span class="o">:</span> <span class="nx">host</span><span class="p">,</span>
|
||||
<span class="nx">port</span><span class="o">:</span> <span class="nx">port</span><span class="p">,</span>
|
||||
<span class="nx">maxSockets</span><span class="o">:</span> <span class="nx">maxSockets</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">return</span> <span class="nx">_agents</span><span class="p">[</span><span class="nx">id</span><span class="p">];</span>
|
||||
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">¶</a> </div> <h3>function _getProtocol (secure, outgoing)</h3>
|
||||
|
||||
<h4>@secure {Object|boolean} Settings for <code>https</code></h4>
|
||||
|
||||
<h4>@outgoing {Object} Outgoing request options</h4>
|
||||
|
||||
<p>Returns the appropriate protocol based on the settings in
|
||||
<code>secure</code>. If the protocol is <code>https</code> this function will update
|
||||
the options in <code>outgoing</code> as appropriate by adding <code>ca</code>, <code>key</code>,
|
||||
and <code>cert</code> if they exist in <code>secure</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">_getProtocol</span> <span class="p">(</span><span class="nx">secure</span><span class="p">,</span> <span class="nx">outgoing</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">protocol</span> <span class="o">=</span> <span class="nx">secure</span> <span class="o">?</span> <span class="nx">https</span> <span class="o">:</span> <span class="nx">http</span><span class="p">;</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">secure</span> <span class="o">===</span> <span class="s1">'object'</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">outgoing</span> <span class="o">=</span> <span class="nx">outgoing</span> <span class="o">||</span> <span class="p">{};</span>
|
||||
<span class="p">[</span><span class="s1">'ca'</span><span class="p">,</span> <span class="s1">'cert'</span><span class="p">,</span> <span class="s1">'key'</span><span class="p">].</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">prop</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">secure</span><span class="p">[</span><span class="nx">prop</span><span class="p">])</span> <span class="p">{</span>
|
||||
<span class="nx">outgoing</span><span class="p">[</span><span class="nx">prop</span><span class="p">]</span> <span class="o">=</span> <span class="nx">secure</span><span class="p">[</span><span class="nx">prop</span><span class="p">];</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">})</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">return</span> <span class="nx">protocol</span><span class="p">;</span>
|
||||
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">¶</a> </div> <h3>function getMaxSockets ()</h3>
|
||||
|
||||
<p>Returns the maximum number of sockets
|
||||
allowed on <strong>every</strong> outgoing request
|
||||
made by <strong>all</strong> instances of <code>HttpProxy</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">exports</span><span class="p">.</span><span class="nx">getMaxSockets</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nx">maxSockets</span><span class="p">;</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">¶</a> </div> <h3>function setMaxSockets ()</h3>
|
||||
|
||||
<p>Sets the maximum number of sockets
|
||||
allowed on <strong>every</strong> outgoing request
|
||||
made by <strong>all</strong> instances of <code>HttpProxy</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">exports</span><span class="p">.</span><span class="nx">setMaxSockets</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">maxSockets</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">¶</a> </div> <h3>function createServer ([port, host, options, handler])</h3>
|
||||
|
||||
<h4>@port {number} <strong>Optional</strong> Port to use on the proxy target host.</h4>
|
||||
|
||||
<h4>@host {string} <strong>Optional</strong> Host of the proxy target.</h4>
|
||||
|
||||
<h4>@options {Object} <strong>Optional</strong> Options for the HttpProxy instance used</h4>
|
||||
|
||||
<h4>@handler {function} <strong>Optional</strong> Request handler for the server</h4>
|
||||
|
||||
<p>Returns a server that manages an instance of HttpProxy. Flexible arguments allow for:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>httpProxy.createServer(9000, 'localhost')</code></li>
|
||||
<li>`httpProxy.createServer(9000, 'localhost', options)</li>
|
||||
<li><code>httpPRoxy.createServer(function (req, res, proxy) { ... })</code></li>
|
||||
</ul> </td> <td class="code"> <div class="highlight"><pre><span class="nx">exports</span><span class="p">.</span><span class="nx">createServer</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">),</span>
|
||||
<span class="nx">callback</span> <span class="o">=</span> <span class="k">typeof</span> <span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">===</span> <span class="s1">'function'</span> <span class="o">&&</span> <span class="nx">args</span><span class="p">.</span><span class="nx">shift</span><span class="p">(),</span>
|
||||
<span class="nx">options</span> <span class="o">=</span> <span class="p">{},</span> <span class="nx">port</span><span class="p">,</span> <span class="nx">host</span><span class="p">,</span> <span class="nx">forward</span><span class="p">,</span> <span class="nx">silent</span><span class="p">,</span> <span class="nx">proxy</span><span class="p">,</span> <span class="nx">server</span><span class="p">;</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">args</span><span class="p">.</span><span class="nx">length</span> <span class="o">>=</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">port</span> <span class="o">=</span> <span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
|
||||
<span class="nx">host</span> <span class="o">=</span> <span class="nx">args</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
|
||||
<span class="nx">options</span> <span class="o">=</span> <span class="nx">args</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">||</span> <span class="p">{};</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">args</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">options</span> <span class="o">=</span> <span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">||</span> <span class="p">{};</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">router</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">'Cannot create server with no router and no callback'</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="nx">proxy</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">HttpProxy</span><span class="p">(</span><span class="nx">options</span><span class="p">);</span>
|
||||
|
||||
<span class="nx">handler</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">¶</a> </div> <p>If we were passed a callback to process the request
|
||||
or response in some way, then call it.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">callback</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">proxy</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">port</span> <span class="o">&&</span> <span class="nx">host</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">¶</a> </div> <p>If we have a target host and port for the request
|
||||
then proxy to the specified location.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">proxy</span><span class="p">.</span><span class="nx">proxyRequest</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="p">{</span>
|
||||
<span class="nx">port</span><span class="o">:</span> <span class="nx">port</span><span class="p">,</span>
|
||||
<span class="nx">host</span><span class="o">:</span> <span class="nx">host</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">proxy</span><span class="p">.</span><span class="nx">proxyTable</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">¶</a> </div> <p>If the proxy is configured with a ProxyTable
|
||||
instance then use that before failing.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">proxy</span><span class="p">.</span><span class="nx">proxyRequest</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">¶</a> </div> <p>Otherwise this server is improperly configured.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">'Cannot proxy without port, host, or router.'</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="nx">server</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">https</span>
|
||||
<span class="o">?</span> <span class="nx">https</span><span class="p">.</span><span class="nx">createServer</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">https</span><span class="p">,</span> <span class="nx">handler</span><span class="p">)</span>
|
||||
<span class="o">:</span> <span class="nx">http</span><span class="p">.</span><span class="nx">createServer</span><span class="p">(</span><span class="nx">handler</span><span class="p">);</span>
|
||||
|
||||
<span class="nx">server</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'close'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">proxy</span><span class="p">.</span><span class="nx">close</span><span class="p">();</span>
|
||||
<span class="p">});</span>
|
||||
|
||||
<span class="nx">proxy</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'routes'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">routes</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">server</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'routes'</span><span class="p">,</span> <span class="nx">routes</span><span class="p">);</span>
|
||||
<span class="p">});</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">¶</a> </div> <p>WebSocket support: if callback is empty tunnel
|
||||
websocket request automatically</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">server</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'upgrade'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">socket</span><span class="p">,</span> <span class="nx">head</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">¶</a> </div> <p>Tunnel websocket requests too</p> </td> <td class="code"> <div class="highlight"><pre>
|
||||
<span class="nx">proxy</span><span class="p">.</span><span class="nx">proxyWebSocketRequest</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">socket</span><span class="p">,</span> <span class="nx">head</span><span class="p">,</span> <span class="p">{</span>
|
||||
<span class="nx">port</span><span class="o">:</span> <span class="nx">port</span><span class="p">,</span>
|
||||
<span class="nx">host</span><span class="o">:</span> <span class="nx">host</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">¶</a> </div> <p>Set the proxy on the server so it is available
|
||||
to the consumer of the server</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">server</span><span class="p">.</span><span class="nx">proxy</span> <span class="o">=</span> <span class="nx">proxy</span><span class="p">;</span>
|
||||
|
||||
<span class="k">return</span> <span class="nx">server</span><span class="p">;</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">¶</a> </div> <h3>function HttpProxy (options)</h3>
|
||||
|
||||
<h4>@options {Object} Options for this instance.</h4>
|
||||
|
||||
<p>Constructor function for new instances of HttpProxy responsible
|
||||
for managing the life-cycle of streaming reverse proxyied HTTP requests.</p>
|
||||
|
||||
<p>Example options:</p>
|
||||
|
||||
<pre><code> {
|
||||
router: {
|
||||
'foo.com': 'localhost:8080',
|
||||
'bar.com': 'localhost:8081'
|
||||
},
|
||||
forward: {
|
||||
host: 'localhost',
|
||||
port: 9001
|
||||
}
|
||||
}
|
||||
</code></pre> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">HttpProxy</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">HttpProxy</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">events</span><span class="p">.</span><span class="nx">EventEmitter</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
|
||||
|
||||
<span class="kd">var</span> <span class="nx">self</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
|
||||
<span class="nx">options</span> <span class="o">=</span> <span class="nx">options</span> <span class="o">||</span> <span class="p">{};</span>
|
||||
</pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">¶</a> </div> <p>Setup basic proxying options</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">https</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">https</span><span class="p">;</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">forward</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">forward</span><span class="p">;</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">target</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">target</span> <span class="o">||</span> <span class="p">{};</span>
|
||||
</pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">¶</a> </div> <p>Setup additional options for WebSocket proxying. When forcing
|
||||
the WebSocket handshake to change the <code>sec-websocket-location</code>
|
||||
and <code>sec-websocket-origin</code> headers <code>options.source</code> <strong>MUST</strong>
|
||||
be provided or the operation will fail with an <code>origin mismatch</code>
|
||||
by definition.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">source</span> <span class="o">||</span> <span class="p">{</span> <span class="nx">host</span><span class="o">:</span> <span class="s1">'localhost'</span><span class="p">,</span> <span class="nx">port</span><span class="o">:</span> <span class="mi">8000</span> <span class="p">};</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">changeOrigin</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">changeOrigin</span> <span class="o">||</span> <span class="kc">false</span><span class="p">;</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">router</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">proxyTable</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ProxyTable</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">router</span><span class="p">,</span> <span class="nx">options</span><span class="p">.</span><span class="nx">silent</span><span class="p">,</span> <span class="nx">options</span><span class="p">.</span><span class="nx">hostnameOnly</span><span class="p">);</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">proxyTable</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'routes'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">routes</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">self</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'routes'</span><span class="p">,</span> <span class="nx">routes</span><span class="p">);</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">¶</a> </div> <p>Inherit from events.EventEmitter</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">util</span><span class="p">.</span><span class="nx">inherits</span><span class="p">(</span><span class="nx">HttpProxy</span><span class="p">,</span> <span class="nx">events</span><span class="p">.</span><span class="nx">EventEmitter</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">¶</a> </div> <h3>function buffer (obj)</h3>
|
||||
|
||||
<h4>@obj {Object} Object to pause events from</h4>
|
||||
|
||||
<p>Buffer <code>data</code> and <code>end</code> events from the given <code>obj</code>.
|
||||
Consumers of HttpProxy performing async tasks
|
||||
<strong>must</strong> utilize this utility, to re-emit data once
|
||||
the async operation has completed, otherwise these
|
||||
<strong>events will be lost.</strong></p>
|
||||
|
||||
<pre><code> var buffer = httpProxy.buffer(req);
|
||||
fs.readFile(path, function(){
|
||||
httpProxy.proxyRequest(req, res, host, port, buffer);
|
||||
});
|
||||
</code></pre>
|
||||
|
||||
<p><strong>Attribution:</strong> This approach is based heavily on
|
||||
<a href="https://github.com/senchalabs/connect/blob/master/lib/utils.js#L157">Connect</a>.
|
||||
However, this is not a big leap from the implementation in node-http-proxy < 0.4.0.
|
||||
This simply chooses to manage the scope of the events on a new Object literal as opposed to
|
||||
<a href="https://github.com/nodejitsu/node-http-proxy/blob/v0.3.1/lib/node-http-proxy.js#L154">on the HttpProxy instance</a>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">HttpProxy</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">buffer</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">onData</span><span class="p">,</span> <span class="nx">onEnd</span><span class="p">,</span> <span class="nx">events</span> <span class="o">=</span> <span class="p">[];</span>
|
||||
|
||||
<span class="nx">obj</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="nx">onData</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">data</span><span class="p">,</span> <span class="nx">encoding</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">events</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="s1">'data'</span><span class="p">,</span> <span class="nx">data</span><span class="p">,</span> <span class="nx">encoding</span><span class="p">]);</span>
|
||||
<span class="p">});</span>
|
||||
|
||||
<span class="nx">obj</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="nx">onEnd</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">data</span><span class="p">,</span> <span class="nx">encoding</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">events</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="s1">'end'</span><span class="p">,</span> <span class="nx">data</span><span class="p">,</span> <span class="nx">encoding</span><span class="p">]);</span>
|
||||
<span class="p">});</span>
|
||||
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="nx">end</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">obj</span><span class="p">.</span><span class="nx">removeListener</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="nx">onData</span><span class="p">);</span>
|
||||
<span class="nx">obj</span><span class="p">.</span><span class="nx">removeListener</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="nx">onEnd</span><span class="p">);</span>
|
||||
<span class="p">},</span>
|
||||
<span class="nx">resume</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">len</span> <span class="o">=</span> <span class="nx">events</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">len</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">obj</span><span class="p">.</span><span class="nx">emit</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">events</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">¶</a> </div> <h3>function close ()</h3>
|
||||
|
||||
<p>Frees the resources associated with this instance,
|
||||
if they exist. </p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">HttpProxy</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">close</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">proxyTable</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">proxyTable</span><span class="p">.</span><span class="nx">close</span><span class="p">();</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">¶</a> </div> <h3>function proxyRequest (req, res, [port, host, paused])</h3>
|
||||
|
||||
<h4>@req {ServerRequest} Incoming HTTP Request to proxy.</h4>
|
||||
|
||||
<h4>@res {ServerResponse} Outgoing HTTP Request to write proxied data to.</h4>
|
||||
|
||||
<h4>@options {Object} Options for the outgoing proxy request.</h4>
|
||||
|
||||
<pre><code>options.port {number} Port to use on the proxy target host.
|
||||
options.host {string} Host of the proxy target.
|
||||
options.buffer {Object} Result from `httpProxy.buffer(req)`
|
||||
options.https {Object|boolean} Settings for https.
|
||||
</code></pre> </td> <td class="code"> <div class="highlight"><pre><span class="nx">HttpProxy</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">proxyRequest</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">self</span> <span class="o">=</span> <span class="k">this</span><span class="p">,</span> <span class="nx">errState</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">location</span><span class="p">,</span> <span class="nx">outgoing</span><span class="p">,</span> <span class="nx">protocol</span><span class="p">,</span> <span class="nx">reverseProxy</span><span class="p">;</span>
|
||||
</pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">¶</a> </div> <p>Create an empty options hash if none is passed.
|
||||
If default options have been passed to the constructor
|
||||
of this instance, use them by default.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">options</span> <span class="o">=</span> <span class="nx">options</span> <span class="o">||</span> <span class="p">{};</span>
|
||||
<span class="nx">options</span><span class="p">.</span><span class="nx">host</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">host</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">host</span><span class="p">;</span>
|
||||
<span class="nx">options</span><span class="p">.</span><span class="nx">port</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">port</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">port</span><span class="p">;</span>
|
||||
</pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">¶</a> </div> <p>Check the proxy table for this instance to see if we need
|
||||
to get the proxy location for the request supplied. We will
|
||||
always ignore the proxyTable if an explicit <code>port</code> and <code>host</code>
|
||||
arguments are supplied to <code>proxyRequest</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">proxyTable</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">host</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">location</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">proxyTable</span><span class="p">.</span><span class="nx">getProxyLocation</span><span class="p">(</span><span class="nx">req</span><span class="p">);</span>
|
||||
</pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">¶</a> </div> <p>If no location is returned from the ProxyTable instance
|
||||
then respond with <code>404</code> since we do not have a valid proxy target.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">location</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">res</span><span class="p">.</span><span class="nx">writeHead</span><span class="p">(</span><span class="mi">404</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">¶</a> </div> <p>When using the ProxyTable in conjunction with an HttpProxy instance
|
||||
only the following arguments are valid:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>proxy.proxyRequest(req, res, { host: 'localhost' })</code>: This will be skipped</li>
|
||||
<li><code>proxy.proxyRequest(req, res, { buffer: buffer })</code>: Buffer will get updated appropriately</li>
|
||||
<li><code>proxy.proxyRequest(req, res)</code>: Options will be assigned appropriately. </li>
|
||||
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">options</span><span class="p">.</span><span class="nx">port</span> <span class="o">=</span> <span class="nx">location</span><span class="p">.</span><span class="nx">port</span><span class="p">;</span>
|
||||
<span class="nx">options</span><span class="p">.</span><span class="nx">host</span> <span class="o">=</span> <span class="nx">location</span><span class="p">.</span><span class="nx">host</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">¶</a> </div> <p>Add common proxy headers to the request so that they can
|
||||
be availible to the proxy target server:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>x-forwarded-for</code>: IP Address of the original request</li>
|
||||
<li><code>x-forwarded-proto</code>: Protocol of the original request</li>
|
||||
<li><code>x-forwarded-port</code>: Port of the original request. </li>
|
||||
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="s1">'x-forwarded-for'</span><span class="p">]</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">remoteAddress</span> <span class="o">||</span> <span class="nx">req</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">remoteAddress</span><span class="p">;</span>
|
||||
<span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="s1">'x-forwarded-port'</span><span class="p">]</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">remotePort</span> <span class="o">||</span> <span class="nx">req</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">remotePort</span><span class="p">;</span>
|
||||
<span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="s1">'x-forwarded-proto'</span><span class="p">]</span> <span class="o">=</span> <span class="nx">res</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">pair</span> <span class="o">?</span> <span class="s1">'https'</span> <span class="o">:</span> <span class="s1">'http'</span><span class="p">;</span>
|
||||
</pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">¶</a> </div> <p>Emit the <code>start</code> event indicating that we have begun the proxy operation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'start'</span><span class="p">,</span> <span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
|
||||
</pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">¶</a> </div> <p>If forwarding is enabled for this instance, foward proxy the
|
||||
specified request to the address provided in <code>this.forward</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">forward</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'forward'</span><span class="p">,</span> <span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">forward</span><span class="p">);</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">_forwardRequest</span><span class="p">(</span><span class="nx">req</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">¶</a> </div> <h4>function proxyError (err)</h4>
|
||||
|
||||
<h4>@err {Error} Error contacting the proxy target</h4>
|
||||
|
||||
<p>Short-circuits <code>res</code> in the event of any error when
|
||||
contacting the proxy target at <code>host</code> / <code>port</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">proxyError</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">errState</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
|
||||
</pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">¶</a> </div> <p>Emit an <code>error</code> event, allowing the application to use custom
|
||||
error handling. The error handler should end the response.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">self</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'proxyError'</span><span class="p">,</span> <span class="nx">err</span><span class="p">,</span> <span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="k">return</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="nx">res</span><span class="p">.</span><span class="nx">writeHead</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="p">{</span> <span class="s1">'Content-Type'</span><span class="o">:</span> <span class="s1">'text/plain'</span> <span class="p">});</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">method</span> <span class="o">!==</span> <span class="s1">'HEAD'</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">¶</a> </div> <p>This NODE_ENV=production behavior is mimics Express and
|
||||
Connect.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">NODE_ENV</span> <span class="o">===</span> <span class="s1">'production'</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">res</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="s1">'Internal Server Error'</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="p">{</span>
|
||||
<span class="nx">res</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="s1">'An error has occurred: '</span> <span class="o">+</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">err</span><span class="p">));</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="nx">res</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="nx">outgoing</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="nx">host</span><span class="o">:</span> <span class="nx">options</span><span class="p">.</span><span class="nx">host</span><span class="p">,</span>
|
||||
<span class="nx">port</span><span class="o">:</span> <span class="nx">options</span><span class="p">.</span><span class="nx">port</span><span class="p">,</span>
|
||||
<span class="nx">agent</span><span class="o">:</span> <span class="nx">_getAgent</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">host</span><span class="p">,</span> <span class="nx">options</span><span class="p">.</span><span class="nx">port</span><span class="p">,</span> <span class="nx">options</span><span class="p">.</span><span class="nx">https</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">https</span><span class="p">),</span>
|
||||
<span class="nx">method</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">method</span><span class="p">,</span>
|
||||
<span class="nx">path</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span>
|
||||
<span class="nx">headers</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="nx">protocol</span> <span class="o">=</span> <span class="nx">_getProtocol</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">https</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">https</span><span class="p">,</span> <span class="nx">outgoing</span><span class="p">);</span>
|
||||
</pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">¶</a> </div> <p>Open new HTTP request to internal resource with will act as a reverse proxy pass</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">reverseProxy</span> <span class="o">=</span> <span class="nx">protocol</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="nx">outgoing</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
|
||||
</pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">¶</a> </div> <p>Process the <code>reverseProxy</code> <code>response</code> when it's received.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">connection</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">connection</span><span class="p">)</span> <span class="nx">response</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">connection</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">connection</span><span class="p">;</span>
|
||||
<span class="k">else</span> <span class="nx">response</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">connection</span> <span class="o">=</span> <span class="s1">'close'</span><span class="p">;</span>
|
||||
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">¶</a> </div> <p>Set the headers of the client response</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">res</span><span class="p">.</span><span class="nx">writeHead</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">statusCode</span><span class="p">,</span> <span class="nx">response</span><span class="p">.</span><span class="nx">headers</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">¶</a> </div> <p><code>response.statusCode === 304</code>: No 'data' event and no 'end'</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">statusCode</span> <span class="o">===</span> <span class="mi">304</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">¶</a> </div> <p>For each data <code>chunk</code> received from the <code>reverseProxy</code>
|
||||
<code>response</code> write it to the outgoing <code>res</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">response</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">method</span> <span class="o">!==</span> <span class="s1">'HEAD'</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">res</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">chunk</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">¶</a> </div> <p>When the <code>reverseProxy</code> <code>response</code> ends, end the
|
||||
corresponding outgoing <code>res</code> unless we have entered
|
||||
an error state. In which case, assume <code>res.end()</code> has
|
||||
already been called and the 'error' event listener
|
||||
removed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">response</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">errState</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">removeListener</span><span class="p">(</span><span class="s1">'error'</span><span class="p">,</span> <span class="nx">proxyError</span><span class="p">);</span>
|
||||
<span class="nx">res</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
</pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">¶</a> </div> <p>Emit the <code>end</code> event now that we have completed proxying</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">self</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">});</span>
|
||||
</pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">¶</a> </div> <p>Handle 'error' events from the <code>reverseProxy</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">once</span><span class="p">(</span><span class="s1">'error'</span><span class="p">,</span> <span class="nx">proxyError</span><span class="p">);</span>
|
||||
</pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">¶</a> </div> <p>For each data <code>chunk</code> received from the incoming
|
||||
<code>req</code> write it to the <code>reverseProxy</code> request.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">req</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">errState</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">chunk</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">¶</a> </div> <p>When the incoming <code>req</code> ends, end the corresponding <code>reverseProxy</code>
|
||||
request unless we have entered an error state. </p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">req</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">errState</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">¶</a> </div> <p>If we have been passed buffered data, resume it.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">buffer</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">errState</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">options</span><span class="p">.</span><span class="nx">buffer</span><span class="p">.</span><span class="nx">resume</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
</pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">¶</a> </div> <h3>@private function _forwardRequest (req)</h3>
|
||||
|
||||
<h4>@req {ServerRequest} Incoming HTTP Request to proxy.</h4>
|
||||
|
||||
<p>Forwards the specified <code>req</code> to the location specified
|
||||
by <code>this.forward</code> ignoring errors and the subsequent response.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">HttpProxy</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_forwardRequest</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">req</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">self</span> <span class="o">=</span> <span class="k">this</span><span class="p">,</span> <span class="nx">port</span><span class="p">,</span> <span class="nx">host</span><span class="p">,</span> <span class="nx">outgoing</span><span class="p">,</span> <span class="nx">protocol</span><span class="p">,</span> <span class="nx">forwardProxy</span><span class="p">;</span>
|
||||
|
||||
<span class="nx">port</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">forward</span><span class="p">.</span><span class="nx">port</span><span class="p">;</span>
|
||||
<span class="nx">host</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">forward</span><span class="p">.</span><span class="nx">host</span><span class="p">;</span>
|
||||
|
||||
<span class="nx">outgoing</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="nx">host</span><span class="o">:</span> <span class="nx">host</span><span class="p">,</span>
|
||||
<span class="nx">port</span><span class="o">:</span> <span class="nx">port</span><span class="p">,</span>
|
||||
<span class="nx">agent</span><span class="o">:</span> <span class="nx">_getAgent</span><span class="p">(</span><span class="nx">host</span><span class="p">,</span> <span class="nx">port</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">forward</span><span class="p">.</span><span class="nx">https</span><span class="p">),</span>
|
||||
<span class="nx">method</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">method</span><span class="p">,</span>
|
||||
<span class="nx">path</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span>
|
||||
<span class="nx">headers</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span>
|
||||
<span class="p">};</span>
|
||||
</pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">¶</a> </div> <p>Force the <code>connection</code> header to be 'close' until
|
||||
node.js core re-implements 'keep-alive'.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">outgoing</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="s1">'connection'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'close'</span><span class="p">;</span>
|
||||
|
||||
<span class="nx">protocol</span> <span class="o">=</span> <span class="nx">_getProtocol</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">forward</span><span class="p">.</span><span class="nx">https</span><span class="p">,</span> <span class="nx">outgoing</span><span class="p">);</span>
|
||||
</pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">¶</a> </div> <p>Open new HTTP request to internal resource with will act as a reverse proxy pass</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">forwardProxy</span> <span class="o">=</span> <span class="nx">protocol</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="nx">outgoing</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">¶</a> </div> <p>Ignore the response from the forward proxy since this is a 'fire-and-forget' proxy.
|
||||
Remark (indexzero): We will eventually emit a 'forward' event here for performance tuning.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="p">});</span>
|
||||
</pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">¶</a> </div> <p>Add a listener for the connection timeout event.</p>
|
||||
|
||||
<p>Remark: Ignoring this error in the event
|
||||
forward target doesn't exist.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">forwardProxy</span><span class="p">.</span><span class="nx">once</span><span class="p">(</span><span class="s1">'error'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span> <span class="p">});</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">¶</a> </div> <p>Chunk the client request body as chunks from the proxied request come in</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">req</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">forwardProxy</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">chunk</span><span class="p">);</span>
|
||||
<span class="p">})</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">¶</a> </div> <p>At the end of the client request, we are going to stop the proxied request</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">req</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">forwardProxy</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">¶</a> </div> <h3>function proxyWebSocketRequest (req, socket, head, options)</h3>
|
||||
|
||||
<h4>@req {ServerRequest} Websocket request to proxy.</h4>
|
||||
|
||||
<h4>@socket {net.Socket} Socket for the underlying HTTP request</h4>
|
||||
|
||||
<h4>@head {string} Headers for the Websocket request.</h4>
|
||||
|
||||
<h4>@options {Object} Options to use when proxying this request.</h4>
|
||||
|
||||
<pre><code>options.port {number} Port to use on the proxy target host.
|
||||
options.host {string} Host of the proxy target.
|
||||
options.buffer {Object} Result from `httpProxy.buffer(req)`
|
||||
options.https {Object|boolean} Settings for https.
|
||||
</code></pre> </td> <td class="code"> <div class="highlight"><pre><span class="nx">HttpProxy</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">proxyWebSocketRequest</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">socket</span><span class="p">,</span> <span class="nx">head</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">self</span> <span class="o">=</span> <span class="k">this</span><span class="p">,</span>
|
||||
<span class="nx">listeners</span> <span class="o">=</span> <span class="p">{},</span>
|
||||
<span class="nx">errState</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span>
|
||||
<span class="nx">CRLF</span> <span class="o">=</span> <span class="s1">'\r\n'</span><span class="p">,</span>
|
||||
<span class="nx">outgoing</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">¶</a> </div> <p>WebSocket requests must have the <code>GET</code> method and
|
||||
the <code>upgrade:websocket</code> header</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">method</span> <span class="o">!==</span> <span class="s1">'GET'</span> <span class="o">||</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">upgrade</span><span class="p">.</span><span class="nx">toLowerCase</span><span class="p">()</span> <span class="o">!==</span> <span class="s1">'websocket'</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">¶</a> </div> <p>This request is not WebSocket request</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">¶</a> </div> <p>Helper function for setting appropriate socket values:
|
||||
1. Turn of all bufferings
|
||||
2. For server set KeepAlive
|
||||
3. For client set encoding</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">_socket</span><span class="p">(</span><span class="nx">socket</span><span class="p">,</span> <span class="nx">keepAlive</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">setTimeout</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">setNoDelay</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">keepAlive</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">socket</span><span class="p">.</span><span class="nx">setKeepAlive</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">setKeepAlive</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">socket</span><span class="p">.</span><span class="nx">pair</span><span class="p">.</span><span class="nx">cleartext</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">setKeepAlive</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">pair</span><span class="p">.</span><span class="nx">cleartext</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">setKeepAlive</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="p">{</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">setEncoding</span><span class="p">(</span><span class="s1">'utf8'</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">¶</a> </div> <p>On <code>upgrade</code> from the Agent socket, listen to
|
||||
the appropriate events.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">onUpgrade</span> <span class="p">(</span><span class="nx">reverseProxy</span><span class="p">,</span> <span class="nx">proxySocket</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">reverseProxy</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">proxySocket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="k">return</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-56">¶</a> </div> <p>Any incoming data on this WebSocket to the proxy target
|
||||
will be written to the <code>reverseProxy</code> socket.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">proxySocket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="nx">listeners</span><span class="p">.</span><span class="nx">onIncoming</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">incoming</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">writable</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">try</span> <span class="p">{</span>
|
||||
<span class="nx">self</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'websocket:outgoing'</span><span class="p">,</span> <span class="nx">req</span><span class="p">,</span> <span class="nx">socket</span><span class="p">,</span> <span class="nx">head</span><span class="p">,</span> <span class="nx">data</span><span class="p">);</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">incoming</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">incoming</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="nx">proxySocket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-57">¶</a> </div> <p>Any outgoing data on this Websocket from the proxy target
|
||||
will be written to the <code>proxySocket</code> socket.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">incoming</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="nx">listeners</span><span class="p">.</span><span class="nx">onOutgoing</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">try</span> <span class="p">{</span>
|
||||
<span class="nx">self</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'websocket:incoming'</span><span class="p">,</span> <span class="nx">reverseProxy</span><span class="p">,</span> <span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">incoming</span><span class="p">,</span> <span class="nx">head</span><span class="p">,</span> <span class="nx">data</span><span class="p">);</span>
|
||||
<span class="nx">proxySocket</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">proxySocket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">});</span>
|
||||
</pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">¶</a> </div> <p>Helper function to detach all event listeners
|
||||
from <code>reverseProxy</code> and <code>proxySocket</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">detach</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">proxySocket</span><span class="p">.</span><span class="nx">removeListener</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="nx">listeners</span><span class="p">.</span><span class="nx">onIncomingClose</span><span class="p">);</span>
|
||||
<span class="nx">proxySocket</span><span class="p">.</span><span class="nx">removeListener</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="nx">listeners</span><span class="p">.</span><span class="nx">onIncoming</span><span class="p">);</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">incoming</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">removeListener</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="nx">listeners</span><span class="p">.</span><span class="nx">onOutgoingClose</span><span class="p">);</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">incoming</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">removeListener</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="nx">listeners</span><span class="p">.</span><span class="nx">onOutgoing</span><span class="p">);</span>
|
||||
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">¶</a> </div> <p>If the incoming <code>proxySocket</code> socket closes, then
|
||||
detach all event listeners. </p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">proxySocket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="nx">listeners</span><span class="p">.</span><span class="nx">onIncomingClose</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">incoming</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="nx">detach</span><span class="p">();</span>
|
||||
</pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">¶</a> </div> <p>Emit the <code>end</code> event now that we have completed proxying</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">self</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'websocket:end'</span><span class="p">,</span> <span class="nx">req</span><span class="p">,</span> <span class="nx">socket</span><span class="p">,</span> <span class="nx">head</span><span class="p">);</span>
|
||||
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-61">¶</a> </div> <p>If the <code>reverseProxy</code> socket closes, then detach all
|
||||
event listeners.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">incoming</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'end'</span><span class="p">,</span> <span class="nx">listeners</span><span class="p">.</span><span class="nx">onOutgoingClose</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">proxySocket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="nx">detach</span><span class="p">();</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-62">¶</a> </div> <p>Setup the incoming client socket.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_socket</span><span class="p">(</span><span class="nx">socket</span><span class="p">);</span>
|
||||
|
||||
<span class="kd">function</span> <span class="nx">getPort</span> <span class="p">(</span><span class="nx">port</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">port</span> <span class="o">=</span> <span class="nx">port</span> <span class="o">||</span> <span class="mi">80</span><span class="p">;</span>
|
||||
<span class="k">return</span> <span class="nx">port</span> <span class="o">-</span> <span class="mi">80</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">?</span> <span class="s1">''</span> <span class="o">:</span> <span class="s1">':'</span> <span class="o">+</span> <span class="nx">port</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-63">¶</a> </div> <p>Get the protocol, and host for this request and create an instance
|
||||
of <code>http.Agent</code> or <code>https.Agent</code> from the pool managed by <code>node-http-proxy</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">protocolName</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">https</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">https</span> <span class="o">?</span> <span class="s1">'https'</span> <span class="o">:</span> <span class="s1">'http'</span><span class="p">,</span>
|
||||
<span class="nx">portUri</span> <span class="o">=</span> <span class="nx">getPort</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">source</span><span class="p">.</span><span class="nx">port</span><span class="p">),</span>
|
||||
<span class="nx">remoteHost</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">host</span> <span class="o">+</span> <span class="nx">portUri</span><span class="p">,</span>
|
||||
<span class="nx">agent</span> <span class="o">=</span> <span class="nx">_getAgent</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">host</span><span class="p">,</span> <span class="nx">options</span><span class="p">.</span><span class="nx">port</span><span class="p">,</span> <span class="nx">options</span><span class="p">.</span><span class="nx">https</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">https</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">¶</a> </div> <p>Change headers (if requested).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">changeOrigin</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">host</span> <span class="o">=</span> <span class="nx">remoteHost</span><span class="p">;</span>
|
||||
<span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">origin</span> <span class="o">=</span> <span class="nx">protocolName</span> <span class="o">+</span> <span class="s1">'://'</span> <span class="o">+</span> <span class="nx">remoteHost</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">¶</a> </div> <p>Make the outgoing WebSocket request</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">outgoing</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="nx">host</span><span class="o">:</span> <span class="nx">options</span><span class="p">.</span><span class="nx">host</span><span class="p">,</span>
|
||||
<span class="nx">port</span><span class="o">:</span> <span class="nx">options</span><span class="p">.</span><span class="nx">port</span><span class="p">,</span>
|
||||
<span class="nx">method</span><span class="o">:</span> <span class="s1">'GET'</span><span class="p">,</span>
|
||||
<span class="nx">path</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span>
|
||||
<span class="nx">headers</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">,</span>
|
||||
<span class="p">};</span>
|
||||
<span class="kd">var</span> <span class="nx">reverseProxy</span> <span class="o">=</span> <span class="nx">agent</span><span class="p">.</span><span class="nx">appendMessage</span><span class="p">(</span><span class="nx">outgoing</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">¶</a> </div> <p>On any errors from the <code>reverseProxy</code> emit the
|
||||
<code>webSocketProxyError</code> and close the appropriate
|
||||
connections.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">proxyError</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">self</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'webSocketProxyError'</span><span class="p">,</span> <span class="nx">req</span><span class="p">,</span> <span class="nx">socket</span><span class="p">,</span> <span class="nx">head</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="k">return</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span>
|
||||
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-67">¶</a> </div> <p>Here we set the incoming <code>req</code>, <code>socket</code> and <code>head</code> data to the outgoing
|
||||
request so that we can reuse this data later on in the closure scope
|
||||
available to the <code>upgrade</code> event. This bookkeeping is not tracked anywhere
|
||||
in nodejs core and is <strong>very</strong> specific to proxying WebSockets.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">agent</span> <span class="o">=</span> <span class="nx">agent</span><span class="p">;</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">incoming</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="nx">request</span><span class="o">:</span> <span class="nx">req</span><span class="p">,</span>
|
||||
<span class="nx">socket</span><span class="o">:</span> <span class="nx">socket</span><span class="p">,</span>
|
||||
<span class="nx">head</span><span class="o">:</span> <span class="nx">head</span>
|
||||
<span class="p">};</span>
|
||||
</pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-68">¶</a> </div> <p>If the agent for this particular <code>host</code> and <code>port</code> combination
|
||||
is not already listening for the <code>upgrade</code> event, then do so once.
|
||||
This will force us not to disconnect. </p>
|
||||
|
||||
<p>In addition, it's important to note the closure scope here. Since
|
||||
there is no mapping of the </p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">agent</span><span class="p">.</span><span class="nx">_events</span> <span class="o">||</span> <span class="nx">agent</span><span class="p">.</span><span class="nx">_events</span><span class="p">[</span><span class="s1">'upgrade'</span><span class="p">].</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">agent</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'upgrade'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="nx">remoteSocket</span><span class="p">,</span> <span class="nx">head</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-69">¶</a> </div> <p>Prepare the socket for the reverseProxy request and begin to
|
||||
stream data between the two sockets. Here it is important to
|
||||
note that <code>remoteSocket._httpMessage === reverseProxy</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_socket</span><span class="p">(</span><span class="nx">remoteSocket</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
|
||||
<span class="nx">onUpgrade</span><span class="p">(</span><span class="nx">remoteSocket</span><span class="p">.</span><span class="nx">_httpMessage</span><span class="p">,</span> <span class="nx">remoteSocket</span><span class="p">);</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-70">¶</a> </div> <p>If the reverseProxy connection has an underlying socket,
|
||||
then execute the WebSocket handshake.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">socket</span> <span class="o">!==</span> <span class="s1">'undefined'</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="kd">function</span> <span class="nx">handshake</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-71">¶</a> </div> <p>Ok, kind of harmfull part of code. Socket.IO sends a hash
|
||||
at the end of handshake if protocol === 76, but we need
|
||||
to replace 'host' and 'origin' in response so we split
|
||||
data to printable data and to non-printable. (Non-printable
|
||||
will come after double-CRLF).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">sdata</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-72">¶</a> </div> <p>Get the Printable data</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">sdata</span> <span class="o">=</span> <span class="nx">sdata</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">sdata</span><span class="p">.</span><span class="nx">search</span><span class="p">(</span><span class="nx">CRLF</span> <span class="o">+</span> <span class="nx">CRLF</span><span class="p">));</span></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-73">¶</a> </div> <p>Get the Non-Printable data</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">data</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">Buffer</span><span class="p">.</span><span class="nx">byteLength</span><span class="p">(</span><span class="nx">sdata</span><span class="p">),</span> <span class="nx">data</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">self</span><span class="p">.</span><span class="nx">https</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">self</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">https</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-74">¶</a> </div> <p>If the proxy server is running HTTPS but the client is running
|
||||
HTTP then replace <code>ws</code> with <code>wss</code> in the data sent back to the client.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">sdata</span> <span class="o">=</span> <span class="nx">sdata</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="s1">'ws:'</span><span class="p">,</span> <span class="s1">'wss:'</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">try</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-75">¶</a> </div> <p>Write the printable and non-printable data to the socket
|
||||
from the original incoming request. </p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">self</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'websocket:handshake'</span><span class="p">,</span> <span class="nx">req</span><span class="p">,</span> <span class="nx">socket</span><span class="p">,</span> <span class="nx">head</span><span class="p">,</span> <span class="nx">sdata</span><span class="p">,</span> <span class="nx">data</span><span class="p">);</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">sdata</span><span class="p">);</span>
|
||||
<span class="nx">socket</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">catch</span> <span class="p">(</span><span class="nx">ex</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">proxyError</span><span class="p">(</span><span class="nx">ex</span><span class="p">)</span>
|
||||
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-76">¶</a> </div> <p>Catch socket errors</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'error'</span><span class="p">,</span> <span class="nx">proxyError</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-77"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-77">¶</a> </div> <p>Remove data listener now that the 'handshake' is complete</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">socket</span><span class="p">.</span><span class="nx">removeListener</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="nx">handshake</span><span class="p">);</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'error'</span><span class="p">,</span> <span class="nx">proxyError</span><span class="p">);</span>
|
||||
|
||||
<span class="k">try</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-78">¶</a> </div> <p>Attempt to write the upgrade-head to the reverseProxy request.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">reverseProxy</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">head</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">catch</span> <span class="p">(</span><span class="nx">ex</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">proxyError</span><span class="p">(</span><span class="nx">ex</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-79">¶</a> </div> <p>If we have been passed buffered data, resume it.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">buffer</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">errState</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">options</span><span class="p">.</span><span class="nx">buffer</span><span class="p">.</span><span class="nx">resume</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
|
||||
@ -1,136 +0,0 @@
|
||||
<!DOCTYPE html> <html> <head> <title>proxy-table.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To … <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="node-http-proxy.html"> node-http-proxy.html </a> <a class="source" href="proxy-table.html"> proxy-table.html </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> proxy-table.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">¶</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/*</span>
|
||||
<span class="cm"> node-http-proxy.js: Lookup table for proxy targets in node.js</span>
|
||||
|
||||
<span class="cm"> Copyright (c) 2010 Charlie Robbins </span>
|
||||
|
||||
<span class="cm"> Permission is hereby granted, free of charge, to any person obtaining</span>
|
||||
<span class="cm"> a copy of this software and associated documentation files (the</span>
|
||||
<span class="cm"> "Software"), to deal in the Software without restriction, including</span>
|
||||
<span class="cm"> without limitation the rights to use, copy, modify, merge, publish,</span>
|
||||
<span class="cm"> distribute, sublicense, and/or sell copies of the Software, and to</span>
|
||||
<span class="cm"> permit persons to whom the Software is furnished to do so, subject to</span>
|
||||
<span class="cm"> the following conditions:</span>
|
||||
|
||||
<span class="cm"> The above copyright notice and this permission notice shall be</span>
|
||||
<span class="cm"> included in all copies or substantial portions of the Software.</span>
|
||||
|
||||
<span class="cm"> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,</span>
|
||||
<span class="cm"> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF</span>
|
||||
<span class="cm"> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND</span>
|
||||
<span class="cm"> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE</span>
|
||||
<span class="cm"> LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION</span>
|
||||
<span class="cm"> OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION</span>
|
||||
<span class="cm"> WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</span>
|
||||
|
||||
<span class="cm">*/</span>
|
||||
|
||||
<span class="kd">var</span> <span class="nx">util</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'util'</span><span class="p">),</span>
|
||||
<span class="nx">events</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'events'</span><span class="p">),</span>
|
||||
<span class="nx">fs</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'fs'</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">¶</a> </div> <h3>function ProxyTable (router, silent)</h3>
|
||||
|
||||
<h4>@router {Object} Object containing the host based routes</h4>
|
||||
|
||||
<h4>@silent {Boolean} Value indicating whether we should suppress logs</h4>
|
||||
|
||||
<h4>@hostnameOnly {Boolean} Value indicating if we should route based on <strong>hostname string only</strong></h4>
|
||||
|
||||
<p>Constructor function for the ProxyTable responsible for getting
|
||||
locations of proxy targets based on ServerRequest headers; specifically
|
||||
the HTTP host header.</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">ProxyTable</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">ProxyTable</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">router</span><span class="p">,</span> <span class="nx">silent</span><span class="p">,</span> <span class="nx">hostnameOnly</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">events</span><span class="p">.</span><span class="nx">EventEmitter</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
|
||||
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">silent</span> <span class="o">=</span> <span class="k">typeof</span> <span class="nx">silent</span> <span class="o">!==</span> <span class="s1">'undefined'</span> <span class="o">?</span> <span class="nx">silent</span> <span class="o">:</span> <span class="kc">true</span><span class="p">;</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">hostnameOnly</span> <span class="o">=</span> <span class="k">typeof</span> <span class="nx">hostnameOnly</span> <span class="o">!==</span> <span class="s1">'undefined'</span> <span class="o">?</span> <span class="nx">hostnameOnly</span> <span class="o">:</span> <span class="kc">false</span><span class="p">;</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">router</span> <span class="o">===</span> <span class="s1">'object'</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">¶</a> </div> <p>If we are passed an object literal setup
|
||||
the routes with RegExps from the router </p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">setRoutes</span><span class="p">(</span><span class="nx">router</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">router</span> <span class="o">===</span> <span class="s1">'string'</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">¶</a> </div> <p>If we are passed a string then assume it is a
|
||||
file path, parse that file and watch it for changes</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">self</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">routeFile</span> <span class="o">=</span> <span class="nx">router</span><span class="p">;</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">setRoutes</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">router</span><span class="p">)).</span><span class="nx">router</span><span class="p">);</span>
|
||||
|
||||
<span class="nx">fs</span><span class="p">.</span><span class="nx">watchFile</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">routeFile</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span><span class="p">(</span><span class="nx">self</span><span class="p">.</span><span class="nx">routeFile</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="k">throw</span> <span class="nx">err</span><span class="p">;</span>
|
||||
<span class="nx">self</span><span class="p">.</span><span class="nx">setRoutes</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">data</span><span class="p">).</span><span class="nx">router</span><span class="p">);</span>
|
||||
<span class="nx">self</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'routes'</span><span class="p">,</span> <span class="nx">self</span><span class="p">.</span><span class="nx">hostnameOnly</span> <span class="o">===</span> <span class="kc">false</span> <span class="o">?</span> <span class="nx">self</span><span class="p">.</span><span class="nx">routes</span> <span class="o">:</span> <span class="nx">self</span><span class="p">.</span><span class="nx">router</span><span class="p">);</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="p">{</span>
|
||||
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">'Cannot parse router with unknown type: '</span> <span class="o">+</span> <span class="k">typeof</span> <span class="nx">router</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">¶</a> </div> <p>Inherit from events.EventEmitter</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">util</span><span class="p">.</span><span class="nx">inherits</span><span class="p">(</span><span class="nx">ProxyTable</span><span class="p">,</span> <span class="nx">events</span><span class="p">.</span><span class="nx">EventEmitter</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">¶</a> </div> <h3>function setRoutes (router)</h3>
|
||||
|
||||
<h4>@router {Object} Object containing the host based routes</h4>
|
||||
|
||||
<p>Sets the host-based routes to be used by this instance. </p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">ProxyTable</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">setRoutes</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">router</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">router</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">'Cannot update ProxyTable routes without router.'</span><span class="p">);</span>
|
||||
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">router</span> <span class="o">=</span> <span class="nx">router</span><span class="p">;</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">hostnameOnly</span> <span class="o">===</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">self</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">routes</span> <span class="o">=</span> <span class="p">[];</span>
|
||||
|
||||
<span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">router</span><span class="p">).</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">path</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">route</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="nx">path</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">);</span>
|
||||
|
||||
<span class="nx">self</span><span class="p">.</span><span class="nx">routes</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span>
|
||||
<span class="nx">route</span><span class="o">:</span> <span class="nx">route</span><span class="p">,</span>
|
||||
<span class="nx">target</span><span class="o">:</span> <span class="nx">router</span><span class="p">[</span><span class="nx">path</span><span class="p">]</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">¶</a> </div> <h3>function getProxyLocation (req)</h3>
|
||||
|
||||
<h4>@req {ServerRequest} The incoming server request to get proxy information about.</h4>
|
||||
|
||||
<p>Returns the proxy location based on the HTTP Headers in the ServerRequest <code>req</code>
|
||||
available to this instance.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">ProxyTable</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getProxyLocation</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">req</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">req</span> <span class="o">||</span> <span class="o">!</span><span class="nx">req</span><span class="p">.</span><span class="nx">headers</span> <span class="o">||</span> <span class="o">!</span><span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">host</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">host</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">':'</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">hostnameOnly</span> <span class="o">==</span> <span class="kc">true</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">router</span><span class="p">.</span><span class="nx">hasOwnProperty</span><span class="p">(</span><span class="nx">target</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">location</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">router</span><span class="p">[</span><span class="nx">target</span><span class="p">].</span><span class="nx">split</span><span class="p">(</span><span class="s1">':'</span><span class="p">),</span>
|
||||
<span class="nx">host</span> <span class="o">=</span> <span class="nx">location</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
|
||||
<span class="nx">port</span> <span class="o">=</span> <span class="nx">location</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span> <span class="o">?</span> <span class="mi">80</span> <span class="o">:</span> <span class="nx">location</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
|
||||
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="nx">port</span><span class="o">:</span> <span class="nx">port</span><span class="p">,</span>
|
||||
<span class="nx">host</span><span class="o">:</span> <span class="nx">host</span>
|
||||
<span class="p">};</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="p">{</span>
|
||||
<span class="nx">target</span> <span class="o">+=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">url</span><span class="p">;</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="k">in</span> <span class="k">this</span><span class="p">.</span><span class="nx">routes</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">match</span><span class="p">,</span> <span class="nx">route</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">routes</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">match</span> <span class="o">=</span> <span class="nx">target</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">route</span><span class="p">.</span><span class="nx">route</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">location</span> <span class="o">=</span> <span class="nx">route</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">':'</span><span class="p">),</span>
|
||||
<span class="nx">host</span> <span class="o">=</span> <span class="nx">location</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
|
||||
<span class="nx">port</span> <span class="o">=</span> <span class="nx">location</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span> <span class="o">?</span> <span class="mi">80</span> <span class="o">:</span> <span class="nx">location</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
|
||||
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="nx">port</span><span class="o">:</span> <span class="nx">port</span><span class="p">,</span>
|
||||
<span class="nx">host</span><span class="o">:</span> <span class="nx">host</span>
|
||||
<span class="p">};</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
|
||||
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">¶</a> </div> <h3>close function ()</h3>
|
||||
|
||||
<p>Cleans up the event listeneners maintained
|
||||
by this instance.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">ProxyTable</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">close</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="k">this</span><span class="p">.</span><span class="nx">routeFile</span> <span class="o">===</span> <span class="s1">'string'</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">fs</span><span class="p">.</span><span class="nx">unwatchFile</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">routeFile</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
|
||||
Loading…
x
Reference in New Issue
Block a user