| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 | /* eslint-env mocha */var assert = require('assert')var tls = require('tls')var net = require('net')var https = require('https')var transport = require('spdy-transport')var util = require('util')var fixtures = require('./fixtures')var spdy = require('../')describe('SPDY Server', function () {  fixtures.everyConfig(function (protocol, alpn, version, plain) {    var server    var client    beforeEach(function (done) {      server = spdy.createServer(Object.assign({        spdy: {          'x-forwarded-for': true,          plain: plain        }      }, fixtures.keys))      server.listen(fixtures.port, function () {        var socket = (plain ? net : tls).connect({          rejectUnauthorized: false,          port: fixtures.port,          ALPNProtocols: [alpn]        }, function () {          client = transport.connection.create(socket, {            protocol: protocol,            isServer: false          })          client.start(version)          done()        })      })    })    afterEach(function (done) {      client.socket.destroy()      server.close(done)    })    it('should process GET request', function (done) {      var stream = client.request({        method: 'GET',        path: '/get',        headers: {          a: 'b'        }      }, function (err) {        assert(!err)        stream.on('error', (err) => {          done(err)        })        stream.on('response', function (status, headers) {          assert.strictEqual(status, 200)          assert.strictEqual(headers.ok, 'yes')          fixtures.expectData(stream, 'response', done)        })        stream.end()      })      server.on('request', function (req, res) {        assert.strictEqual(req.isSpdy, res.isSpdy)        assert.strictEqual(req.spdyVersion, res.spdyVersion)        assert(req.isSpdy)        if (!plain) {          assert(req.socket.encrypted)          assert(req.socket.getPeerCertificate())        }        // Auto-detection        if (version === 3.1) {          assert(req.spdyVersion >= 3 && req.spdyVersion <= 3.1)        } else {          assert.strictEqual(req.spdyVersion, version)        }        assert(req.spdyStream)        assert(res.spdyStream)        assert.strictEqual(req.method, 'GET')        assert.strictEqual(req.url, '/get')        assert.deepStrictEqual(req.headers, { a: 'b', host: 'localhost' })        req.on('end', function () {          res.writeHead(200, {            ok: 'yes'          })          res.end('response')          assert(res.finished, 'res.finished should be set')        })        req.resume()      })    })    it('should process POST request', function (done) {      var stream = client.request({        method: 'POST',        path: '/post'      }, function (err) {        assert(!err)        stream.on('response', function (status, headers) {          assert.strictEqual(status, 200)          assert.strictEqual(headers.ok, 'yes')          fixtures.expectData(stream, 'response', next)        })        stream.end('request')      })      server.on('request', function (req, res) {        assert.strictEqual(req.method, 'POST')        assert.strictEqual(req.url, '/post')        res.writeHead(200, {          ok: 'yes'        })        res.end('response')        fixtures.expectData(req, 'request', next)      })      var waiting = 2      function next () {        if (--waiting === 0) {          return done()        }      }    })    it('should process expect-continue request', function (done) {      var stream = client.request({        method: 'GET',        path: '/get',        headers: {          Expect: '100-continue'        }      }, function (err) {        assert(!err)        stream.on('response', function (status, headers) {          assert.strictEqual(status, 100)          fixtures.expectData(stream, 'response', done)        })        stream.end()      })      server.on('request', function (req, res) {        req.on('end', function () {          res.end('response')        })        req.resume()      })    })    it('should emit `checkContinue` request', function (done) {      var stream = client.request({        method: 'GET',        path: '/get',        headers: {          Expect: '100-continue'        }      }, function (err) {        assert(!err)        stream.on('response', function (status, headers) {          assert.strictEqual(status, 100)          fixtures.expectData(stream, 'response', done)        })        stream.end()      })      server.on('checkContinue', function (req, res) {        req.on('end', function () {          res.writeContinue()          res.end('response')        })        req.resume()      })    })    it('should send PUSH_PROMISE', function (done) {      var stream = client.request({        method: 'POST',        path: '/page'      }, function (err) {        assert(!err)        stream.on('pushPromise', function (push) {          assert.strictEqual(push.path, '/push')          assert.strictEqual(push.headers.yes, 'push')          fixtures.expectData(push, 'push', next)          fixtures.expectData(stream, 'response', next)        })        stream.end('request')      })      server.on('request', function (req, res) {        assert.strictEqual(req.method, 'POST')        assert.strictEqual(req.url, '/page')        res.writeHead(200, {          ok: 'yes'        })        var push = res.push('/push', {          request: {            yes: 'push'          }        })        push.end('push')        res.end('response')        fixtures.expectData(req, 'request', next)      })      var waiting = 3      function next () {        if (--waiting === 0) {          return done()        }      }    })    it('should receive trailing headers', function (done) {      var stream = client.request({        method: 'POST',        path: '/post'      }, function (err) {        assert(!err)        stream.sendHeaders({ trai: 'ler' })        stream.end()        stream.on('response', function (status, headers) {          assert.strictEqual(status, 200)          assert.strictEqual(headers.ok, 'yes')          fixtures.expectData(stream, 'response', done)        })      })      server.on('request', function (req, res) {        var gotHeaders = false        req.on('trailers', function (headers) {          gotHeaders = true          assert.strictEqual(headers.trai, 'ler')        })        req.on('end', function () {          assert(gotHeaders)          res.writeHead(200, {            ok: 'yes'          })          res.end('response')        })        req.resume()      })    })    it('should call .writeHead() automatically', function (done) {      var stream = client.request({        method: 'POST',        path: '/post'      }, function (err) {        assert(!err)        stream.on('response', function (status, headers) {          assert.strictEqual(status, 300)          fixtures.expectData(stream, 'response', done)        })        stream.end()      })      server.on('request', function (req, res) {        req.on('end', function () {          res.statusCode = 300          res.end('response')        })        req.resume()      })    })    it('should not crash on .writeHead() after socket close', function (done) {      var stream = client.request({        method: 'POST',        path: '/post'      }, function (err) {        assert(!err)        setTimeout(function () {          client.socket.destroy()        }, 50)        stream.on('error', function () {})        stream.end()      })      server.on('request', function (req, res) {        req.connection.on('close', function () {          assert.doesNotThrow(function () {            res.writeHead(200)            res.end('response')          })          done()        })      })    })    it('should not crash on .push() after socket close', function (done) {      var stream = client.request({        method: 'POST',        path: '/post'      }, function (err) {        assert(!err)        setTimeout(function () {          client.socket.destroy()        }, 50)        stream.on('error', function () {})        stream.end()      })      server.on('request', function (req, res) {        req.connection.on('close', function () {          assert.doesNotThrow(function () {            assert.strictEqual(res.push('/push', {}), undefined)            res.end('response')          })          done()        })      })    })    it('should end response after writing everything down', function (done) {      var stream = client.request({        method: 'GET',        path: '/post'      }, function (err) {        assert(!err)        stream.on('response', function (status, headers) {          assert.strictEqual(status, 200)          fixtures.expectData(stream, 'hello world, what\'s up?', done)        })        stream.end()      })      server.on('request', function (req, res) {        req.resume()        res.writeHead(200)        res.write('hello ')        res.write('world')        res.write(', what\'s')        res.write(' up?')        res.end()      })    })    it('should handle x-forwarded-for', function (done) {      client.sendXForwardedFor('1.2.3.4')      var stream = client.request({        method: 'GET',        path: '/post'      }, function (err) {        assert(!err)        stream.resume()        stream.on('end', done)        stream.end()      })      server.on('request', function (req, res) {        assert.strictEqual(req.headers['x-forwarded-for'], '1.2.3.4')        req.resume()        res.end()      })    })    it('should destroy request after end', function (done) {      var stream = client.request({        method: 'POST',        path: '/post'      }, function (err) {        assert(!err)      })      stream.end()      stream.on('error', function () {})      server.on('request', function (req, res) {        res.end()        res.destroy()        res.socket.on('close', function () {          done()        })      })    })  })  it('should respond to http/1.1', function (done) {    var server = spdy.createServer(fixtures.keys, function (req, res) {      assert.strictEqual(req.isSpdy, res.isSpdy)      assert.strictEqual(req.spdyVersion, res.spdyVersion)      assert(!req.isSpdy)      assert.strictEqual(req.spdyVersion, 1)      res.writeHead(200)      res.end()    })    server.listen(fixtures.port, function () {      var req = https.request({        agent: false,        rejectUnauthorized: false,        NPNProtocols: ['http/1.1'],        port: fixtures.port,        method: 'GET',        path: '/'      }, function (res) {        assert.strictEqual(res.statusCode, 200)        res.resume()        res.on('end', function () {          server.close(done)        })      })      req.end()    })  })  it('should support custom base', function (done) {    function Pseuver (options, listener) {      https.Server.call(this, options, listener)    }    util.inherits(Pseuver, https.Server)    var server = spdy.createServer(Pseuver, fixtures.keys, function (req, res) {      assert.strictEqual(req.isSpdy, res.isSpdy)      assert.strictEqual(req.spdyVersion, res.spdyVersion)      assert(!req.isSpdy)      assert.strictEqual(req.spdyVersion, 1)      res.writeHead(200)      res.end()    })    server.listen(fixtures.port, function () {      var req = https.request({        agent: false,        rejectUnauthorized: false,        NPNProtocols: ['http/1.1'],        port: fixtures.port,        method: 'GET',        path: '/'      }, function (res) {        assert.strictEqual(res.statusCode, 200)        res.resume()        res.on('end', function () {          server.close(done)        })      })      req.end()    })  })})
 |