index.html 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. <html>
  2. <head>
  3. <title>FlashPolicyFileServer</title>
  4. <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  5. <style>body {
  6. margin: 0;
  7. padding: 0;
  8. font: 14px/1.5 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
  9. color: #252519;
  10. }
  11. a {
  12. color: #252519;
  13. }
  14. a:hover {
  15. text-decoration: underline;
  16. color: #19469D;
  17. }
  18. p {
  19. margin: 12px 0;
  20. }
  21. h1, h2, h3 {
  22. margin: 0;
  23. padding: 0;
  24. }
  25. table#source {
  26. width: 100%;
  27. border-collapse: collapse;
  28. }
  29. table#source td:first-child {
  30. padding: 30px 40px 30px 40px;
  31. vertical-align: top;
  32. }
  33. table#source td:first-child,
  34. table#source td:first-child pre {
  35. width: 450px;
  36. }
  37. table#source td:last-child {
  38. padding: 30px 0 30px 40px;
  39. border-left: 1px solid #E5E5EE;
  40. background: #F5F5FF;
  41. }
  42. table#source tr {
  43. border-bottom: 1px solid #E5E5EE;
  44. }
  45. table#source tr.filename {
  46. padding-top: 40px;
  47. border-top: 1px solid #E5E5EE;
  48. }
  49. table#source tr.filename td:first-child {
  50. text-transform: capitalize;
  51. }
  52. table#source tr.filename td:last-child {
  53. font-size: 12px;
  54. }
  55. table#source tr.filename h2 {
  56. margin: 0;
  57. padding: 0;
  58. cursor: pointer;
  59. }
  60. table#source tr.code h1,
  61. table#source tr.code h2,
  62. table#source tr.code h3 {
  63. margin-top: 30px;
  64. font-family: "Lucida Grande", "Helvetica Nueue", Arial, sans-serif;
  65. font-size: 18px;
  66. }
  67. table#source tr.code h2 {
  68. font-size: 16px;
  69. }
  70. table#source tr.code h3 {
  71. font-size: 14px;
  72. }
  73. table#source tr.code ul {
  74. margin: 15px 0 15px 35px;
  75. padding: 0;
  76. }
  77. table#source tr.code ul li {
  78. margin: 0;
  79. padding: 1px 0;
  80. }
  81. table#source tr.code ul li p {
  82. margin: 0;
  83. padding: 0;
  84. }
  85. table#source tr.code td:first-child pre {
  86. padding: 20px;
  87. }
  88. #ribbon {
  89. position: fixed;
  90. top: 0;
  91. right: 0;
  92. }
  93. code .string { color: #219161; }
  94. code .regexp { color: #219161; }
  95. code .keyword { color: #954121; }
  96. code .number { color: #19469D; }
  97. code .comment { color: #bbb; }
  98. code .this { color: #19469D; }</style>
  99. <script>
  100. $(function(){
  101. $('tr.code').hide();
  102. $('tr.filename').toggle(function(){
  103. $(this).nextUntil('.filename').fadeIn();
  104. }, function(){
  105. $(this).nextUntil('.filename').fadeOut();
  106. });
  107. });
  108. </script>
  109. </head>
  110. <body>
  111. <table id="source"><tbody><tr><td><h1>FlashPolicyFileServer</h1></td><td></td></tr><tr class="filename"><td><h2 id="lib/server.js"><a href="#">server</a></h2></td><td>lib/server.js</td></tr><tr class="code">
  112. <td class="docs">
  113. <p>Module dependencies and cached references.
  114. </p>
  115. </td>
  116. <td class="code">
  117. <pre><code><span class="keyword">var</span> <span class="variable">slice</span> = <span class="class">Array</span>.<span class="variable">prototype</span>.<span class="variable">slice</span>
  118. , <span class="variable">net</span> = <span class="variable">require</span>(<span class="string">'net'</span>);</code></pre>
  119. </td>
  120. </tr>
  121. <tr class="code">
  122. <td class="docs">
  123. <p>The server that does the Policy File severing</p>
  124. <h2>Options</h2>
  125. <ul><li><code>log</code> false or a function that can output log information, defaults to console.log?</li></ul>
  126. <h2></h2>
  127. <ul><li><p><strong>param</strong>: <em>Object</em> options Options to customize the servers functionality.</p></li><li><p><strong>param</strong>: <em>Array</em> origins The origins that are allowed on this server, defaults to <code>*:*</code>.</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul>
  128. </td>
  129. <td class="code">
  130. <pre><code><span class="keyword">function</span> <span class="class">Server</span>(<span class="variable">options</span>, <span class="variable">origins</span>){
  131. <span class="keyword">var</span> <span class="variable">me</span> = <span class="this">this</span>;
  132. <span class="this">this</span>.<span class="variable">origins</span> = <span class="variable">origins</span> || [<span class="string">'*:*'</span>];
  133. <span class="this">this</span>.<span class="variable">port</span> = <span class="number integer">843</span>;
  134. <span class="this">this</span>.<span class="variable">log</span> = <span class="variable">console</span>.<span class="variable">log</span>;
  135. <span class="comment">// merge `this` with the options</span>
  136. <span class="class">Object</span>.<span class="variable">keys</span>(<span class="variable">options</span>).<span class="variable">forEach</span>(<span class="keyword">function</span>(<span class="variable">key</span>){
  137. <span class="variable">me</span>[<span class="variable">key</span>] &<span class="variable">amp</span>;&<span class="variable">amp</span>; (<span class="variable">me</span>[<span class="variable">key</span>] = <span class="variable">options</span>[<span class="variable">key</span>])
  138. });
  139. <span class="comment">// create the net server</span>
  140. <span class="this">this</span>.<span class="variable">socket</span> = <span class="variable">net</span>.<span class="variable">createServer</span>(<span class="keyword">function</span> <span class="variable">createServer</span>(<span class="variable">socket</span>){
  141. <span class="variable">socket</span>.<span class="variable">on</span>(<span class="string">'error'</span>, <span class="keyword">function</span> <span class="variable">socketError</span>(){ <span class="variable">me</span>.<span class="variable">responder</span>.<span class="variable">call</span>(<span class="variable">me</span>, <span class="variable">socket</span>) });
  142. <span class="variable">me</span>.<span class="variable">responder</span>.<span class="variable">call</span>(<span class="variable">me</span>, <span class="variable">socket</span>);
  143. });
  144. <span class="comment">// Listen for errors as the port might be blocked because we do not have root priv.</span>
  145. <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">on</span>(<span class="string">'error'</span>, <span class="keyword">function</span> <span class="variable">serverError</span>(<span class="variable">err</span>){
  146. <span class="comment">// Special and common case error handling</span>
  147. <span class="keyword">if</span> (<span class="variable">err</span>.<span class="variable">errno</span> == <span class="number integer">13</span>){
  148. <span class="variable">me</span>.<span class="variable">log</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">log</span>(
  149. <span class="string">'Unable to listen to port `'</span> + <span class="variable">me</span>.<span class="variable">port</span> + <span class="string">'` as your Node.js instance does not have root privileges. '</span> +
  150. (
  151. <span class="variable">me</span>.<span class="variable">server</span>
  152. ? <span class="string">'The Flash Policy file will now be served inline over the supplied HTTP server, Flash Policy files request will suffer.'</span>
  153. : <span class="string">'No fallback server supplied.'</span>
  154. )
  155. );
  156. <span class="variable">me</span>.<span class="variable">socket</span>.<span class="variable">removeAllListeners</span>();
  157. <span class="keyword">delete</span> <span class="variable">me</span>.<span class="variable">socket</span>;
  158. <span class="variable">me</span>.<span class="variable">emit</span>(<span class="string">'connect_failed'</span>, <span class="variable">err</span>);
  159. } <span class="keyword">else</span> {
  160. <span class="variable">me</span>.<span class="variable">log</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">log</span>(<span class="string">'FlashPolicyFileServer received a error event:\n'</span> + (<span class="variable">err</span>.<span class="variable">message</span> ? <span class="variable">err</span>.<span class="variable">message</span> : <span class="variable">err</span>));
  161. }
  162. });
  163. <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">on</span>(<span class="string">'timeout'</span>, <span class="keyword">function</span> <span class="variable">serverTimeout</span>(){});
  164. <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">on</span>(<span class="string">'close'</span>, <span class="keyword">function</span> <span class="variable">serverClosed</span>(<span class="variable">err</span>){
  165. <span class="variable">err</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">log</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">log</span>(<span class="string">'Server closing due to an error: \n'</span> + (<span class="variable">err</span>.<span class="variable">message</span> ? <span class="variable">err</span>.<span class="variable">message</span> : <span class="variable">err</span>));
  166. <span class="keyword">if</span> (<span class="variable">me</span>.<span class="variable">server</span>){
  167. <span class="comment">// not online anymore</span>
  168. <span class="keyword">delete</span> <span class="variable">me</span>.<span class="variable">server</span>.<span class="variable">online</span>;
  169. <span class="comment">// Remove the inline policy listener if we close down</span>
  170. <span class="comment">// but only when the server was `online` (see listen prototype)</span>
  171. <span class="keyword">if</span>( <span class="variable">me</span>.<span class="variable">server</span>[<span class="string">'@'</span>] &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">server</span>.<span class="variable">online</span>){
  172. <span class="variable">me</span>.<span class="variable">server</span>.<span class="variable">removeListener</span>(<span class="string">'connection'</span>, <span class="variable">me</span>.<span class="variable">server</span>[<span class="string">'@'</span>]);
  173. }
  174. }
  175. <span class="variable">me</span>.<span class="variable">log</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">me</span>.<span class="variable">log</span>(<span class="string">'Shutting down FlashPolicyFileServer'</span>);
  176. });
  177. <span class="comment">// Compile the initial `buffer`</span>
  178. <span class="this">this</span>.<span class="variable">compile</span>();
  179. }</code></pre>
  180. </td>
  181. </tr>
  182. <tr class="code">
  183. <td class="docs">
  184. <p>Start listening for requests</p>
  185. <h2></h2>
  186. <ul><li><p><strong>param</strong>: <em>Number</em> port The port number it should be listening to.</p></li><li><p><strong>param</strong>: <em>Server</em> server A HTTP server instance, this will be used to listen for inline requests</p></li><li><p><strong>param</strong>: <em>Function</em> cb The callback needs to be called once server is ready</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul>
  187. </td>
  188. <td class="code">
  189. <pre><code><span class="class">Server</span>.<span class="variable">prototype</span>.<span class="variable">listen</span> = <span class="keyword">function</span> <span class="variable">listen</span>(<span class="variable">port</span>, <span class="variable">server</span>, <span class="variable">cb</span>){
  190. <span class="keyword">var</span> <span class="variable">me</span> = <span class="this">this</span>
  191. , <span class="variable">args</span> = <span class="variable">slice</span>.<span class="variable">call</span>(<span class="variable">arguments</span>, <span class="number integer">0</span>)
  192. , <span class="variable">callback</span>;
  193. <span class="comment">// assign the correct vars, for flexible arguments</span>
  194. <span class="variable">args</span>.<span class="variable">forEach</span>(<span class="keyword">function</span> <span class="variable">args</span>(<span class="variable">arg</span>){
  195. <span class="keyword">var</span> <span class="variable">type</span> = <span class="keyword">typeof</span> <span class="variable">arg</span>;
  196. <span class="keyword">if</span> (<span class="variable">type</span> === <span class="string">'number'</span>) <span class="variable">me</span>.<span class="variable">port</span> = <span class="variable">arg</span>;
  197. <span class="keyword">if</span> (<span class="variable">type</span> === <span class="string">'function'</span>) <span class="variable">callback</span> = <span class="variable">arg</span>;
  198. <span class="keyword">if</span> (<span class="variable">type</span> === <span class="string">'object'</span>) <span class="variable">me</span>.<span class="variable">server</span> = <span class="variable">arg</span>;
  199. });
  200. <span class="keyword">if</span> (<span class="this">this</span>.<span class="variable">server</span>){
  201. <span class="comment">// no one in their right mind would ever create a `@` prototype, so Im just gonna store</span>
  202. <span class="comment">// my function on the server, so I can remove it later again once the server(s) closes</span>
  203. <span class="this">this</span>.<span class="variable">server</span>[<span class="string">'@'</span>] = <span class="keyword">function</span> <span class="variable">connection</span>(<span class="variable">socket</span>){
  204. <span class="variable">socket</span>.<span class="variable">once</span>(<span class="string">'data'</span>, <span class="keyword">function</span> <span class="variable">requestData</span>(<span class="variable">data</span>){
  205. <span class="comment">// if it's a Flash policy request, and we can write to the </span>
  206. <span class="keyword">if</span> (
  207. <span class="variable">data</span>
  208. &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">data</span>[<span class="number integer">0</span>] === <span class="number integer">60</span>
  209. &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">data</span>.<span class="variable">toString</span>() === <span class="string">'&lt;policy-file-request/&gt;\0'</span>
  210. &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">socket</span>
  211. &<span class="variable">amp</span>;&<span class="variable">amp</span>; (<span class="variable">socket</span>.<span class="variable">readyState</span> === <span class="string">'open'</span> || <span class="variable">socket</span>.<span class="variable">readyState</span> === <span class="string">'writeOnly'</span>)
  212. ){
  213. <span class="comment">// send the buffer</span>
  214. <span class="variable">socket</span>.<span class="variable">end</span>(<span class="variable">me</span>.<span class="variable">buffer</span>);
  215. }
  216. });
  217. };
  218. <span class="comment">// attach it</span>
  219. <span class="this">this</span>.<span class="variable">server</span>.<span class="variable">on</span>(<span class="string">'connection'</span>, <span class="this">this</span>.<span class="variable">server</span>[<span class="string">'@'</span>]);
  220. }
  221. <span class="comment">// We add a callback method, so we can set a flag for when the server is `enabled` or `online`.</span>
  222. <span class="comment">// this flag is needed because if a error occurs and the we cannot boot up the server the</span>
  223. <span class="comment">// fallback functionality should not be removed during the `close` event</span>
  224. <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">listen</span>(<span class="this">this</span>.<span class="variable">port</span>, <span class="keyword">function</span> <span class="variable">serverListening</span>(){
  225. <span class="variable">me</span>.<span class="variable">socket</span>.<span class="variable">online</span> = <span class="variable">true</span>;
  226. <span class="keyword">if</span> (<span class="variable">callback</span>) <span class="variable">callback</span>(), <span class="variable">callback</span> = <span class="variable">undefined</span>;
  227. });
  228. <span class="keyword">return</span> <span class="this">this</span>;
  229. };</code></pre>
  230. </td>
  231. </tr>
  232. <tr class="code">
  233. <td class="docs">
  234. <p>Adds a new origin to the Flash Policy File.</p>
  235. <h2></h2>
  236. <ul><li><p><strong>param</strong>: <em>Arguments</em> The origins that need to be added.</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul>
  237. </td>
  238. <td class="code">
  239. <pre><code><span class="class">Server</span>.<span class="variable">prototype</span>.<span class="variable">add</span> = <span class="keyword">function</span> <span class="variable">add</span>(){
  240. <span class="keyword">var</span> <span class="variable">args</span> = <span class="variable">slice</span>.<span class="variable">call</span>(<span class="variable">arguments</span>, <span class="number integer">0</span>)
  241. , <span class="variable">i</span> = <span class="variable">args</span>.<span class="variable">length</span>;
  242. <span class="comment">// flag duplicates</span>
  243. <span class="keyword">while</span> (<span class="variable">i</span>--){
  244. <span class="keyword">if</span> (<span class="this">this</span>.<span class="variable">origins</span>.<span class="variable">indexOf</span>(<span class="variable">args</span>[<span class="variable">i</span>]) &<span class="variable">gt</span>;= <span class="number integer">0</span>){
  245. <span class="variable">args</span>[<span class="variable">i</span>] = <span class="keyword">null</span>;
  246. }
  247. }
  248. <span class="comment">// Add all the arguments to the array</span>
  249. <span class="comment">// but first we want to remove all `falsy` values from the args</span>
  250. <span class="class">Array</span>.<span class="variable">prototype</span>.<span class="variable">push</span>.<span class="variable">apply</span>(
  251. <span class="this">this</span>.<span class="variable">origins</span>
  252. , <span class="variable">args</span>.<span class="variable">filter</span>(<span class="keyword">function</span>(<span class="variable">value</span>){ <span class="keyword">return</span> !!<span class="variable">value</span> })
  253. );
  254. <span class="this">this</span>.<span class="variable">compile</span>();
  255. <span class="keyword">return</span> <span class="this">this</span>;
  256. };</code></pre>
  257. </td>
  258. </tr>
  259. <tr class="code">
  260. <td class="docs">
  261. <p>Removes a origin from the Flash Policy File.</p>
  262. <h2></h2>
  263. <ul><li><p><strong>param</strong>: <em>String</em> origin The origin that needs to be removed from the server</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul>
  264. </td>
  265. <td class="code">
  266. <pre><code><span class="class">Server</span>.<span class="variable">prototype</span>.<span class="variable">remove</span> = <span class="keyword">function</span> <span class="variable">remove</span>(<span class="variable">origin</span>){
  267. <span class="keyword">var</span> <span class="variable">position</span> = <span class="this">this</span>.<span class="variable">origins</span>.<span class="variable">indexOf</span>(<span class="variable">origin</span>);
  268. <span class="comment">// only remove and recompile if we have a match</span>
  269. <span class="keyword">if</span> (<span class="variable">position</span> &<span class="variable">gt</span>; <span class="number integer">0</span>){
  270. <span class="this">this</span>.<span class="variable">origins</span>.<span class="variable">splice</span>(<span class="variable">position</span>,<span class="number integer">1</span>);
  271. <span class="this">this</span>.<span class="variable">compile</span>();
  272. }
  273. <span class="keyword">return</span> <span class="this">this</span>;
  274. };</code></pre>
  275. </td>
  276. </tr>
  277. <tr class="code">
  278. <td class="docs">
  279. <p>Closes and cleans up the server</p>
  280. <ul><li><p><strong>api</strong>: <em>public</em></p></li></ul>
  281. </td>
  282. <td class="code">
  283. <pre><code><span class="class">Server</span>.<span class="variable">prototype</span>.<span class="variable">close</span> = <span class="keyword">function</span> <span class="variable">close</span>(){
  284. <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">removeAllListeners</span>();
  285. <span class="this">this</span>.<span class="variable">socket</span>.<span class="variable">close</span>();
  286. <span class="keyword">return</span> <span class="this">this</span>;
  287. };</code></pre>
  288. </td>
  289. </tr>
  290. <tr class="code">
  291. <td class="docs">
  292. <p>Proxy the event listener requests to the created Net server
  293. </p>
  294. </td>
  295. <td class="code">
  296. <pre><code><span class="class">Object</span>.<span class="variable">keys</span>(<span class="variable">process</span>.<span class="class">EventEmitter</span>.<span class="variable">prototype</span>).<span class="variable">forEach</span>(<span class="keyword">function</span> <span class="variable">proxy</span>(<span class="variable">key</span>){
  297. <span class="class">Server</span>.<span class="variable">prototype</span>[<span class="variable">key</span>] = <span class="class">Server</span>.<span class="variable">prototype</span>[<span class="variable">key</span>] || <span class="keyword">function</span> (){
  298. <span class="keyword">if</span> (<span class="this">this</span>.<span class="variable">socket</span>) <span class="this">this</span>.<span class="variable">socket</span>[<span class="variable">key</span>].<span class="variable">apply</span>(<span class="this">this</span>.<span class="variable">socket</span>, <span class="variable">arguments</span>);
  299. <span class="keyword">return</span> <span class="this">this</span>;
  300. };
  301. });</code></pre>
  302. </td>
  303. </tr>
  304. <tr class="code">
  305. <td class="docs">
  306. <p>Creates a new server instance.</p>
  307. <h2></h2>
  308. <ul><li><p><strong>param</strong>: <em>Object</em> options A options object to override the default config</p></li><li><p><strong>param</strong>: <em>Array</em> origins The origins that should be allowed by the server</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul>
  309. </td>
  310. <td class="code">
  311. <pre><code><span class="variable">exports</span>.<span class="variable">createServer</span> = <span class="keyword">function</span> <span class="variable">createServer</span>(<span class="variable">options</span>, <span class="variable">origins</span>){
  312. <span class="variable">origins</span> = <span class="class">Array</span>.<span class="variable">isArray</span>(<span class="variable">origins</span>) ? <span class="variable">origins</span> : (<span class="class">Array</span>.<span class="variable">isArray</span>(<span class="variable">options</span>) ? <span class="variable">options</span> : <span class="variable">false</span>);
  313. <span class="variable">options</span> = !<span class="class">Array</span>.<span class="variable">isArray</span>(<span class="variable">options</span>) &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">options</span> ? <span class="variable">options</span> : {};
  314. <span class="keyword">return</span> <span class="keyword">new</span> <span class="class">Server</span>(<span class="variable">options</span>, <span class="variable">origins</span>);
  315. };</code></pre>
  316. </td>
  317. </tr>
  318. <tr class="code">
  319. <td class="docs">
  320. <p>Provide a hook to the original server, so it can be extended if needed.
  321. </p>
  322. </td>
  323. <td class="code">
  324. <pre><code><span class="variable">exports</span>.<span class="class">Server</span> = <span class="class">Server</span>;</code></pre>
  325. </td>
  326. </tr>
  327. <tr class="code">
  328. <td class="docs">
  329. <p>Module version
  330. </p>
  331. </td>
  332. <td class="code">
  333. <pre><code><span class="variable">exports</span>.<span class="variable">version</span> = <span class="string">'0.0.2'</span>;
  334. </code></pre>
  335. </td>
  336. </tr> </body>
  337. </html></tbody></table>