-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
http: Expose http.validateHeaderName/Value #33119
Conversation
BTW - My current work-around is a hack, roughly in the spirit below.
|
-1 It's not clear to me why this is required. Besides, if the internals change where other public API methods end up using additional validation functions, those would need to be exported too and trying to keep up with that would be a nightmare. If the end goal here is to mutate the error object thrown by
const reply = {
//... more stuff
setHeader: (...args) => {
try {
setHeader.call(this, ...args)
} catch (e) {
throw augmentWithFrameworkContextInfo(e)
}
},
//... more stuff
}
OutgoingMessage.call(reply);
res.setHeader = (...args) => {
try {
setHeader.call(this, ...args)
} catch (e) {
throw augmentWithFrameworkContextInfo(e)
}
} |
@mscdex - thanks for your quick response. My personal goal - as in, the specific use-case I'm currently at now - is indeed to mediate and restrict access to res, but I was not thinking only about myself but trying to think generically. It's a purely functional logic with no implications of state... 😉 Keeping this logic hidden basically results in code duplications in user codes... Anyway - the example I brought here is very simplified, I have more going on (potentially proprietary). I admit that what you proposed in your points will work - but IMHO - it is by far more cumbersome than just using the validator functions.
For the work-around - I consider replacing my workaround with option 2 just until such change can be accepted - however - that's basically replacing one specific monkey patch with another, both of which are workaround hacks tailored for this use-case and do not solve the fact that this logic should be reusable and it is not. About the argument of needing future validations - do you feel that any future validation will not be applicable as part of I considered for a moment to add |
@mscdex - thanks for the lead!! - FYI - I got a simpler hack:
(never thought this constructor will work without all the wireworks...) Still monkeying, just shorter, and does not mount lotta dirt on an Object passed to user-code. So I still believe this PR has value and no risk 😉 |
I still think we shouldn't expose them. If internals change and/or these functions change in one way or another (e.g. split into smaller functions or even removed entirely), we don't want to have to be maintaining these utility functions because they've now been exposed to userland. I think the solutions outlined in this PR are fine for userland. If others happen to share this similar (and uncommon IMO) need, they can use one of those -- or develop their own validators. |
would you please consider for a moment that whatever any additional validations may be needed in the future, they can be implemented as part of Let us also consider that if there will be such a need for future validations, it would also mean that the code duplications of this logic will need it too... 😉 As for the 3 ways - I have played with them, and they do not fit the use-case of mediation and restricting access to res. Hmmm. If you would like not to export these validators, - here's an alternative that does not expose anything that is not already exposed. How about the following change instead. Would that be considerable?
it could also be
or
whatever fits the lint rules... Unfortunately, this line is what prevents me from a clear and efficient code, in the spirit of:
because, you see, it ensists on having What do you think? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems okay to me, but it should come with tests and documentation
Let`s start with tests. As a basis - I can obviously show the validators are exposed and that they have the expected signature. Anyway - I'll appreciate a point in the right direction So what I'm expected here is something in the spirit of I'm also confused that there are no test titles... hardly comments... Thanks in advance for any guidance. Editedok. I found the I mean to do it in one file for both validators if that's alright with ppl here |
@addaleax I do suspect that it's what referred in docs as When I'm looking at how it looks from user perspective, I start to think that it will provide a better interface if they'll be exposed directly on
it will be
I was also surprized to find that some obvious validations do not happen. E.g - this does not fail validation:
I actually got to fail on the max length of strings before I saw any error thrown for invalid length of header name or value. I don't mind if it's not part of the infra, this length validation may indeed belong to user-land, I just have to double-check with you... To sum up:
Thanks!! EDITEDI'm getting the feeling that Can you please confirm this or correct me so I know how to proceed? |
Yes, that’s correct – |
@addaleax - Okie dokie.
So here's what we've got so far:
- validator methods are exposed directly on `http`
(which internally pulls them from `OutgoingMessage` - I did it this way
to minimize code changes, I hope it's on target).
- test file named `test/parallel/test-http-validate-headers.js`, and test
them from there
- added docs in `docs/http.md`
…On Tue, May 5, 2020 at 4:41 PM Anna Henningsen ***@***.***> wrote:
I'm getting the feeling that OutgoingMessage is an undocumented
implementation detail, and therefore the validators should not be exposed
on it, but either on http or on http.ServerResponse.
Can you please confirm this or correct me so I know how to proceed?
Yes, that’s correct – OutgoingMessage serves as the base class for client
requests and server responses, but it’s not intended to be used directly by
users. Providing these methods on the http module itself seems to make
sense to me 👍
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#33119 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGECHLLHK7QFEJ5D34JR63RQAJQBANCNFSM4MSVHO3Q>
.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with the linter failures fixed
@nodejs/http
doc/api/http.md
Outdated
try { | ||
validateHeaderName('') | ||
} catch(err) { | ||
err instanceof TypeError // --> true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m not sure we should document this, partly because it seems wrong to me to use TypeError
here.
err instanceof TypeError // --> true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please have a look at the docs for setHeader
- it explicitly says TypeError
, so I took it from there.
Do you still believe we should remove it?
P.S - good that you note it - because many infrastructures I've witnessed (the lionshare are proprietary, but not only) use error types to distinguish between and sort errors, often with a secondary look at the code
.
I personally detest class hierarchies and consider them to be implementation details, but, you know... let them have what they say they can't live without...
doc/api/http.md
Outdated
try { | ||
validateHeaderValue('x-my-header', undefined); | ||
} catch(err) { | ||
err instanceof TypeError; // --> true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto here,
err instanceof TypeError; // --> true |
The use-case is for any framework that provides user mw a response replacement, that collects the desired response state, and applies them only on conclusion. As such a framework, I'd want to validate the header names and values as soon as the user-code provides them. This - to eliminate errors on response-send time, and provide developer stack trace that contains the line that submits the offending values.
@addaleax - I adhered everything except one thing I would like to double-check - about removing from doc examples:
Please have a look at the docs for |
@osher It’s not essential but yes, I’d prefer to remove those lines – partially for the exact reason that you mentioned, which is that if you want to check for this type of error, looking at the error code is the right thing to do 👍 |
The use-case is for any framework that provides user mw a response replacement, that collects the desired response state, and applies them only on conclusion. As such a framework, I'd want to validate the header names and values as soon as the user-code provides them. This - to eliminate errors on response-send time, and provide developer stack trace that contains the line that submits the offending values. PR-URL: #33119 Reviewed-By: Anna Henningsen <[email protected]>
Landed in 96faea1, thanks for the PR! |
It seems these functions are still tacked onto |
@mscdex - @addaleax - I agree that the |
I don't understand how it's an implementation detail. There's no need for it to be set on |
Yes. I see what you point at, that's true.
and in http:
(plus similar effect on tests) I can agree It looks tidier. Would you like a PR for that? |
PR would be great. |
The use-case is for any framework that provides user mw a response replacement, that collects the desired response state, and applies them only on conclusion. As such a framework, I'd want to validate the header names and values as soon as the user-code provides them. This - to eliminate errors on response-send time, and provide developer stack trace that contains the line that submits the offending values. PR-URL: #33119 Reviewed-By: Anna Henningsen <[email protected]>
Notable changes: async_hooks: * (SEMVER-MINOR) move PromiseHook handler to JS (Stephen Belanger) #32891 cli: * (SEMVER-MINOR) add `--trace-atomics-wait` flag (Anna Henningsen) #33292 fs: * (SEMVER-MINOR) add .ref() and .unref() methods to watcher classes (rickyes) #33134 http: * (SEMVER-MINOR) expose http.validate-header-name/value (osher) #33119 repl: * (SEMVER-MINOR) deprecate repl._builtinLibs (Ruben Bridgewater) #33294 * (SEMVER-MINOR) remove obsolete completer variable (Ruben Bridgewater) #33294 * (SEMVER-MINOR) deprecate repl.inputStream and repl.outputStream (Ruben Bridgewater) #33294 * (SEMVER-MINOR) improve repl autocompletion for require calls (Ruben Bridgewater) #33282 * (SEMVER-MINOR) replace hard coded core module list with actual list (Ruben Bridgewater) #33282 * (SEMVER-MINOR) show reference errors during preview (Ruben Bridgewater) #33282 * (SEMVER-MINOR) improve repl preview (Ruben Bridgewater) #33282 src: * add support for TLA (Gus Caplan) #30370 test: * (SEMVER-MINOR) refactor test/parallel/test-bootstrap-modules.js (Ruben Bridgewater) #33282 PR-URL: TODO
Notable changes: async_hooks: * (SEMVER-MINOR) move PromiseHook handler to JS (Stephen Belanger) #32891 cli: * (SEMVER-MINOR) add `--trace-atomics-wait` flag (Anna Henningsen) #33292 fs: * (SEMVER-MINOR) add .ref() and .unref() methods to watcher classes (rickyes) #33134 http: * (SEMVER-MINOR) expose http.validate-header-name/value (osher) #33119 repl: * (SEMVER-MINOR) deprecate repl._builtinLibs (Ruben Bridgewater) #33294 * (SEMVER-MINOR) deprecate repl.inputStream and repl.outputStream (Ruben Bridgewater) #33294 * (SEMVER-MINOR) show reference errors during preview (Ruben Bridgewater) #33282 * (SEMVER-MINOR) improve repl preview (Ruben Bridgewater) #33282 src: * add support for TLA (Gus Caplan) #30370 PR-URL: TODO
Notable changes: async_hooks: * (SEMVER-MINOR) move PromiseHook handler to JS (Stephen Belanger) #32891 cli: * (SEMVER-MINOR) add `--trace-atomics-wait` flag (Anna Henningsen) #33292 fs: * (SEMVER-MINOR) add .ref() and .unref() methods to watcher classes (rickyes) #33134 http: * (SEMVER-MINOR) expose http.validate-header-name/value (osher) #33119 repl: * (SEMVER-MINOR) deprecate repl._builtinLibs (Ruben Bridgewater) #33294 * (SEMVER-MINOR) deprecate repl.inputStream and repl.outputStream (Ruben Bridgewater) #33294 * (SEMVER-MINOR) show reference errors during preview (Ruben Bridgewater) #33282 * (SEMVER-MINOR) improve repl preview (Ruben Bridgewater) #33282 src: * add support for TLA (Gus Caplan) #30370 PR-URL: TODO
Notable changes: async_hooks: * (SEMVER-MINOR) move PromiseHook handler to JS (Stephen Belanger) #32891 cli: * (SEMVER-MINOR) add `--trace-atomics-wait` flag (Anna Henningsen) #33292 fs: * (SEMVER-MINOR) add .ref() and .unref() methods to watcher classes (rickyes) #33134 http: * (SEMVER-MINOR) expose http.validate-header-name/value (osher) #33119 repl: * (SEMVER-MINOR) deprecate repl._builtinLibs (Ruben Bridgewater) #33294 * (SEMVER-MINOR) deprecate repl.inputStream and repl.outputStream (Ruben Bridgewater) #33294 * (SEMVER-MINOR) show reference errors during preview (Ruben Bridgewater) #33282 * (SEMVER-MINOR) improve repl preview (Ruben Bridgewater) #33282 src: * add support for TLA (Gus Caplan) #30370 PR-URL: TODO
Notable changes: async_hooks: * (SEMVER-MINOR) move PromiseHook handler to JS (Stephen Belanger) #32891 cli: * (SEMVER-MINOR) add `--trace-atomics-wait` flag (Anna Henningsen) #33292 fs: * (SEMVER-MINOR) add .ref() and .unref() methods to watcher classes (rickyes) #33134 http: * (SEMVER-MINOR) expose http.validate-header-name/value (osher) #33119 repl: * (SEMVER-MINOR) deprecate repl._builtinLibs (Ruben Bridgewater) #33294 * (SEMVER-MINOR) deprecate repl.inputStream and repl.outputStream (Ruben Bridgewater) #33294 * (SEMVER-MINOR) show reference errors during preview (Ruben Bridgewater) #33282 * (SEMVER-MINOR) improve repl preview (Ruben Bridgewater) #33282 src: * add support for TLA (Gus Caplan) #30370 PR-URL: #33452
Would we want to backport this to v12.x? If so it seems like they should come with #33371 |
The use-case is for any framework that provides user mw a response replacement, that collects the desired response state, and sends it only on conclusion.
As such a framework, I'd want to validate the header names and values as soon as the user-code provides them.
This - to
Doing it this will allow to:
and use them.
Checklist