Repository navigation
Support http connection keep-alive #9
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,7 +16,6 @@ public function __construct(SocketServerInterface $io) | |
| $this->io = $io; | ||
|
|
||
| $this->io->on('connection', function ($conn) { | ||
| // TODO: http 1.1 keep-alive | ||
| // TODO: chunked transfer encoding (also for outgoing data) | ||
| // TODO: multipart parsing | ||
|
|
||
|
|
@@ -25,8 +24,6 @@ public function __construct(SocketServerInterface $io) | |
| // attach remote ip to the request as metadata | ||
| $request->remoteAddress = $conn->getRemoteAddress(); | ||
|
|
||
| $this->handleRequest($conn, $request, $bodyBuffer); | ||
|
|
||
| $conn->removeListener('data', array($parser, 'feed')); | ||
| $conn->on('end', function () use ($request) { | ||
| $request->emit('end'); | ||
|
|
@@ -40,13 +37,18 @@ public function __construct(SocketServerInterface $io) | |
| $request->on('resume', function () use ($conn) { | ||
| $conn->emit('resume'); | ||
| }); | ||
|
|
||
| $this->handleRequest($conn, $parser, $request, $bodyBuffer); | ||
| }); | ||
|
|
||
| $conn->on('data', array($parser, 'feed')); | ||
| $conn->on('end', function () use ($parser) { | ||
| $parser->removeAllListeners(); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| public function handleRequest(ConnectionInterface $conn, Request $request, $bodyBuffer) | ||
| public function handleRequest(ConnectionInterface $conn, RequestHeaderParser $parser, Request $request, $bodyBuffer) | ||
| { | ||
| $response = new Response($conn); | ||
| $response->on('close', array($request, 'close')); | ||
|
|
@@ -57,6 +59,19 @@ public function handleRequest(ConnectionInterface $conn, Request $request, $body | |
| return; | ||
| } | ||
|
|
||
| $response->on('end', function ($keepAlive) use ($conn, $parser) { | ||
| $conn->removeAllListeners(); // stop data being sent to this Request instance | ||
| if ($keepAlive) { | ||
| $conn->on('data', array($parser, 'feed')); // resume sending data to RequestHeaderParser | ||
| $conn->on('end', function () use ($parser) { | ||
| $parser->removeAllListeners(); | ||
| }); | ||
| } | ||
| else { | ||
| $parser->removeAllListeners(); | ||
| } | ||
| }); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe we should also do a
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When keeping the connection alive, the RequestHeaderParser continues to emit 'header' events so removing the listeners would prevent subsequent header events from being handled.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, good point! I was/am worried about resource cleanup that is no longer happening here. |
||
|
|
||
| $this->emit('request', array($request, $response)); | ||
| $request->emit('data', array($bodyBuffer)); | ||
| } | ||
|
|
||
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.
Can you give some example code on how you expect this to be used?
It's my understanding that the
Responseobject should behave like aWritableStreamInterface, i.e. end()ing this only terminates its "virtual stream" and should not have any effect on the underlying socket connection. IMO it should be up to the server to determine when the close the underlying connection.Any info on how other HTTP libs handle this?
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.
Yeah it could be neater for the http framework to handle closing connections rather than leaving each request handler do it.
The Request object could process the received headers according to http://tools.ietf.org/html/rfc7230#section-6.3 to know when to close a connection. In addition the writeHead function would need to check for presence of a "Connection: Close" header in the response, to close the connection when present.
This would seem to mimic the behaviour of PHP scripts running under Apache.