Comments (15)
As for your case, wouldn't it be easier (and less dependent on the internals) to just create a server and do
server.emit('connection', yourInputStream)
and then sendrequest
events to the output stream?
For anyone else curious about a minimal way to utilize these parsers, as mentioned above, here's a code snippet.
import { createServer, request } from 'http'
import { PassThrough } from 'node:stream'
const parseRequest = (data) => new Promise(resolve =>
createServer()
.on('request', resolve)
.on('connection', stream => stream.write(data))
.emit('connection', new PassThrough())
)
const parseResponse = (data) => new Promise(resolve =>
request({ createConnection: () => new PassThrough() })
.on('socket', stream => stream.write(data))
.on('response', resolve)
)
const parsedRequest = await parseRequest(Buffer.from('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'))
const parsedResponse = await parseResponse(Buffer.from('HTTP/1.1 200 OK\r\n\r\n'))
For other ways of accessing these parsers, see here: gr3p1p3/transparent-proxy#30
from llhttp.
Hello!
That stackoverflow page is referring to http-parser-js
which is a JavaScript port of http-parser. I believe it is still possible to use this module, because it doesn't use any C/C++ bindings at all.
It is not clear what you'd like to do, however. Do you want to run old HTTP parser or new HTTP parser? Do you want to run it manually (i.e. outside of http.createServer()
/http.request
)?
from llhttp.
@indutny Thanks for the quick answer!
You're right, I linked to the wrong snippet, I meant to link to the native bindings: https://stackoverflow.com/a/42003256
Yes, the idea would be to run the new HTTP parser that you wrote, llhttp, but manually in Node.js in a similar way than in the stackoverflow answer.
I'd like to pipe a Node.js stream into the parser that would then pipe the response headers and body back into a stream.
I know how to write the stream interfaces so that's ok, I'm just looking for a way to run the llhttp part.
I know that this is pretty much what the HTTP module does, but I'd like to be able to recreate something similar on my own.
from llhttp.
The process.binding(...)
should work without any changes on your end since llhttp and http-parser are interoperable (at least when it comes to their JS APIs).
from llhttp.
Hmm, then I'm encountering a bug I believe in [email protected]
and [email protected]
on OSX, for this short test case (which would work on the old parser):
cconst HTTPParser = process.binding('http_parser').HTTPParser;
const httpParser = new HTTPParser(HTTPParser.REQUEST);
httpParser[HTTPParser.kOnHeadersComplete] = () => console.log('headers=', arguments);
httpParser.execute(Buffer.from(
'GET /test HTTP/1.1\r\n' +
'Host: www.example.com\r\n' +
'\r\n'
));
I'm getting the following error:
node(55269,0x10df1a5c0) malloc: can't allocate region
*** mach_vm_map(size=9007066110754816) failed (error code=3)
node(55269,0x10df1a5c0) malloc: *** set a breakpoint in malloc_error_break to debug
libc++abi.dylib: terminating with uncaught exception of type std::bad_alloc: std::bad_alloc
fish: 'node http-parser-test.js' terminated by signal SIGABRT (Abort)
from llhttp.
Wow, it's actually even weirder than I thought.
If I run the program multiple times, it will sometimes fail with the error I posted above:
node(55465,0x1097d65c0) malloc: can't allocate region
*** mach_vm_map(size=27105212221095936) failed (error code=3)
node(55465,0x1097d65c0) malloc: *** set a breakpoint in malloc_error_break to debug
libc++abi.dylib: terminating with uncaught exception of type std::bad_alloc: std::bad_alloc
Abort trap: 6
sometimes with only the abort trap error:
Abort trap: 6
and then a few times:
Segmentation fault: 11
Even on the latest version, v13.7.0
.
from llhttp.
It is likely that there is some mandatory callback missing. Let me see.
As for your case, wouldn't it be easier (and less dependent on the internals) to just create a server and do server.emit('connection', yourInputStream)
and then send request
events to the output stream?
from llhttp.
Ah, you haven't initialized the parser:
parser.initialize(
HTTPParser.REQUEST,
new HTTPServerAsyncResource('HTTPINCOMINGMESSAGE', socket)
);
As I said before, it is not easy to use this outside of Node.js core...
from llhttp.
Thanks for the follow-up!
Even with the correct initialisation parameters (which I mocked), I seem to keep getting the same errors described above.
The updated snippet is now:
const { Socket } = require('net');
const HTTPParser = process.binding('http_parser').HTTPParser;
class HTTPServerAsyncResource {
constructor(type, socket) {
this.type = type;
this.socket = socket;
}
}
const httpParser = new HTTPParser(
HTTPParser.REQUEST,
new HTTPServerAsyncResource('HTTPINCOMINGMESSAGE', new Socket())
);
httpParser[HTTPParser.kOnHeadersComplete] = () => console.log('headers=', arguments);
httpParser.execute(Buffer.from(
'GET /test HTTP/1.1\r\n' +
'Host: www.example.com\r\n' +
'\r\n'
));
I understand that it's tricky but I would still like to try to call the parser manually because it was possible in the past and it let's you try out a lot of things on the parser directly.
from llhttp.
Could you try calling .initialize()
on the parser?
from llhttp.
@indutny It seems to work now. Thank you very much for the support and sorry for asking silly questions. :)
Have a nice evening.
from llhttp.
Np at all. Glad it worked! You have a good evening as well!
from llhttp.
For those wondering, getting HTTPParser
from the bindings has been deprecated. If you absolutely must, import it from the node:_http_common
module instead:
import { HTTPParser } from 'node:_http_common'
from llhttp.
is import { HTTPParser } from 'node:_http_common'
a public api? if not, can it be?
from llhttp.
It's not a public API and there is no need for it to be.
llhttp can be used in JS by using its WASM version, just like undici does.
See: https://github.com/nodejs/undici/blob/219da8b7b3fea7e38a7644b8bc35fe6fec97d66e/lib/dispatcher/client-h1.js#L139
from llhttp.
Related Issues (20)
- add URL parser HOT 1
- release tag name HOT 1
- Using with cmake results in `VERSION "_RELEASE_" format invalid.` HOT 2
- Couldn't add llhttp as dependency with cmake HOT 2
- when header has Transfer-Encoding: chunked and body is divided into two chunked then parse result is error
- Build errors with IAR 9.40.1 HOT 4
- How to handle one requests in multiple packet with llhttp HOT 4
- llhttp 9.0.0 no longer accepts bare LF HOT 3
- Comma splitting doesn't work HOT 3
- Test mistake? HOT 1
- cmake include path still not working HOT 1
- Problem with on_body callback with bare LF HOT 17
- Transfer-Encoding parsing bugs - RFC violation HOT 2
- Content-Length should be ignored for 304 responses
- 9.1.0 regression: doesn't parse message following 100 response HOT 21
- 9.1.2: build fails HOT 4
- llhttp allows empty header names
- Feature Request: Lenient Flag that Allows UTF-8 Muti-Byte Characters in URL Path HOT 6
- Consider performance improvements comming from PR to llparse HOT 3
- 5l\u7oyo9fgov|\\\\\\\\\\\\\\\\\\\\\\\fppofw25555
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from llhttp.