Repository navigation
doc, http: Type specification incomplete for ServerResponse.getHeader() #13825
Description
Activity
- addedhttpIssues and PRs related to the http subsystem.Issues and PRs related to the http subsystem.
on Jun 20, 2017 - addeddocIssues and PRs related to Node.js documentation.Issues and PRs related to Node.js documentation.
on Jun 23, 2017 @Flarna - if I understand your question correctly, you are saying that the headers are stored as objects before sent to the wire, so
getHeader()could retrieve them as it is, as opposed tostrings?I guess they are stored as strings by stripping them from the object in writeHead method .
It's quite a while till I submitted this. Here is a small reproducer; hope I remember correct on the actual use case...
const http = require('http') let cnt = 0 function onRequest(req, res) { const body = 'hello world' if (cnt++ % 2) { res.writeHead(200, { 'Content-Length': Buffer.byteLength(body), 'Content-Type': 'text/plain' }) } else { res.setHeader('Content-Length', Buffer.byteLength(body)) res.setHeader('Content-Type', 'text/plain') } console.log(`typeof(res.getHeader('Content-Length')): ${typeof(res.getHeader('Content-Length'))}`) console.log(`typeof(res.getHeader('Content-Type')): ${typeof(res.getHeader('Content-Type'))}`) res.end(body) } http.createServer(onRequest).listen(8000) http.get('http://localhost:8000') http.get('http://localhost:8000')this prints:
typeof(res.getHeader('Content-Length')): number typeof(res.getHeader('Content-Type')): string typeof(res.getHeader('Content-Length')): undefined typeof(res.getHeader('Content-Type')): undefinedSo if
writeHead()is used thengetHeader()doesn't return anything at all.
If I usesetHeader()then I get exactly what I have set before (e.g. a number in case of 'Content-Length') and not astring.The use of
Buffer.byteLenght()is inspired by the sample at https://nodejs.org/dist/latest/docs/api/http.html#http_response_writehead_statuscode_statusmessage_headers@Flarna - I think I got your point now. Probably the
setHeader()expects a series of incremental writes to the header and hence it stores the requests in an internal fieldoutHeadersKeyfor potential future modifications. Whereas, if the code invokedwriteHeadfirst, the expectation is that it does in one shot, so the storing does not happen here - probably this is an optimization, based on the comments around.Consequently, if you do a dummy setHeader first, subsequent writeHeads are stored in the internal field, and are accessible through getHeader:
#cat 13825.js
const h = require('http') const n = require('net') h.createServer((q, s) => { const bodys = 'hello world' const bodyw = '<html>hello</html>' if(process.argv[2]) s.setHeader('Content-Length', bodys.length) s.writeHead(200, { 'Content-Length': bodyw.length, 'Content-Type': 'text/html' }) console.log(s.getHeader('Content-Length')) console.log(s.getHeader('Content-Type')) s.end(bodyw) }).listen(8000, () => { h.get('http://localhost:8000') })
#node 13825.js
undefined
undefined
^C
#node 13825.js true
18
text/html
^CHope this helps. /cc @nodejs/http for expert opinion.
@Flarna I think the document needs to be changed. Would you like to make a PR to make the document more perfect?
Reacted by Gireesh Punathil@MoonBall ok, will do so once I have some poetic moments to formulate this in a reasonable way.
- added a commit that references this issue
on Apr 13, 2018 - added a commit that references this issue
on Apr 16, 2018 - added a commit that references this issue
on May 1, 2018
ServerResponse.setHeader()specifies name asstringand value asstring | string[].ServerResponse.writeHead()allows an object for headers (key is header name, value is header value). All samples usestringfor keys andstring | string[]for values - except one which usesBuffer.byteLength(body)which is anumber(the sample works fine).ServerResponse.getHeader()specifies to return astring.Actually
getHeader()returns what as passed in so it should be at leaststring | string[].But as
setHeader()andwriteHead()actually allow any stringifyable type you get also such type back as the conversion tostringhappens when writing the outgoing stream not during storing the header.Not sure here if this is worth a change; and if yes should it be in doc or code?
I would guess the same is applicable to
ClientRequest.