|
|
@ -127,7 +127,10 @@ const { |
|
|
|
HTTP_STATUS_OK, |
|
|
|
HTTP_STATUS_NO_CONTENT, |
|
|
|
HTTP_STATUS_NOT_MODIFIED, |
|
|
|
HTTP_STATUS_SWITCHING_PROTOCOLS |
|
|
|
HTTP_STATUS_SWITCHING_PROTOCOLS, |
|
|
|
|
|
|
|
STREAM_OPTION_EMPTY_PAYLOAD, |
|
|
|
STREAM_OPTION_GET_TRAILERS |
|
|
|
} = constants; |
|
|
|
|
|
|
|
// Top level to avoid creating a closure
|
|
|
@ -412,20 +415,22 @@ function requestOnConnect(headers, options) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
let getTrailers = false; |
|
|
|
let streamOptions = 0; |
|
|
|
if (options.endStream) |
|
|
|
streamOptions |= STREAM_OPTION_EMPTY_PAYLOAD; |
|
|
|
|
|
|
|
if (typeof options.getTrailers === 'function') { |
|
|
|
getTrailers = true; |
|
|
|
streamOptions |= STREAM_OPTION_GET_TRAILERS; |
|
|
|
this[kState].getTrailers = options.getTrailers; |
|
|
|
} |
|
|
|
|
|
|
|
// ret will be either the reserved stream ID (if positive)
|
|
|
|
// or an error code (if negative)
|
|
|
|
const ret = handle.submitRequest(headersList, |
|
|
|
!!options.endStream, |
|
|
|
streamOptions, |
|
|
|
options.parent | 0, |
|
|
|
options.weight | 0, |
|
|
|
!!options.exclusive, |
|
|
|
getTrailers); |
|
|
|
!!options.exclusive); |
|
|
|
|
|
|
|
// In an error condition, one of three possible response codes will be
|
|
|
|
// possible:
|
|
|
@ -1568,7 +1573,7 @@ function processHeaders(headers) { |
|
|
|
} |
|
|
|
|
|
|
|
function processRespondWithFD(fd, headers, offset = 0, length = -1, |
|
|
|
getTrailers = false) { |
|
|
|
streamOptions = 0) { |
|
|
|
const session = this[kSession]; |
|
|
|
const state = this[kState]; |
|
|
|
state.headersSent = true; |
|
|
@ -1578,7 +1583,7 @@ function processRespondWithFD(fd, headers, offset = 0, length = -1, |
|
|
|
|
|
|
|
const handle = session[kHandle]; |
|
|
|
const ret = |
|
|
|
handle.submitFile(this[kID], fd, headers, offset, length, getTrailers); |
|
|
|
handle.submitFile(this[kID], fd, headers, offset, length, streamOptions); |
|
|
|
let err; |
|
|
|
switch (ret) { |
|
|
|
case NGHTTP2_ERR_NOMEM: |
|
|
@ -1593,7 +1598,7 @@ function processRespondWithFD(fd, headers, offset = 0, length = -1, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function doSendFD(session, options, fd, headers, getTrailers, err, stat) { |
|
|
|
function doSendFD(session, options, fd, headers, streamOptions, err, stat) { |
|
|
|
if (this.destroyed || session.destroyed) { |
|
|
|
abort(this); |
|
|
|
return; |
|
|
@ -1623,10 +1628,10 @@ function doSendFD(session, options, fd, headers, getTrailers, err, stat) { |
|
|
|
processRespondWithFD.call(this, fd, headersList, |
|
|
|
statOptions.offset, |
|
|
|
statOptions.length, |
|
|
|
getTrailers); |
|
|
|
streamOptions); |
|
|
|
} |
|
|
|
|
|
|
|
function doSendFileFD(session, options, fd, headers, getTrailers, err, stat) { |
|
|
|
function doSendFileFD(session, options, fd, headers, streamOptions, err, stat) { |
|
|
|
if (this.destroyed || session.destroyed) { |
|
|
|
abort(this); |
|
|
|
return; |
|
|
@ -1681,10 +1686,10 @@ function doSendFileFD(session, options, fd, headers, getTrailers, err, stat) { |
|
|
|
processRespondWithFD.call(this, fd, headersList, |
|
|
|
options.offset, |
|
|
|
options.length, |
|
|
|
getTrailers); |
|
|
|
streamOptions); |
|
|
|
} |
|
|
|
|
|
|
|
function afterOpen(session, options, headers, getTrailers, err, fd) { |
|
|
|
function afterOpen(session, options, headers, streamOptions, err, fd) { |
|
|
|
const state = this[kState]; |
|
|
|
const onError = options.onError; |
|
|
|
if (this.destroyed || session.destroyed) { |
|
|
@ -1702,7 +1707,8 @@ function afterOpen(session, options, headers, getTrailers, err, fd) { |
|
|
|
state.fd = fd; |
|
|
|
|
|
|
|
fs.fstat(fd, |
|
|
|
doSendFileFD.bind(this, session, options, fd, headers, getTrailers)); |
|
|
|
doSendFileFD.bind(this, session, options, fd, |
|
|
|
headers, streamOptions)); |
|
|
|
} |
|
|
|
|
|
|
|
function streamOnError(err) { |
|
|
@ -1786,9 +1792,9 @@ class ServerHttp2Stream extends Http2Stream { |
|
|
|
throw headersList; |
|
|
|
} |
|
|
|
|
|
|
|
const ret = handle.submitPushPromise(this[kID], |
|
|
|
headersList, |
|
|
|
options.endStream); |
|
|
|
const streamOptions = options.endStream ? STREAM_OPTION_EMPTY_PAYLOAD : 0; |
|
|
|
|
|
|
|
const ret = handle.submitPushPromise(this[kID], headersList, streamOptions); |
|
|
|
let err; |
|
|
|
switch (ret) { |
|
|
|
case NGHTTP2_ERR_NOMEM: |
|
|
@ -1844,14 +1850,17 @@ class ServerHttp2Stream extends Http2Stream { |
|
|
|
options = Object.assign(Object.create(null), options); |
|
|
|
options.endStream = !!options.endStream; |
|
|
|
|
|
|
|
let getTrailers = false; |
|
|
|
let streamOptions = 0; |
|
|
|
if (options.endStream) |
|
|
|
streamOptions |= STREAM_OPTION_EMPTY_PAYLOAD; |
|
|
|
|
|
|
|
if (options.getTrailers !== undefined) { |
|
|
|
if (typeof options.getTrailers !== 'function') { |
|
|
|
throw new errors.TypeError('ERR_INVALID_OPT_VALUE', |
|
|
|
'getTrailers', |
|
|
|
options.getTrailers); |
|
|
|
} |
|
|
|
getTrailers = true; |
|
|
|
streamOptions |= STREAM_OPTION_GET_TRAILERS; |
|
|
|
state.getTrailers = options.getTrailers; |
|
|
|
} |
|
|
|
|
|
|
@ -1881,10 +1890,7 @@ class ServerHttp2Stream extends Http2Stream { |
|
|
|
|
|
|
|
const handle = session[kHandle]; |
|
|
|
const ret = |
|
|
|
handle.submitResponse(this[kID], |
|
|
|
headersList, |
|
|
|
options.endStream, |
|
|
|
getTrailers); |
|
|
|
handle.submitResponse(this[kID], headersList, streamOptions); |
|
|
|
let err; |
|
|
|
switch (ret) { |
|
|
|
case NGHTTP2_ERR_NOMEM: |
|
|
@ -1937,14 +1943,14 @@ class ServerHttp2Stream extends Http2Stream { |
|
|
|
options.statCheck); |
|
|
|
} |
|
|
|
|
|
|
|
let getTrailers = false; |
|
|
|
let streamOptions = 0; |
|
|
|
if (options.getTrailers !== undefined) { |
|
|
|
if (typeof options.getTrailers !== 'function') { |
|
|
|
throw new errors.TypeError('ERR_INVALID_OPT_VALUE', |
|
|
|
'getTrailers', |
|
|
|
options.getTrailers); |
|
|
|
} |
|
|
|
getTrailers = true; |
|
|
|
streamOptions |= STREAM_OPTION_GET_TRAILERS; |
|
|
|
state.getTrailers = options.getTrailers; |
|
|
|
} |
|
|
|
|
|
|
@ -1963,7 +1969,8 @@ class ServerHttp2Stream extends Http2Stream { |
|
|
|
|
|
|
|
if (options.statCheck !== undefined) { |
|
|
|
fs.fstat(fd, |
|
|
|
doSendFD.bind(this, session, options, fd, headers, getTrailers)); |
|
|
|
doSendFD.bind(this, session, options, fd, |
|
|
|
headers, streamOptions)); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
@ -1977,7 +1984,7 @@ class ServerHttp2Stream extends Http2Stream { |
|
|
|
processRespondWithFD.call(this, fd, headersList, |
|
|
|
options.offset, |
|
|
|
options.length, |
|
|
|
getTrailers); |
|
|
|
streamOptions); |
|
|
|
} |
|
|
|
|
|
|
|
// Initiate a file response on this Http2Stream. The path is passed to
|
|
|
@ -2019,14 +2026,14 @@ class ServerHttp2Stream extends Http2Stream { |
|
|
|
options.statCheck); |
|
|
|
} |
|
|
|
|
|
|
|
let getTrailers = false; |
|
|
|
let streamOptions = 0; |
|
|
|
if (options.getTrailers !== undefined) { |
|
|
|
if (typeof options.getTrailers !== 'function') { |
|
|
|
throw new errors.TypeError('ERR_INVALID_OPT_VALUE', |
|
|
|
'getTrailers', |
|
|
|
options.getTrailers); |
|
|
|
} |
|
|
|
getTrailers = true; |
|
|
|
streamOptions |= STREAM_OPTION_GET_TRAILERS; |
|
|
|
state.getTrailers = options.getTrailers; |
|
|
|
} |
|
|
|
|
|
|
@ -2040,7 +2047,7 @@ class ServerHttp2Stream extends Http2Stream { |
|
|
|
} |
|
|
|
|
|
|
|
fs.open(path, 'r', |
|
|
|
afterOpen.bind(this, session, options, headers, getTrailers)); |
|
|
|
afterOpen.bind(this, session, options, headers, streamOptions)); |
|
|
|
} |
|
|
|
|
|
|
|
// Sends a block of informational headers. In theory, the HTTP/2 spec
|
|
|
|