Index: frontend/node_modules/spdy/lib/spdy.js
===================================================================
--- frontend/node_modules/spdy/lib/spdy.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/spdy/lib/spdy.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+'use strict'
+
+var spdy = exports
+
+// Export tools
+spdy.handle = require('./spdy/handle')
+spdy.request = require('./spdy/request')
+spdy.response = require('./spdy/response')
+spdy.Socket = require('./spdy/socket')
+
+// Export client
+spdy.agent = require('./spdy/agent')
+spdy.Agent = spdy.agent.Agent
+spdy.createAgent = spdy.agent.create
+
+// Export server
+spdy.server = require('./spdy/server')
+spdy.Server = spdy.server.Server
+spdy.PlainServer = spdy.server.PlainServer
+spdy.createServer = spdy.server.create
Index: frontend/node_modules/spdy/lib/spdy/agent.js
===================================================================
--- frontend/node_modules/spdy/lib/spdy/agent.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/spdy/lib/spdy/agent.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,295 @@
+'use strict'
+
+var assert = require('assert')
+var http = require('http')
+var https = require('https')
+var net = require('net')
+var util = require('util')
+var transport = require('spdy-transport')
+var debug = require('debug')('spdy:client')
+
+// Node.js 0.10 and 0.12 support
+Object.assign = process.versions.modules >= 46
+  ? Object.assign // eslint-disable-next-line
+  : util._extend
+
+var EventEmitter = require('events').EventEmitter
+
+var spdy = require('../spdy')
+
+var mode = /^v0\.8\./.test(process.version)
+  ? 'rusty'
+  : /^v0\.(9|10)\./.test(process.version)
+    ? 'old'
+    : /^v0\.12\./.test(process.version)
+      ? 'normal'
+      : 'modern'
+
+var proto = {}
+
+function instantiate (base) {
+  function Agent (options) {
+    this._init(base, options)
+  }
+  util.inherits(Agent, base)
+
+  Agent.create = function create (options) {
+    return new Agent(options)
+  }
+
+  Object.keys(proto).forEach(function (key) {
+    Agent.prototype[key] = proto[key]
+  })
+
+  return Agent
+}
+
+proto._init = function _init (base, options) {
+  base.call(this, options)
+
+  var state = {}
+  this._spdyState = state
+
+  state.host = options.host
+  state.options = options.spdy || {}
+  state.secure = this instanceof https.Agent
+  state.fallback = false
+  state.createSocket = this._getCreateSocket()
+  state.socket = null
+  state.connection = null
+
+  // No chunked encoding
+  this.keepAlive = false
+
+  var self = this
+  this._connect(options, function (err, connection) {
+    if (err) {
+      return self.emit('error', err)
+    }
+
+    state.connection = connection
+    self.emit('_connect')
+  })
+}
+
+proto._getCreateSocket = function _getCreateSocket () {
+  // Find super's `createSocket` method
+  var createSocket
+  var cons = this.constructor.super_
+  do {
+    createSocket = cons.prototype.createSocket
+
+    if (cons.super_ === EventEmitter || !cons.super_) {
+      break
+    }
+    cons = cons.super_
+  } while (!createSocket)
+  if (!createSocket) {
+    createSocket = http.Agent.prototype.createSocket
+  }
+
+  assert(createSocket, '.createSocket() method not found')
+
+  return createSocket
+}
+
+proto._connect = function _connect (options, callback) {
+  var self = this
+  var state = this._spdyState
+
+  var protocols = state.options.protocols || [
+    'h2',
+    'spdy/3.1', 'spdy/3', 'spdy/2',
+    'http/1.1', 'http/1.0'
+  ]
+
+  // TODO(indutny): reconnect automatically?
+  var socket = this.createConnection(Object.assign({
+    NPNProtocols: protocols,
+    ALPNProtocols: protocols,
+    servername: options.servername || options.host
+  }, options))
+  state.socket = socket
+
+  socket.setNoDelay(true)
+
+  function onError (err) {
+    return callback(err)
+  }
+  socket.on('error', onError)
+
+  socket.on(state.secure ? 'secureConnect' : 'connect', function () {
+    socket.removeListener('error', onError)
+
+    var protocol
+    if (state.secure) {
+      protocol = socket.npnProtocol ||
+                 socket.alpnProtocol ||
+                 state.options.protocol
+    } else {
+      protocol = state.options.protocol
+    }
+
+    // HTTP server - kill socket and switch to the fallback mode
+    if (!protocol || protocol === 'http/1.1' || protocol === 'http/1.0') {
+      debug('activating fallback')
+      socket.destroy()
+      state.fallback = true
+      return
+    }
+
+    debug('connected protocol=%j', protocol)
+    var connection = transport.connection.create(socket, Object.assign({
+      protocol: /spdy/.test(protocol) ? 'spdy' : 'http2',
+      isServer: false
+    }, state.options.connection || {}))
+
+    // Pass connection level errors are passed to the agent.
+    connection.on('error', function (err) {
+      self.emit('error', err)
+    })
+
+    // Set version when we are certain
+    if (protocol === 'h2') {
+      connection.start(4)
+    } else if (protocol === 'spdy/3.1') {
+      connection.start(3.1)
+    } else if (protocol === 'spdy/3') {
+      connection.start(3)
+    } else if (protocol === 'spdy/2') {
+      connection.start(2)
+    } else {
+      socket.destroy()
+      callback(new Error('Unexpected protocol: ' + protocol))
+      return
+    }
+
+    if (state.options['x-forwarded-for'] !== undefined) {
+      connection.sendXForwardedFor(state.options['x-forwarded-for'])
+    }
+
+    callback(null, connection)
+  })
+}
+
+proto._createSocket = function _createSocket (req, options, callback) {
+  var state = this._spdyState
+  if (state.fallback) { return state.createSocket(req, options) }
+
+  var handle = spdy.handle.create(null, null, state.socket)
+
+  var socketOptions = {
+    handle: handle,
+    allowHalfOpen: true
+  }
+
+  var socket
+  if (state.secure) {
+    socket = new spdy.Socket(state.socket, socketOptions)
+  } else {
+    socket = new net.Socket(socketOptions)
+  }
+
+  handle.assignSocket(socket)
+  handle.assignClientRequest(req)
+
+  // Create stream only once `req.end()` is called
+  var self = this
+  handle.once('needStream', function () {
+    if (state.connection === null) {
+      self.once('_connect', function () {
+        handle.setStream(self._createStream(req, handle))
+      })
+    } else {
+      handle.setStream(self._createStream(req, handle))
+    }
+  })
+
+  // Yes, it is in reverse
+  req.on('response', function (res) {
+    handle.assignRequest(res)
+  })
+  handle.assignResponse(req)
+
+  // Handle PUSH
+  req.addListener('newListener', spdy.request.onNewListener)
+
+  // For v0.8
+  socket.readable = true
+  socket.writable = true
+
+  if (callback) {
+    return callback(null, socket)
+  }
+
+  return socket
+}
+
+if (mode === 'modern' || mode === 'normal') {
+  proto.createSocket = proto._createSocket
+} else {
+  proto.createSocket = function createSocket (name, host, port, addr, req) {
+    var state = this._spdyState
+    if (state.fallback) {
+      return state.createSocket(name, host, port, addr, req)
+    }
+
+    return this._createSocket(req, {
+      host: host,
+      port: port
+    })
+  }
+}
+
+proto._createStream = function _createStream (req, handle) {
+  var state = this._spdyState
+
+  var self = this
+  return state.connection.reserveStream({
+    method: req.method,
+    path: req.path,
+    headers: req._headers,
+    host: state.host
+  }, function (err, stream) {
+    if (err) {
+      return self.emit('error', err)
+    }
+
+    stream.on('response', function (status, headers) {
+      handle.emitResponse(status, headers)
+    })
+  })
+}
+
+// Public APIs
+
+proto.close = function close (callback) {
+  var state = this._spdyState
+
+  if (state.connection === null) {
+    this.once('_connect', function () {
+      this.close(callback)
+    })
+    return
+  }
+
+  state.connection.end(callback)
+}
+
+exports.Agent = instantiate(https.Agent)
+exports.PlainAgent = instantiate(http.Agent)
+
+exports.create = function create (base, options) {
+  if (typeof base === 'object') {
+    options = base
+    base = null
+  }
+
+  if (base) {
+    return instantiate(base).create(options)
+  }
+
+  if (options.spdy && options.spdy.plain) {
+    return exports.PlainAgent.create(options)
+  } else { return exports.Agent.create(options) }
+}
Index: frontend/node_modules/spdy/lib/spdy/handle.js
===================================================================
--- frontend/node_modules/spdy/lib/spdy/handle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/spdy/lib/spdy/handle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,247 @@
+'use strict'
+
+var assert = require('assert')
+var thing = require('handle-thing')
+var httpDeceiver = require('http-deceiver')
+var util = require('util')
+
+function Handle (options, stream, socket) {
+  var state = {}
+  this._spdyState = state
+
+  state.options = options || {}
+
+  state.stream = stream
+  state.socket = null
+  state.rawSocket = socket || stream.connection.socket
+  state.deceiver = null
+  state.ending = false
+
+  var self = this
+  thing.call(this, stream, {
+    getPeerName: function () {
+      return self._getPeerName()
+    },
+    close: function (callback) {
+      return self._closeCallback(callback)
+    }
+  })
+
+  if (!state.stream) {
+    this.on('stream', function (stream) {
+      state.stream = stream
+    })
+  }
+}
+util.inherits(Handle, thing)
+module.exports = Handle
+
+Handle.create = function create (options, stream, socket) {
+  return new Handle(options, stream, socket)
+}
+
+Handle.prototype._getPeerName = function _getPeerName () {
+  var state = this._spdyState
+
+  if (state.rawSocket._getpeername) {
+    return state.rawSocket._getpeername()
+  }
+
+  return null
+}
+
+Handle.prototype._closeCallback = function _closeCallback (callback) {
+  var state = this._spdyState
+  var stream = state.stream
+
+  if (state.ending) {
+    // The .end() method of the stream may be called by us or by the
+    // .shutdown() method in our super-class. If the latter has already been
+    // called, then calling the .end() method below will have no effect, with
+    // the result that the callback will never get executed, leading to an ever
+    // so subtle memory leak.
+    if (stream._writableState.finished) {
+      // NOTE: it is important to call `setImmediate` instead of `nextTick`,
+      // since this is how regular `handle.close()` works in node.js core.
+      //
+      // Using `nextTick` will lead to `net.Socket` emitting `close` before
+      // `end` on UV_EOF. This results in aborted request without `end` event.
+      setImmediate(callback)
+    } else if (stream._writableState.ending) {
+      stream.once('finish', function () {
+        callback(null)
+      })
+    } else {
+      stream.end(callback)
+    }
+  } else {
+    stream.abort(callback)
+  }
+
+  // Only a single end is allowed
+  state.ending = false
+}
+
+Handle.prototype.getStream = function getStream (callback) {
+  var state = this._spdyState
+
+  if (!callback) {
+    assert(state.stream)
+    return state.stream
+  }
+
+  if (state.stream) {
+    process.nextTick(function () {
+      callback(state.stream)
+    })
+    return
+  }
+
+  this.on('stream', callback)
+}
+
+Handle.prototype.assignSocket = function assignSocket (socket, options) {
+  var state = this._spdyState
+
+  state.socket = socket
+  state.deceiver = httpDeceiver.create(socket, options)
+
+  function onStreamError (err) {
+    state.socket.emit('error', err)
+  }
+
+  this.getStream(function (stream) {
+    stream.on('error', onStreamError)
+  })
+}
+
+Handle.prototype.assignClientRequest = function assignClientRequest (req) {
+  var state = this._spdyState
+  var oldEnd = req.end
+  var oldSend = req._send
+
+  // Catch the headers before request will be sent
+  var self = this
+
+  // For old nodes
+  if (thing.mode !== 'modern') {
+    req.end = function end () {
+      this.end = oldEnd
+
+      this._send('')
+
+      return this.end.apply(this, arguments)
+    }
+  }
+
+  req._send = function send (data) {
+    this._headerSent = true
+
+    // for v0.10 and below, otherwise it will set `hot = false` and include
+    // headers in first write
+    this._header = 'ignore me'
+
+    // To prevent exception
+    this.connection = state.socket
+
+    // It is very important to leave this here, otherwise it will be executed
+    // on a next tick, after `_send` will perform write
+    self.getStream(function (stream) {
+      if (!stream.connection._isGoaway(stream.id)) {
+        stream.send()
+      }
+    })
+
+    // We are ready to create stream
+    self.emit('needStream')
+
+    // Ensure that the connection is still ok to use
+    if (state.stream && state.stream.connection._isGoaway(state.stream.id)) {
+      return
+    }
+
+    req._send = oldSend
+
+    // Ignore empty writes
+    if (req.method === 'GET' && data.length === 0) {
+      return
+    }
+
+    return req._send.apply(this, arguments)
+  }
+
+  // No chunked encoding
+  req.useChunkedEncodingByDefault = false
+
+  req.on('finish', function () {
+    req.socket.end()
+  })
+}
+
+Handle.prototype.assignRequest = function assignRequest (req) {
+  // Emit trailing headers
+  this.getStream(function (stream) {
+    stream.on('headers', function (headers) {
+      req.emit('trailers', headers)
+    })
+  })
+}
+
+Handle.prototype.assignResponse = function assignResponse (res) {
+  var self = this
+
+  res.addTrailers = function addTrailers (headers) {
+    self.getStream(function (stream) {
+      stream.sendHeaders(headers)
+    })
+  }
+}
+
+Handle.prototype._transformHeaders = function _transformHeaders (kind, headers) {
+  var state = this._spdyState
+
+  var res = {}
+  var keys = Object.keys(headers)
+
+  if (kind === 'request' && state.options['x-forwarded-for']) {
+    var xforwarded = state.stream.connection.getXForwardedFor()
+    if (xforwarded !== null) {
+      res['x-forwarded-for'] = xforwarded
+    }
+  }
+
+  for (var i = 0; i < keys.length; i++) {
+    var key = keys[i]
+    var value = headers[key]
+
+    if (key === ':authority') {
+      res.host = value
+    }
+    if (/^:/.test(key)) {
+      continue
+    }
+
+    res[key] = value
+  }
+  return res
+}
+
+Handle.prototype.emitRequest = function emitRequest () {
+  var state = this._spdyState
+  var stream = state.stream
+
+  state.deceiver.emitRequest({
+    method: stream.method,
+    path: stream.path,
+    headers: this._transformHeaders('request', stream.headers)
+  })
+}
+
+Handle.prototype.emitResponse = function emitResponse (status, headers) {
+  var state = this._spdyState
+
+  state.deceiver.emitResponse({
+    status: status,
+    headers: this._transformHeaders('response', headers)
+  })
+}
Index: frontend/node_modules/spdy/lib/spdy/request.js
===================================================================
--- frontend/node_modules/spdy/lib/spdy/request.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/spdy/lib/spdy/request.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,33 @@
+'use strict'
+
+function attachPush (req) {
+  var handle = req.socket._handle
+
+  handle.getStream(function (stream) {
+    stream.on('pushPromise', function (push) {
+      req.emit('push', push)
+    })
+  })
+}
+
+exports.onNewListener = function onNewListener (type) {
+  var req = this
+
+  if (type !== 'push') {
+    return
+  }
+
+  // Not first listener
+  if (req.listeners('push').length !== 0) {
+    return
+  }
+
+  if (!req.socket) {
+    req.on('socket', function () {
+      attachPush(req)
+    })
+    return
+  }
+
+  attachPush(req)
+}
Index: frontend/node_modules/spdy/lib/spdy/response.js
===================================================================
--- frontend/node_modules/spdy/lib/spdy/response.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/spdy/lib/spdy/response.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,100 @@
+'use strict'
+
+// NOTE: Mostly copy paste from node
+exports.writeHead = function writeHead (statusCode, reason, obj) {
+  var headers
+
+  if (typeof reason === 'string') {
+    // writeHead(statusCode, reasonPhrase[, headers])
+    this.statusMessage = reason
+  } else {
+    // writeHead(statusCode[, headers])
+    this.statusMessage =
+      this.statusMessage || 'unknown'
+    obj = reason
+  }
+  this.statusCode = statusCode
+
+  if (this._headers) {
+    // Slow-case: when progressive API and header fields are passed.
+    if (obj) {
+      var keys = Object.keys(obj)
+      for (var i = 0; i < keys.length; i++) {
+        var k = keys[i]
+        if (k) this.setHeader(k, obj[k])
+      }
+    }
+    // only progressive api is used
+    headers = this._renderHeaders()
+  } else {
+    // only writeHead() called
+    headers = obj
+  }
+
+  if (statusCode === 204 || statusCode === 304 ||
+      (statusCode >= 100 && statusCode <= 199)) {
+    // RFC 2616, 10.2.5:
+    // The 204 response MUST NOT include a message-body, and thus is always
+    // terminated by the first empty line after the header fields.
+    // RFC 2616, 10.3.5:
+    // The 304 response MUST NOT contain a message-body, and thus is always
+    // terminated by the first empty line after the header fields.
+    // RFC 2616, 10.1 Informational 1xx:
+    // This class of status code indicates a provisional response,
+    // consisting only of the Status-Line and optional headers, and is
+    // terminated by an empty line.
+    this._hasBody = false
+  }
+
+  // don't keep alive connections where the client expects 100 Continue
+  // but we sent a final status; they may put extra bytes on the wire.
+  if (this._expect_continue && !this._sent100) {
+    this.shouldKeepAlive = false
+  }
+
+  // Implicit headers sent!
+  this._header = true
+  this._headerSent = true
+
+  if (this.socket._handle) { this.socket._handle._spdyState.stream.respond(this.statusCode, headers) }
+}
+
+exports.end = function end (data, encoding, callback) {
+  if (!this._headerSent) {
+    this.writeHead(this.statusCode)
+  }
+
+  if (!this.socket._handle) {
+    return
+  }
+
+  // Compatibility with Node.js core
+  this.finished = true
+
+  var self = this
+  var handle = this.socket._handle
+  handle._spdyState.ending = true
+  this.socket.end(data, encoding, function () {
+    self.constructor.prototype.end.call(self, '', 'utf8', callback)
+  })
+}
+
+exports.push = function push (path, headers, callback) {
+  var frame = {
+    path: path,
+    method: headers.method ? headers.method.toString() : 'GET',
+    status: headers.status ? parseInt(headers.status, 10) : 200,
+    host: this._req.headers.host,
+    headers: headers.request,
+    response: headers.response
+  }
+
+  var stream = this.spdyStream
+  return stream.pushPromise(frame, callback)
+}
+
+exports.writeContinue = function writeContinue (callback) {
+  if (this.socket._handle) {
+    this.socket._handle._spdyState.stream.respond(100, {}, callback)
+  }
+}
Index: frontend/node_modules/spdy/lib/spdy/server.js
===================================================================
--- frontend/node_modules/spdy/lib/spdy/server.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/spdy/lib/spdy/server.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,288 @@
+'use strict'
+
+var assert = require('assert')
+var https = require('https')
+var http = require('http')
+var tls = require('tls')
+var net = require('net')
+var util = require('util')
+var selectHose = require('select-hose')
+var transport = require('spdy-transport')
+var debug = require('debug')('spdy:server')
+var EventEmitter = require('events').EventEmitter
+
+// Node.js 0.8, 0.10 and 0.12 support
+Object.assign = process.versions.modules >= 46
+  ? Object.assign // eslint-disable-next-line
+  : util._extend
+
+var spdy = require('../spdy')
+
+var proto = {}
+
+function instantiate (base) {
+  function Server (options, handler) {
+    this._init(base, options, handler)
+  }
+  util.inherits(Server, base)
+
+  Server.create = function create (options, handler) {
+    return new Server(options, handler)
+  }
+
+  Object.keys(proto).forEach(function (key) {
+    Server.prototype[key] = proto[key]
+  })
+
+  return Server
+}
+
+proto._init = function _init (base, options, handler) {
+  var state = {}
+  this._spdyState = state
+
+  state.options = options.spdy || {}
+
+  var protocols = state.options.protocols || [
+    'h2',
+    'spdy/3.1', 'spdy/3', 'spdy/2',
+    'http/1.1', 'http/1.0'
+  ]
+
+  var actualOptions = Object.assign({
+    NPNProtocols: protocols,
+
+    // Future-proof
+    ALPNProtocols: protocols
+  }, options)
+
+  state.secure = this instanceof tls.Server
+
+  if (state.secure) {
+    base.call(this, actualOptions)
+  } else {
+    base.call(this)
+  }
+
+  // Support HEADERS+FIN
+  this.httpAllowHalfOpen = true
+
+  var event = state.secure ? 'secureConnection' : 'connection'
+
+  state.listeners = this.listeners(event).slice()
+  assert(state.listeners.length > 0, 'Server does not have default listeners')
+  this.removeAllListeners(event)
+
+  if (state.options.plain) {
+    this.on(event, this._onPlainConnection)
+  } else { this.on(event, this._onConnection) }
+
+  if (handler) {
+    this.on('request', handler)
+  }
+
+  debug('server init secure=%d', state.secure)
+}
+
+proto._onConnection = function _onConnection (socket) {
+  var state = this._spdyState
+
+  var protocol
+  if (state.secure) {
+    protocol = socket.npnProtocol || socket.alpnProtocol
+  }
+
+  this._handleConnection(socket, protocol)
+}
+
+proto._handleConnection = function _handleConnection (socket, protocol) {
+  var state = this._spdyState
+
+  if (!protocol) {
+    protocol = state.options.protocol
+  }
+
+  debug('incoming socket protocol=%j', protocol)
+
+  // No way we can do anything with the socket
+  if (!protocol || protocol === 'http/1.1' || protocol === 'http/1.0') {
+    debug('to default handler it goes')
+    return this._invokeDefault(socket)
+  }
+
+  socket.setNoDelay(true)
+
+  var connection = transport.connection.create(socket, Object.assign({
+    protocol: /spdy/.test(protocol) ? 'spdy' : 'http2',
+    isServer: true
+  }, state.options.connection || {}))
+
+  // Set version when we are certain
+  if (protocol === 'http2') { connection.start(4) } else if (protocol === 'spdy/3.1') {
+    connection.start(3.1)
+  } else if (protocol === 'spdy/3') { connection.start(3) } else if (protocol === 'spdy/2') {
+    connection.start(2)
+  }
+
+  connection.on('error', function () {
+    socket.destroy()
+  })
+
+  var self = this
+  connection.on('stream', function (stream) {
+    self._onStream(stream)
+  })
+}
+
+// HTTP2 preface
+var PREFACE = 'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'
+var PREFACE_BUFFER = Buffer.from(PREFACE)
+
+function hoseFilter (data, callback) {
+  if (data.length < 1) {
+    return callback(null, null)
+  }
+
+  // SPDY!
+  if (data[0] === 0x80) { return callback(null, 'spdy') }
+
+  var avail = Math.min(data.length, PREFACE_BUFFER.length)
+  for (var i = 0; i < avail; i++) {
+    if (data[i] !== PREFACE_BUFFER[i]) { return callback(null, 'http/1.1') }
+  }
+
+  // Not enough bytes to be sure about HTTP2
+  if (avail !== PREFACE_BUFFER.length) { return callback(null, null) }
+
+  return callback(null, 'h2')
+}
+
+proto._onPlainConnection = function _onPlainConnection (socket) {
+  var hose = selectHose.create(socket, {}, hoseFilter)
+
+  var self = this
+  hose.on('select', function (protocol, socket) {
+    self._handleConnection(socket, protocol)
+  })
+
+  hose.on('error', function (err) {
+    debug('hose error %j', err.message)
+    socket.destroy()
+  })
+}
+
+proto._invokeDefault = function _invokeDefault (socket) {
+  var state = this._spdyState
+
+  for (var i = 0; i < state.listeners.length; i++) { state.listeners[i].call(this, socket) }
+}
+
+proto._onStream = function _onStream (stream) {
+  var state = this._spdyState
+
+  var handle = spdy.handle.create(this._spdyState.options, stream)
+
+  var socketOptions = {
+    handle: handle,
+    allowHalfOpen: true
+  }
+
+  var socket
+  if (state.secure) {
+    socket = new spdy.Socket(stream.connection.socket, socketOptions)
+  } else {
+    socket = new net.Socket(socketOptions)
+  }
+
+  // This is needed because the `error` listener, added by the default
+  // `connection` listener, no longer has bound arguments. It relies instead
+  // on the `server` property of the socket. See https://github.com/nodejs/node/pull/11926
+  // for more details.
+  // This is only done for Node.js >= 4 in order to not break compatibility
+  // with older versions of the platform.
+  if (process.versions.modules >= 46) { socket.server = this }
+
+  handle.assignSocket(socket)
+
+  // For v0.8
+  socket.readable = true
+  socket.writable = true
+
+  this._invokeDefault(socket)
+
+  // For v0.8, 0.10 and 0.12
+  if (process.versions.modules < 46) {
+    // eslint-disable-next-line
+    this.listenerCount = EventEmitter.listenerCount.bind(this)
+  }
+
+  // Add lazy `checkContinue` listener, otherwise `res.writeContinue` will be
+  // called before the response object was patched by us.
+  if (stream.headers.expect !== undefined &&
+      /100-continue/i.test(stream.headers.expect) &&
+      this.listenerCount('checkContinue') === 0) {
+    this.once('checkContinue', function (req, res) {
+      res.writeContinue()
+
+      this.emit('request', req, res)
+    })
+  }
+
+  handle.emitRequest()
+}
+
+proto.emit = function emit (event, req, res) {
+  if (event !== 'request' && event !== 'checkContinue') {
+    return EventEmitter.prototype.emit.apply(this, arguments)
+  }
+
+  if (!(req.socket._handle instanceof spdy.handle)) {
+    debug('not spdy req/res')
+    req.isSpdy = false
+    req.spdyVersion = 1
+    res.isSpdy = false
+    res.spdyVersion = 1
+    return EventEmitter.prototype.emit.apply(this, arguments)
+  }
+
+  var handle = req.connection._handle
+
+  req.isSpdy = true
+  req.spdyVersion = handle.getStream().connection.getVersion()
+  res.isSpdy = true
+  res.spdyVersion = req.spdyVersion
+  req.spdyStream = handle.getStream()
+
+  debug('override req/res')
+  res.writeHead = spdy.response.writeHead
+  res.end = spdy.response.end
+  res.push = spdy.response.push
+  res.writeContinue = spdy.response.writeContinue
+  res.spdyStream = handle.getStream()
+
+  res._req = req
+
+  handle.assignRequest(req)
+  handle.assignResponse(res)
+
+  return EventEmitter.prototype.emit.apply(this, arguments)
+}
+
+exports.Server = instantiate(https.Server)
+exports.PlainServer = instantiate(http.Server)
+
+exports.create = function create (base, options, handler) {
+  if (typeof base === 'object') {
+    handler = options
+    options = base
+    base = null
+  }
+
+  if (base) {
+    return instantiate(base).create(options, handler)
+  }
+
+  if (options.spdy && options.spdy.plain) { return exports.PlainServer.create(options, handler) } else {
+    return exports.Server.create(options, handler)
+  }
+}
Index: frontend/node_modules/spdy/lib/spdy/socket.js
===================================================================
--- frontend/node_modules/spdy/lib/spdy/socket.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/spdy/lib/spdy/socket.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+'use strict'
+
+var util = require('util')
+var net = require('net')
+
+function Socket (parent, options) {
+  net.Socket.call(this, options)
+
+  var state = {}
+
+  this._spdyState = state
+
+  state.parent = parent
+
+  this.servername = parent.servername
+  this.npnProtocol = parent.npnProtocol
+  this.alpnProtocol = parent.alpnProtocol
+  this.authorized = parent.authorized
+  this.authorizationError = parent.authorizationError
+  this.encrypted = true
+  this.allowHalfOpen = true
+}
+
+util.inherits(Socket, net.Socket)
+
+module.exports = Socket
+
+var methods = [
+  'renegotiate', 'setMaxSendFragment', 'getTLSTicket', 'setServername',
+  'setSession', 'getPeerCertificate', 'getSession', 'isSessionReused',
+  'getCipher', 'getEphemeralKeyInfo'
+]
+
+methods.forEach(function (method) {
+  Socket.prototype[method] = function methodWrap () {
+    var parent = this._spdyState.parent
+    return parent[method].apply(parent, arguments)
+  }
+})
