Coder Social home page Coder Social logo

node-spdy's Introduction

SPDY Server for node.js

Build Status NPM version dependencies Status Standard - JavaScript Style Guide Waffle

With this module you can create HTTP2 / SPDY servers in node.js with natural http module interface and fallback to regular https (for browsers that don't support neither HTTP2, nor SPDY yet).

This module named spdy but it provides support for both http/2 (h2) and spdy (2,3,3.1). Also, spdy is compatible with Express.

Usage

Examples

Server:

var spdy = require('spdy'),
    fs = require('fs');

var options = {
  // Private key
  key: fs.readFileSync(__dirname + '/keys/spdy-key.pem'),

  // Fullchain file or cert file (prefer the former)
  cert: fs.readFileSync(__dirname + '/keys/spdy-fullchain.pem'),

  // **optional** SPDY-specific options
  spdy: {
    protocols: [ 'h2', 'spdy/3.1', ..., 'http/1.1' ],
    plain: false,

    // **optional**
    // Parse first incoming X_FORWARDED_FOR frame and put it to the
    // headers of every request.
    // NOTE: Use with care! This should not be used without some proxy that
    // will *always* send X_FORWARDED_FOR
    'x-forwarded-for': true,

    connection: {
      windowSize: 1024 * 1024, // Server's window size

      // **optional** if true - server will send 3.1 frames on 3.0 *plain* spdy
      autoSpdy31: false
    }
  }
};

var server = spdy.createServer(options, function(req, res) {
  res.writeHead(200);
  res.end('hello world!');
});

server.listen(3000);

Client:

var spdy = require('spdy');
var https = require('https');

var agent = spdy.createAgent({
  host: 'www.google.com',
  port: 443,

  // Optional SPDY options
  spdy: {
    plain: false,
    ssl: true,

    // **optional** send X_FORWARDED_FOR
    'x-forwarded-for': '127.0.0.1'
  }
});

https.get({
  host: 'www.google.com',
  agent: agent
}, function(response) {
  console.log('yikes');
  // Here it goes like with any other node.js HTTP request
  // ...
  // And once we're done - we may close TCP connection to server
  // NOTE: All non-closed requests will die!
  agent.close();
}).end();

Please note that if you use a custom agent, by default all connection-level errors will result in an uncaught exception. To handle these errors subscribe to the error event and re-emit the captured error:

var agent = spdy.createAgent({
  host: 'www.google.com',
  port: 443
}).once('error', function (err) {
  this.emit(err);
});

Push streams

It is possible to initiate PUSH_PROMISE to send content to clients before the client requests it.

spdy.createServer(options, function(req, res) {
  var stream = res.push('/main.js', {
    status: 200, // optional
    method: 'GET', // optional
    request: {
      accept: '*/*'
    },
    response: {
      'content-type': 'application/javascript'
    }
  });
  stream.on('error', function() {
  });
  stream.end('alert("hello from push stream!");');

  res.end('<script src="/main.js"></script>');
}).listen(3000);

PUSH_PROMISE may be sent using the push() method on the current response object. The signature of the push() method is:

.push('/some/relative/url', { request: {...}, response: {...} }, callback)

Second argument contains headers for both PUSH_PROMISE and emulated response. callback will receive two arguments: err (if any error is happened) and a Duplex stream as the second argument.

Client usage:

var agent = spdy.createAgent({ /* ... */ });
var req = http.get({
  host: 'www.google.com',
  agent: agent
}, function(response) {
});
req.on('push', function(stream) {
  stream.on('error', function(err) {
    // Handle error
  });
  // Read data from stream
});

NOTE: You're responsible for the stream object once given it in .push() callback or push event. Hence ignoring error event on it will result in uncaught exception and crash your program.

Trailing headers

Server usage:

function (req, res) {
  // Send trailing headers to client
  res.addTrailers({ header1: 'value1', header2: 'value2' });

  // On client's trailing headers
  req.on('trailers', function(headers) {
    // ...
  });
}

Client usage:

var req = http.request({ agent: spdyAgent, /* ... */ }).function (res) {
  // On server's trailing headers
  res.on('trailers', function(headers) {
    // ...
  });
});
req.write('stuff');
req.addTrailers({ /* ... */ });
req.end();

Options

All options supported by tls work with node-spdy.

Additional options may be passed via spdy sub-object:

  • plain - if defined, server will ignore NPN and ALPN data and choose whether to use spdy or plain http by looking at first data packet.
  • ssl - if false and options.plain is true, http.Server will be used as a base class for created server.
  • maxChunk - if set and non-falsy, limits number of bytes sent in one DATA chunk. Setting it to non-zero value is recommended if you care about interleaving of outgoing data from multiple different streams. (defaults to 8192)
  • protocols - list of NPN/ALPN protocols to use (default is: ['h2','spdy/3.1', 'spdy/3', 'spdy/2','http/1.1', 'http/1.0'])
  • protocol - use specific protocol if no NPN/ALPN ex In addition,
  • maxStreams - set "maximum concurrent streams" protocol option

API

API is compatible with http and https module, but you can use another function as base class for SPDYServer.

spdy.createServer(
  [base class constructor, i.e. https.Server],
  { /* keys and options */ }, // <- the only one required argument
  [request listener]
).listen([port], [host], [callback]);

Request listener will receive two arguments: request and response. They're both instances of http's IncomingMessage and OutgoingMessage. But three custom properties are added to both of them: isSpdy, spdyVersion. isSpdy is true when the request was processed using HTTP2/SPDY protocols, it is false in case of HTTP/1.1 fallback. spdyVersion is either of: 2, 3, 3.1, or 4 (for HTTP2).

Contributors

LICENSE

This software is licensed under the MIT License.

Copyright Fedor Indutny, 2015.

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

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

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

node-spdy's People

Contributors

3rd-eden avatar adammagaluk avatar albertorestifo avatar anandsuresh avatar astorije avatar azat-co avatar bebraw avatar bmeck avatar chrisrauh avatar daviddias avatar e-nomem avatar eee-c avatar emile22 avatar felixsanz avatar francois2metz avatar frank-dspeed avatar guilhermehn avatar halvards avatar igrigorik avatar indutny avatar jacobheun avatar jamescostian avatar jcayzac avatar jessecravens-frog avatar jonathanong avatar lpinca avatar michielbdejong avatar nya3jp avatar ploer avatar rauchg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-spdy's Issues

Object has no method 'createTlsServer'

Greetings,

I am getting the following error:

TypeError: Object # has no method 'createTlsServer'
at Object. (/mnt/eoh/experiments/node_server/server.js:17:6)
at Module._compile (module.js:423:26)
at Object..js (module.js:429:10)
at Module.load (module.js:339:31)
at Function._load (module.js:298:12)
at Array. (module.js:442:10)
at EventEmitter._tickCallback (node.js:175:26)

I'm using node.js 5.0-pre and have installed node-spdy as specified. Anyone got any ideas?

Many thanks in advance,

Eamonn

Server process hangs on quick reload

If i do some consecutive rapid clicks on the reload button in my browser the serversprocess stops responding.
Tried to increase max connections, but nothing changed.

I get no log entries in debug mode.

Parser's performance

Buffer concatenation is slow even if we're doing it on demand.
So good algorithm needs to be created (or probably use external module for chunkified input parsing).

can not connect to spdy server

Hi,
I created a simple spdy server.

 spdy.createServer(keys, @onRequest).listen(3000)

 onRequest : (req, res) =>  # http.ServerRequest and http.
    reqpath = url.parse req.url, true
    Node.log 'request :' + reqpath

On the client side, I just do https.request with the following options.

createClientRequests : () ->
option = {
host: 'localhost',
port: 3000,
path: '/',
method: 'GET',
agent: false,
rejectUnauthorized: false
}

    @clientreq = https.request option, (res) =>
        res.on 'data', (chunk) =>       
            Node.log 'response: ', @name, ' << ', chunk.toString() 

        res.on 'close', () ->           
            Node.log 'server closed connection...'

    @clientreq.on 'connect', (res, socket, head) =>
        Node.log 'client connected....', @name
        @oneRequest()

    @clientreq.on 'error', (e) ->   
        Node.log 'server error...:', e  

I did not see server onRequest() log when I launch client.

However, if I do curl -k https://localhost:3000, I can see server log.
What is the trick here ?

Also, the test/unit/server_test.js, this line is wrong, it is a comma , ; however, tls does not have request.
I am using node 0.8.11

tls = require('tls'),request

Concurrent streams limit

node-spdy should follow google's implementation conventions and send RST_STREAM after exceeding concurrent streams limit given in SETTINGS frame. That should be configurable in .createServer's options

WINDOW_UPDATE + INITIAL_WINDOW_SIZE

While those will be ignored by SPDY clients with version 2, controlling flow is required for implementing per stream .pause() and .resume()

susceptible to BEAST attack

Hmm, perhaps this is not a node-spdy bug, but have a feeling you may have a good lead as to where to direct it...

var spdy = require('spdy'),
    fs = require('fs');

var options = {
  key: fs.readFileSync(__dirname + '/keys/key.pem'),
  cert: fs.readFileSync(__dirname + '/keys/crt.pem'),
  ca: fs.readFileSync(__dirname + '/keys/ca.pem'),
  ciphers: 'ECDHE-RSA-AES256-SHA:AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM',
  honorCipherOrder: true
};

var server = spdy.createServer(options, function(req, res) {
  res.writeHead(200);
  res.end('hello world!');
});

Running above through Qualys SSL labs check reports that the server is still susceptible to BEAST attack.
https://www.ssllabs.com/ssltest/analyze.html?d=www.spdy.io

Hmm, just tried a plain HTTPS node server.. same thing. What the? Am I missing something obvious?

Basic sample issues

I'm trying to simply establish a bare-bones SPDY connection to a server with Chrome, but when ever I try and connect Chrome says an empty response was returned. Below is the code and I'm accessing through Chrome by http://localhost

[Code]
var spdy = require('spdy'),
fs = require('fs');

var server = spdy.createServer({}, function(req, res) {
res.writeHead(200);
res.end('hello world!');
});

server.listen(80);

Problem with spdy if crypt module throws error

I was playing with the crypto module. On part of my app decrypts text. I was testing some error cases and recognised that spdy does not closes the connection properly. The following example works with https module, but not with spdy module. Express error handling method is called, but res.send does not close the connection with spdy properly. The good thing is, that the whole app does not crash.

Try it by switching between https and spdy module.

Error shown on console:
[secureConnection] error Error: 140735268589952:error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length:../deps/openssl/openssl/crypto/evp/evp_enc.c:460:

// load basic packages
var express = require('express');
var https = require('https');
var spdy = require('spdy');
var fs = require("fs");

var port = 4002;
var privateKey = fs.readFileSync('privatekey.pem').toString();
var certificate = fs.readFileSync('certificate.pem').toString();

var options = {
  key: privateKey,
  cert: certificate
};

// session and password salt
var salt = 'sdgfdgdfgdfgdfgdf';

var app = express();

app.configure(function() {

    app.use(express.cookieParser());
    app.use(express.session({
        secret: salt
    }));

    app.use(express.bodyParser());
    app.use(express.methodOverride());

    app.use(app.router);

    // access error
    app.use(function(req, res, next){
      res.status(404);
      // respond with json
      if (req.accepts('json')) {
        res.send({ error: 'Not found' });
        return;
      }
    });

    // all error should be handled here latest
    app.use(function(err, req, res, next){
      // respond with json
      res.send({ error: 'invalid request' });
      return;
    });
});

function decrypter () {
      var cryptText = "abc";
      var assert = require('assert');
      var crypto = require('crypto');
      var Buffer = require('buffer').Buffer;
      var SECRET_KEY = "dsfgdfgdsfgdsfgsdfgfdsgfdsgdsgdsg";
      var ENCODING = 'hex';
      var ALGORITHM = "aes256";

      // decrypt text
      var decipher = crypto.createDecipher(ALGORITHM, SECRET_KEY);
      var decryptedText = decipher.update(cryptText, ENCODING,'utf8');
      decryptedText += decipher.final('utf8');
      return decryptedText;
}

app.get('/', function(req, res, next) {
  var value;
  try {
    value = decrypter();
  } 
  catch(err){
    throw new Error(err);
  }
  res.send(value);
}); 

https.createServer(options, app).listen(port);
//spdy.createServer(options, app).listen(port);

express 3 example

Hi,

I'm trying to run a simple application with SPDY and express3.
It does not trow any error but does not return any response.

var express = require('express'),
    routes = require('./routes'),
    user = require('./routes/user'),
    http = require('http'),
    path = require('path'),
    spdy = require('spdy'),
    fs = require('fs');
var app = express();
var options = {
    key: fs.readFileSync(__dirname + '/keys/spdy-key.pem'),
    cert: fs.readFileSync(__dirname + '/keys/spdy-cert.pem'),
    ca: fs.readFileSync(__dirname + '/keys/spdy-csr.pem')
};
app.configure(function () {
    app.set('port', process.env.PORT || 3000);
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function () {
    app.use(express.errorHandler());
});
app.get('/', routes.index);
app.get('/users', user.list);
var server = spdy.createServer(options, app);
server.listen(8081);

zlibcontext install problem

Hi,

The published version of zlibcontext is broken. Can you publish a new version please ?

npm install zlibcontext
npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm info fetch http://registry.npmjs.org/zlibcontext/-/zlibcontext-1.0.4.tgz
npm info calculating sha1 /tmp/npm-1303465247478/1303465247478-0.25052001723088324/tmp.tgz
npm info shasum 784c5f9e709d72efbbd47d3306ac0e7fabbd930e
npm info calculating sha1 /home/francois/.node_libraries/.npm/.cache/zlibcontext/1.0.4/package.tgz
npm info shasum 3c4153fc57eb37dbd67dcf9abc199a4483160290
npm info preinstall [email protected]
Nothing to clean (project not configured)
Setting srcdir to : /home/francois/.node_libraries/.npm/zlibcontext/1.0.4/package
Setting blddir to : /home/francois/.node_libraries/.npm/zlibcontext/1.0.4/package/build
Checking for program g++ or c++ : /usr/bin/g++
Checking for program cpp : /usr/bin/cpp
Checking for program ar : /usr/bin/ar
Checking for program ranlib : /usr/bin/ranlib
Checking for g++ : ok
Checking for node path : ok /home/francois/dev/node/lib
Checking for node prefix : ok /home/francois/opt
Checking for library z : yes
'configure' finished successfully (0.168s)
Waf: Entering directory /home/donnerjack13589/coding/git/kkaefer/node-zlib/build' Waf: Leaving directory/home/donnerjack13589/coding/git/kkaefer/node-zlib/build'
Traceback (most recent call last):
File "/home/francois/opt/bin/node-waf", line 16, in
Scripting.prepare(t, os.getcwd(), VERSION, wafdir)
File "/home/francois/opt/bin/../lib/node/wafadmin/Scripting.py", line 145, in prepare
prepare_impl(t, cwd, ver, wafdir)
File "/home/francois/opt/bin/../lib/node/wafadmin/Scripting.py", line 135, in prepare_impl
main()
File "/home/francois/opt/bin/../lib/node/wafadmin/Scripting.py", line 188, in main
fun(ctx)
File "/home/francois/opt/bin/../lib/node/wafadmin/Scripting.py", line 386, in build
return build_impl(bld)
File "/home/francois/opt/bin/../lib/node/wafadmin/Scripting.py", line 405, in build_impl
bld.compile()
File "/home/francois/opt/bin/../lib/node/wafadmin/Build.py", line 268, in compile
os.chdir(self.bldnode.abspath())
OSError: [Errno 2] No such file or directory: '/home/donnerjack13589/coding/git/kkaefer/node-zlib/build'
npm info [email protected] Failed to exec preinstall script
npm ERR! install failed Error: [email protected] preinstall: node-waf clean || true; node-waf configure build
npm ERR! install failed sh "-c" "node-waf clean || true; node-waf configure build" failed with 1
npm ERR! install failed at ChildProcess. (/home/francois/.node_libraries/.npm/npm/0.3.18/package/lib/utils/exec.js:49:20)
npm ERR! install failed at ChildProcess.emit (events.js:67:17)
npm ERR! install failed at ChildProcess.onexit (child_process.js:192:12)
npm info install failed rollback
npm info uninstall [ '[email protected]' ]
npm info preuninstall [email protected]
npm info uninstall [email protected]
npm info auto-deactive not symlink
npm info postuninstall [email protected]
npm info uninstall [email protected] complete
npm info install failed rolled back
npm ERR! Error: [email protected] preinstall: node-waf clean || true; node-waf configure build
npm ERR! sh "-c" "node-waf clean || true; node-waf configure build" failed with 1
npm ERR! at ChildProcess. (/home/francois/.node_libraries/.npm/npm/0.3.18/package/lib/utils/exec.js:49:20)
npm ERR! at ChildProcess.emit (events.js:67:17)
npm ERR! at ChildProcess.onexit (child_process.js:192:12)
npm ERR!
npm ERR! Failed at the [email protected] preinstall script.
npm ERR! This is most likely a problem with the zlibcontext package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node-waf clean || true; node-waf configure build
npm ERR! You can get their info via:
npm ERR! npm owner ls zlibcontext
npm ERR! There is likely additional logging output above.
npm ERR! System Linux 2.6.38-2-686-bigmem
npm ERR! argv { remain: [ 'zlibcontext' ],
npm ERR! argv cooked: [ 'install', 'zlibcontext' ],
npm ERR! argv original: [ 'install', 'zlibcontext' ] }
npm not ok

Failed to set dictionary

In Windows (node v0.7.1), running through the "hello world" crashes the process with the follow output:

Assertion failed: err == Z_OK && "Failed to set dictionary", file src\node_zlib.cc, line 338

when hitting https://127.0.0.1:443

Express Sessions not working with SPDY

Hello,

today I tried to setup express with spdy. I set up express-spdy and tried to store something in a session. Unfortunately that didn't work out as expected. We managed to track the bug down to spdy in express.

Consider this rather minimal example. (cf. this)

mkdir issue
cd issue
mkdir keys
npm install express spdy

You may want to generate spdy-key.pem, spdy-csr.pem and spdy-crt.pem in keys/ using

cd ./keys/
openssl genrsa -out spdy-key.pem 4096
openssl req -new -key spdy-key.pem -out spdy-csr.pem
openssl x509 -req -days 3650 -in spdy-csr.pem -signkey spdy-key.pem -out spdy-cert.pem

Then place app.js from the gist in issue and run:

node app.js

Switching the variable spdy in line 1 of app.js toggles the use of https/spdy. Just navigate to localhost:3000 and refresh. You'll only see the number of views increasing only when using https, which means that something in spdy is messed up.

Of course, that's not a basic use of spdy, but I don't have time to dive into the express session code ...

Please keep me updated if you fix this, because I#d really like to use your module :)

spdy-v3 merge?

Is v3 branch ready for merge? Can I start reviewing it?

Res.socket is nil on CONNECT

Trying to figure out what's going here.. For some reason, if I issue a "CONNECT" query against the server, the response object does not have the socket? This fails later when we try to create the SYN_REPLY.

debug> n
< ...writeHead: undefined
break in node_modules/spdy/lib/spdy/response.js:34
 32   console.log('...writeHead: ' + this.socket)
 33 
 34   if (this._headerSent) return;
 35   this._headerSent = true;
 36 
debug> 

Frame example:

<   frame: 
<    { type: 'SYN_STREAM',
<      id: 1,
<      associated: 0,
<      priority: 0,
<      fin: false,
<      unidir: false,
<      _offset: 10,
<      headers: 
<       { host: 'google.com',
<         method: 'CONNECT',
<         path: 'google.com:443',
<         url: 'google.com:443',
<         version: 'HTTP/1.1',
<         'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.0 Safari/537.1' } },
<   writable: true,
<   readable: true }

Any ideas?

failed to make examples/twitlog work

Im trying to make examples twitlog work. when i launch the application, i get the message below. how can i fix that ?

ultimatly i just want a working example of node-spdy, any suggestion of where i can find that ?

/node-spdy/examples/twitlog $ node app.js 
Express server listening on port 8081 in development mode

events.js:50
        throw new Error("Uncaught, unspecified 'error' event.");
        ^
Error: Uncaught, unspecified 'error' event.
    at EventEmitter.emit (events.js:50:15)
    at ClientRequest.<anonymous> (/Users/jerome/Downloads/node-spdy/examples/twitlog/node_modules/ntwitter/lib/twitter.js:251:14)
    at ClientRequest.emit (events.js:67:17)
    at HTTPParser.onIncoming (http.js:1261:11)
    at HTTPParser.onHeadersComplete (http.js:102:31)
    at CleartextStream.ondata (http.js:1150:24)
    at CleartextStream._push (tls.js:375:27)
    at SecurePair.cycle (tls.js:734:20)
    at EncryptedStream.write (tls.js:130:13)
    at Socket.ondata (stream.js:38:26)

Parser's buffer becomes dirty

For some reason (actually, I'd only seen this once) some junk remains in parser after successful frame parsing.
Need to find test case and fix a problem if it wasn't a node.js TLS problem.

New version in NPM

Much has changed in node-spdy since 0.0.1. Can you please publish 0.0.2 to NPM?

SPDY/3

Jo!

Straight implementing the SPDY/3 specs.

Anyone likes to help collecting the minor / major changes in spdy/3 (considering spdy/2)?

Ty,
k.s.

max connection count should be per-side

There should be a separate max connection count for server originated streams and for client-originated streams.
Currently there is just one, and this messes up in conjunction with server push.

zlibcontext does not load

When trying to execute a test, I get :

Error: Cannot find module './zlib_bindings'
at Function._resolveFilename (module.js:320:11)

snooping with dtrace shows that node tries to find a package.json

501 86597 node -1 /usr/local/lib/node_modules/zlibcontext/lib/zlib_bindings/package.json

I am not sure of the proper way to ask node to search for a binary extension.

undefined symbol: ev_rt_now

I'm getting the following error when trying to run the test spdy-server:

hynese@hynese:/home/hynese/spdy# node spdy-server.js

node.js:183
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: /home/hynese/spdy/node_modules/zlibcontext/lib/zlib_bindings.node: undefined symbol: ev_rt_now
at Object..node (module.js:472:11)
at Module.load (module.js:339:31)
at Function._load (module.js:298:12)
at require (module.js:367:19)
at Object. (/home/hynese/spdy/node_modules/zlibcontext/lib/zlib.js:1:88)
at Module._compile (module.js:427:26)
at Object..js (module.js:466:10)
at Module.load (module.js:339:31)
at Function._load (module.js:298:12)
at require (module.js:367:19)

Any insight is greatly appreciated,

SPDY not working on dev code

I can't get the SPDY code to successfully get either Chrome or Firefox to use it over https.

If I change the port to 443, (running as sudo), edit my hosts file to be the same as your domain hosting the sample, and hit that page, it gives the 'Oh, no... your browser requested this page via HTTPS' error, but when I take away the hosts entry and hit your server, it works properly.

What do I need to do different than the current revision of code in the repository?

No remoteAddress in request object

In Geddy we're adding SPDY support and we have a logger that logs all the requests. But when a browser request comes in from SPDY we aren't getting back a request.connection.remoteAddress item, which we are using to log the request IP.

But the remoteAddress exists when you try to curl to the server.

Here's the http version of the code I was using:

var http = require('http');

http.createServer(function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  console.log(req.method + ' ' + req.connection.remoteAddress)
  res.end('Hello ' + req.connection.remoteAddress);
}).listen(3000);

Curling to the server I get this response, same if I go to the address on the browser.

curl localhost:3000 
=> Hello 127.0.0.1

Now here's the SPDY example I was using:

var fs = require('fs')
  , spdy = require('spdy')
  , options = { 
      key: fs.readFileSync('/home/larz/Desktop/server.key')
    , cert: fs.readFileSync('/home/larz/Desktop/server.crt')
  };

spdy.createServer(options, function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  console.log(req.method + ' ' + req.connection.remoteAddress);
  res.end('Hello ' + req.connection.remoteAddress);
}).listen(3000);

Curling to the server this time I get the same thing back

curl -k https://localhost:3000
=> Hello 127.0.0.1

But when I try to go to it via the browser I get "Hello undefined"

Push example issues

I'm trying to get the sample for .push() working but when I run it node returns the error that no method for 'push' exists in the object.

Am I missing something obvious? I feel like I am...

express secure cookies fail

If I set {secure: true} for my cookies when using express.session, no cookies will be passed to the client.

Here's some simple code testing this:

fs = require 'fs'
spdy = require 'spdy'
express = require 'express'

securityOptions = 
    key: fs.readFileSync 'keys/privatekey.pem'
    cert: fs.readFileSync 'keys/certificate.pem'
    ca: fs.readFileSync 'keys/certrequest.csr'

expressServer = express()
expressServer.use express.cookieParser()
expressServer.use express.session
    secret: 'super secret'
    cookie:
        path: '/'
        httpOnly: true
        secure: true  # COMMENT OUT THIS LINE AND THINGS WILL WORK

expressServer.get '/', (request, response) ->
    headers = 'content-type': 'application/javascript'
    response.push '/main.js', headers, (error, stream) ->
        throw error if error?
        stream.end 'alert("hello from push stream!");'
    response.end '<script src="/main.js"></script>'

server = spdy.createServer securityOptions, expressServer
server.listen 10443

console.log 'started server'

Long term running

While testing under load for a long term, I'd found that my server crashed.

So task is: collect logs, try to emulate situation and fix problem.

parser.js chunk has no method copy

[TypeError: Object # has no method 'copy']
TypeError: Object # has no method 'copy'
at Parser.write (node_modules/spdy/lib/spdy/parser.js:85:13)
at CleartextStream.ondata (stream.js:38:26)
at CleartextStream.EventEmitter.emit (events.js:126:20)
at CleartextStream.CryptoStream._push (tls.js:522:12)
at SecurePair.cycle (tls.js:880:20)
at EncryptedStream.CryptoStream.write (tls.js:267:13)
at Socket.ondata (stream.js:38:26)
at Socket.EventEmitter.emit (events.js:96:17)

the src is here: chunk should be buffer[sliced], should be data. Not sure why it becomes ClearTextSream.

51 Parser.prototype.write = function write(data) {
52 if (data !== undefined) {
53 // Buffer data
54 this.buffer.push(data);
55 this.buffered += data.length;
56 }
57
58 // Notify caller about state (for piping)
59 if (this.paused) return false;
60
61 // We shall not do anything until we get all expected data
62 if (this.buffered < this.waiting) return;
63
64 // Mark parser as not drained
65 if (data !== undefined) this.drained = false;
66
67 var self = this,
68 buffer = new Buffer(this.waiting),
69 sliced = 0,
70 offset = 0;
71
72 while (this.waiting > offset && sliced < this.buffer.length) {
73 var chunk = this.buffer[sliced++],
74 overmatched = false;
75
76 // Copy chunk into buffer
77 if (chunk.length > this.waiting - offset) {
78 chunk.copy(buffer, offset, 0, this.waiting - offset);
79
80 this.buffer[--sliced] = chunk.slice(this.waiting - offset);
81 this.buffered += this.buffer[sliced].length;
82
83 overmatched = true;
84 } else {
85 chunk.copy(buffer, offset);
86 }

SPDY example should work out of the box

looks like express isn't working yet with v0.7


ryan@ryan-ThinkPad-X201:~/src/example% node -v
v0.7.12-pre
ryan@ryan-ThinkPad-X201:~/src/example% npm -v
1.1.26
ryan@ryan-ThinkPad-X201:~/src/example% pwd         
/home/ryan/src/example
ryan@ryan-ThinkPad-X201:~/src/example% npm install spdy
[email protected] node_modules/spdy
ryan@ryan-ThinkPad-X201:~/src/example% ls
node_modules
ryan@ryan-ThinkPad-X201:~/src/example% cd node_modules/spdy/examples/twitlog 
ryan@ryan-ThinkPad-X201:.../spdy/examples/twitlog% ls
app.js  autorestart.js  keys  package.json  public  realtime  routes  views
ryan@ryan-ThinkPad-X201:.../spdy/examples/twitlog% npm install
npm ERR! Error: No compatible version found: express@'>=2.5.0- <2.6.0-'
npm ERR! Valid install targets:
npm ERR! ["0.14.0","0.14.1","1.0.0beta","1.0.0beta2","1.0.0rc","1.0.0rc2","1.0.0rc3","1.0.0rc4","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.0.5","1.0.6","1.0.7","3.0.0alpha3","3.0.0alpha4","3.0.0alpha5","3.0.0beta1","3.0.0beta2","3.0.0beta3"]
npm ERR!     at installTargetsError (/home/ryan/local/node/lib/node_modules/npm/lib/cache.js:506:10)
npm ERR!     at next_ (/home/ryan/local/node/lib/node_modules/npm/lib/cache.js:452:17)
npm ERR!     at next (/home/ryan/local/node/lib/node_modules/npm/lib/cache.js:427:44)
npm ERR!     at /home/ryan/local/node/lib/node_modules/npm/lib/cache.js:419:5
npm ERR!     at saved (/home/ryan/local/node/lib/node_modules/npm/node_modules/npm-registry-client/lib/get.js:136:7)
npm ERR!     at /home/ryan/local/node/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:230:7
npm ERR!     at Object.oncomplete (fs.js:297:15)
npm ERR!  [Error: No compatible version found: express@'>=2.5.0- <2.6.0-'
npm ERR! Valid install targets:
npm ERR! ["0.14.0","0.14.1","1.0.0beta","1.0.0beta2","1.0.0rc","1.0.0rc2","1.0.0rc3","1.0.0rc4","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.0.5","1.0.6","1.0.7","3.0.0alpha3","3.0.0alpha4","3.0.0alpha5","3.0.0beta1","3.0.0beta2","3.0.0beta3"]]
npm ERR! You may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <[email protected]>

npm ERR! System Linux 3.2.0-24-generic
npm ERR! command "/home/ryan/local/node/bin/node" "/home/ryan/local/node/bin/npm" "install"
npm ERR! cwd /home/ryan/src/example/node_modules/spdy/examples/twitlog
npm ERR! node -v v0.7.12-pre
npm ERR! npm -v 1.1.26
npm ERR! message No compatible version found: express@'>=2.5.0- <2.6.0-'
npm ERR! message Valid install targets:
npm ERR! message ["0.14.0","0.14.1","1.0.0beta","1.0.0beta2","1.0.0rc","1.0.0rc2","1.0.0rc3","1.0.0rc4","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.0.5","1.0.6","1.0.7","3.0.0alpha3","3.0.0alpha4","3.0.0alpha5","3.0.0beta1","3.0.0beta2","3.0.0beta3"]
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /home/ryan/src/example/node_modules/spdy/examples/twitlog/npm-debug.log
npm ERR! not ok code 0
-1- ryan@ryan-ThinkPad-X201:.../spdy/examples/twitlog% 

cc @visionmedia

Error in SPDY Implementation

Hi Fedor,

I deployed a proxy server powered by node-spdy and tested it with Chrome and everything works great. After that I tested it with Firefox 11 (which now has SPDY but disabled). I enabled SPDY and tried it against the node-spdy proxy. The server that is being proxied used the "Transfer-Encoding: chunked" header and did not provide a "Content-Length" header, which made Firefox Croak.

I then filed a bug with Firefox, but the guys there pointed me at the SPDY specification which states that: Chunked encodings in spdy/2 are not valid.

The question then arises at which level this needs to be fixed. Mozilla obviously is of the opinion that the specification is king, so they will not fix it in the browser. On the other hand, I can't ask the downstream server to avoid chunked encoding, since I may not even be mine. So there remain 2 possible places:

  1. The proxy (I use node-proxy for this)
  2. The SPDY Implementation (node-spdy)

I personally think that node-spdy would be the right place to do this. Since it has the same general properties as the built in HTTPS server and the adoption will only ever happen if it is trivial to use this via node. This is also the reason that the built in HTTP server does the same when the HTTP version of the client is below 1.1.

Basic research has shown me that since I don't know the content-length at the time of writeHead() I would need to intercept that call and then buffer the result that is written by write() and then tally the total-length on end() and set "Transfer-Encoding: identity" and "Content-Length". Then writeHead() for real and write() all the chunks and call end();

The only disadvantage of this approach is that I need to buffer the entire reply, which may be a lot of memory if there are a lot of requests.

The question is are you interested in me creating a patch that does this and are there any guidelines you want to apply if you do.

Regards,
Phil

Roadmap

Could you sketch up a roadmap with future implementation details and what's already been done. Would be much easier
for us outsiders to track your actual progress :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.