Wed, 31 Dec 2014 06:55:46 +0100
Added tag TORBROWSER_REPLICA for changeset 6474c204b198
michael@0 | 1 | # SPDY Server for node.js [](http://travis-ci.org/indutny/node-spdy) |
michael@0 | 2 | |
michael@0 | 3 | <a href="http://flattr.com/thing/758213/indutnynode-spdy-on-GitHub" target="_blank"> |
michael@0 | 4 | <img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0" /></a> |
michael@0 | 5 | |
michael@0 | 6 | With this module you can create [SPDY](http://www.chromium.org/spdy) servers |
michael@0 | 7 | in node.js with natural http module interface and fallback to regular https |
michael@0 | 8 | (for browsers that doesn't support SPDY yet). |
michael@0 | 9 | |
michael@0 | 10 | ## Usage |
michael@0 | 11 | |
michael@0 | 12 | ```javascript |
michael@0 | 13 | var spdy = require('spdy'), |
michael@0 | 14 | fs = require('fs'); |
michael@0 | 15 | |
michael@0 | 16 | var options = { |
michael@0 | 17 | key: fs.readFileSync(__dirname + '/keys/spdy-key.pem'), |
michael@0 | 18 | cert: fs.readFileSync(__dirname + '/keys/spdy-cert.pem'), |
michael@0 | 19 | ca: fs.readFileSync(__dirname + '/keys/spdy-csr.pem'), |
michael@0 | 20 | |
michael@0 | 21 | // SPDY-specific options |
michael@0 | 22 | windowSize: 1024, // Server's window size |
michael@0 | 23 | }; |
michael@0 | 24 | |
michael@0 | 25 | var server = spdy.createServer(options, function(req, res) { |
michael@0 | 26 | res.writeHead(200); |
michael@0 | 27 | res.end('hello world!'); |
michael@0 | 28 | }); |
michael@0 | 29 | |
michael@0 | 30 | server.listen(443); |
michael@0 | 31 | ``` |
michael@0 | 32 | |
michael@0 | 33 | And by popular demand - usage with |
michael@0 | 34 | [express](https://github.com/visionmedia/express): |
michael@0 | 35 | |
michael@0 | 36 | ```javascript |
michael@0 | 37 | var spdy = require('spdy'), |
michael@0 | 38 | express = require('express'), |
michael@0 | 39 | fs = require('fs'); |
michael@0 | 40 | |
michael@0 | 41 | var options = { /* the same as above */ }; |
michael@0 | 42 | |
michael@0 | 43 | var app = express(); |
michael@0 | 44 | |
michael@0 | 45 | app.use(/* your favorite middleware */); |
michael@0 | 46 | |
michael@0 | 47 | var server = spdy.createServer(options, app); |
michael@0 | 48 | |
michael@0 | 49 | server.listen(443); |
michael@0 | 50 | ``` |
michael@0 | 51 | |
michael@0 | 52 | ## API |
michael@0 | 53 | |
michael@0 | 54 | API is compatible with `http` and `https` module, but you can use another |
michael@0 | 55 | function as base class for SPDYServer. |
michael@0 | 56 | |
michael@0 | 57 | ```javascript |
michael@0 | 58 | spdy.createServer( |
michael@0 | 59 | [base class constructor, i.e. https.Server], |
michael@0 | 60 | { /* keys and options */ }, // <- the only one required argument |
michael@0 | 61 | [request listener] |
michael@0 | 62 | ).listen([port], [host], [callback]); |
michael@0 | 63 | ``` |
michael@0 | 64 | |
michael@0 | 65 | Request listener will receive two arguments: `request` and `response`. They're |
michael@0 | 66 | both instances of `http`'s `IncomingMessage` and `OutgoingMessage`. But three |
michael@0 | 67 | custom properties are added to both of them: `streamID`, `isSpdy`, |
michael@0 | 68 | `spdyVersion`. The first one indicates on which spdy stream are sitting request |
michael@0 | 69 | and response. Second is always true and can be checked to ensure that incoming |
michael@0 | 70 | request wasn't received by HTTPS fallback and last one is a number representing |
michael@0 | 71 | used SPDY protocol version (2 or 3 for now). |
michael@0 | 72 | |
michael@0 | 73 | ### Push streams |
michael@0 | 74 | |
michael@0 | 75 | It is possible to initiate 'push' streams to send content to clients _before_ |
michael@0 | 76 | the client requests it. |
michael@0 | 77 | |
michael@0 | 78 | ```javascript |
michael@0 | 79 | spdy.createServer(options, function(req, res) { |
michael@0 | 80 | var headers = { 'content-type': 'application/javascript' }; |
michael@0 | 81 | res.push('/main.js', headers, function(err, stream) { |
michael@0 | 82 | if (err) return; |
michael@0 | 83 | |
michael@0 | 84 | stream.end('alert("hello from push stream!");'); |
michael@0 | 85 | }); |
michael@0 | 86 | |
michael@0 | 87 | res.end('<script src="/main.js"></script>'); |
michael@0 | 88 | }).listen(443); |
michael@0 | 89 | ``` |
michael@0 | 90 | |
michael@0 | 91 | Push is accomplished via the `push()` method invoked on the current response |
michael@0 | 92 | object (this works for express.js response objects as well). The format of the |
michael@0 | 93 | `push()` method is: |
michael@0 | 94 | |
michael@0 | 95 | `.push('full or relative url', { ... headers ... }, optional priority, callback)` |
michael@0 | 96 | |
michael@0 | 97 | You can use either full ( `http://host/path` ) or relative ( `/path` ) urls with |
michael@0 | 98 | `.push()`. `headers` are the same as for regular response object. `callback` |
michael@0 | 99 | will receive two arguments: `err` (if any error is happened) and `stream` |
michael@0 | 100 | (stream object have API compatible with a |
michael@0 | 101 | [net.Socket](http://nodejs.org/docs/latest/api/net.html#net.Socket) ). |
michael@0 | 102 | |
michael@0 | 103 | ### Options |
michael@0 | 104 | |
michael@0 | 105 | All options supported by |
michael@0 | 106 | [tls](http://nodejs.org/docs/latest/api/tls.html#tls.createServer) are working |
michael@0 | 107 | with node-spdy. In addition, `maxStreams` options is available. it allows you |
michael@0 | 108 | controlling [maximum concurrent streams][http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2#TOC-SETTINGS] |
michael@0 | 109 | protocol option (if client will start more streams than that limit, RST_STREAM |
michael@0 | 110 | will be sent for each additional stream). |
michael@0 | 111 | |
michael@0 | 112 | Additional options: |
michael@0 | 113 | |
michael@0 | 114 | * `plain` - if defined, server will accept only plain (non-encrypted) |
michael@0 | 115 | connections. |
michael@0 | 116 | |
michael@0 | 117 | #### Contributors |
michael@0 | 118 | |
michael@0 | 119 | * [Fedor Indutny](https://github.com/indutny) |
michael@0 | 120 | * [Chris Strom](https://github.com/eee-c) |
michael@0 | 121 | * [François de Metz](https://github.com/francois2metz) |
michael@0 | 122 | * [Ilya Grigorik](https://github.com/igrigorik) |
michael@0 | 123 | * [Roberto Peon](https://github.com/grmocg) |
michael@0 | 124 | * [Tatsuhiro Tsujikawa](https://github.com/tatsuhiro-t) |
michael@0 | 125 | * [Jesse Cravens](https://github.com/jessecravens) |
michael@0 | 126 | |
michael@0 | 127 | #### LICENSE |
michael@0 | 128 | |
michael@0 | 129 | This software is licensed under the MIT License. |
michael@0 | 130 | |
michael@0 | 131 | Copyright Fedor Indutny, 2012. |
michael@0 | 132 | |
michael@0 | 133 | Permission is hereby granted, free of charge, to any person obtaining a |
michael@0 | 134 | copy of this software and associated documentation files (the |
michael@0 | 135 | "Software"), to deal in the Software without restriction, including |
michael@0 | 136 | without limitation the rights to use, copy, modify, merge, publish, |
michael@0 | 137 | distribute, sublicense, and/or sell copies of the Software, and to permit |
michael@0 | 138 | persons to whom the Software is furnished to do so, subject to the |
michael@0 | 139 | following conditions: |
michael@0 | 140 | |
michael@0 | 141 | The above copyright notice and this permission notice shall be included |
michael@0 | 142 | in all copies or substantial portions of the Software. |
michael@0 | 143 | |
michael@0 | 144 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
michael@0 | 145 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
michael@0 | 146 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
michael@0 | 147 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
michael@0 | 148 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
michael@0 | 149 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
michael@0 | 150 | USE OR OTHER DEALINGS IN THE SOFTWARE. |