Skip to content

Commit 5084c45

Browse files
Copilotithewei
andcommitted
Retire old writer before replacing to prevent hio_t close; extract hookHttpCb helper
Before creating a new HttpResponseWriter in Reset(), mark the old writer as DISCONNECTED and clear its io_ pointer. This ensures: - ~Channel() won't close the hio_t when the async handler's shared_ptr reference is eventually released (isOpened() returns false) - Any further write attempts through the retired writer fail gracefully (write() returns -1) instead of interfering with the new request Also extract the duplicated http_cb lambda from Init() and Reset() into a private hookHttpCb() helper method. Co-authored-by: ithewei <26049660+ithewei@users.noreply.github.com>
1 parent 93e11a7 commit 5084c45

2 files changed

Lines changed: 17 additions & 20 deletions

File tree

http/server/HttpHandler.cpp

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ bool HttpHandler::Init(int http_version) {
8686
tid = hv_gettid();
8787
}
8888
parser->InitRequest(req.get());
89+
hookHttpCb();
90+
return true;
91+
}
92+
93+
void HttpHandler::hookHttpCb() {
8994
// NOTE: hook http_cb
9095
req->http_cb = [this](HttpMessage* msg, http_parser_state state, const char* data, size_t size) {
9196
if (this->state == WANT_CLOSE) return;
@@ -105,7 +110,6 @@ bool HttpHandler::Init(int http_version) {
105110
break;
106111
}
107112
};
108-
return true;
109113
}
110114

111115
void HttpHandler::Reset() {
@@ -124,32 +128,24 @@ void HttpHandler::Reset() {
124128
ctx = NULL;
125129
api_handler = NULL;
126130
closeFile();
131+
if (writer) {
132+
// Retire old writer: mark DISCONNECTED and clear io_ so that
133+
// ~Channel() won't close the hio_t when the async handler's
134+
// shared_ptr reference is eventually released, and any
135+
// further write attempts through the old writer fail gracefully.
136+
writer->status = hv::SocketChannel::DISCONNECTED;
137+
writer->io_ = NULL;
138+
writer->onwrite = NULL;
139+
writer->onclose = NULL;
140+
}
127141
if (io) {
128142
writer = std::make_shared<HttpResponseWriter>(io, resp);
129143
writer->status = hv::SocketChannel::CONNECTED;
130144
} else {
131145
writer = NULL;
132146
}
133147
parser->InitRequest(req.get());
134-
// Re-hook http_cb for the new request object
135-
req->http_cb = [this](HttpMessage* msg, http_parser_state state, const char* data, size_t size) {
136-
if (this->state == WANT_CLOSE) return;
137-
switch (state) {
138-
case HP_HEADERS_COMPLETE:
139-
if (this->error != 0) return;
140-
onHeadersComplete();
141-
break;
142-
case HP_BODY:
143-
if (this->error != 0) return;
144-
onBody(data, size);
145-
break;
146-
case HP_MESSAGE_COMPLETE:
147-
onMessageComplete();
148-
break;
149-
default:
150-
break;
151-
}
152-
};
148+
hookHttpCb();
153149
}
154150

155151
void HttpHandler::Close() {

http/server/HttpHandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class HttpHandler {
149149
void addResponseHeaders();
150150

151151
// http_cb
152+
void hookHttpCb();
152153
void onHeadersComplete();
153154
void onBody(const char* data, size_t size);
154155
void onMessageComplete();

0 commit comments

Comments
 (0)