Skip to content

Commit 5919290

Browse files
committed
More strict handling of connection: close
1 parent 654b455 commit 5919290

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

src/AsyncSocket.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct AsyncSocket {
5050
template <bool> friend struct TemplatedApp;
5151
template <bool, typename> friend struct WebSocketContextData;
5252
template <typename, typename> friend struct TopicTree;
53+
template <bool> friend struct HttpResponse;
5354

5455
private:
5556
/* Helper, do not use directly (todo: move to uSockets or de-crazify) */

src/HttpResponse.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,21 @@ struct HttpResponse : public AsyncSocket<SSL> {
132132

133133
httpResponseData->markDone();
134134

135+
/* We need to check if we should close this socket here now */
136+
if (!Super::isCorked()) {
137+
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_CONNECTION_CLOSE) {
138+
if ((httpResponseData->state & HttpResponseData<SSL>::HTTP_RESPONSE_PENDING) == 0) {
139+
if (((AsyncSocket<SSL> *) this)->getBufferedAmount() == 0) {
140+
((AsyncSocket<SSL> *) this)->shutdown();
141+
/* We need to force close after sending FIN since we want to hinder
142+
* clients from keeping to send their huge data */
143+
((AsyncSocket<SSL> *) this)->close();
144+
return true;
145+
}
146+
}
147+
}
148+
}
149+
135150
/* tryEnd can never fail when in chunked mode, since we do not have tryWrite (yet), only write */
136151
Super::timeout(HTTP_TIMEOUT_S);
137152
return true;
@@ -182,6 +197,20 @@ struct HttpResponse : public AsyncSocket<SSL> {
182197
/* Remove onAborted function if we reach the end */
183198
if (httpResponseData->offset == totalSize) {
184199
httpResponseData->markDone();
200+
201+
/* We need to check if we should close this socket here now */
202+
if (!Super::isCorked()) {
203+
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_CONNECTION_CLOSE) {
204+
if ((httpResponseData->state & HttpResponseData<SSL>::HTTP_RESPONSE_PENDING) == 0) {
205+
if (((AsyncSocket<SSL> *) this)->getBufferedAmount() == 0) {
206+
((AsyncSocket<SSL> *) this)->shutdown();
207+
/* We need to force close after sending FIN since we want to hinder
208+
* clients from keeping to send their huge data */
209+
((AsyncSocket<SSL> *) this)->close();
210+
}
211+
}
212+
}
213+
}
185214
}
186215

187216
return success;
@@ -472,6 +501,19 @@ struct HttpResponse : public AsyncSocket<SSL> {
472501
/* This behavior should equal the behavior in HttpContext when uncorking fails */
473502
Super::timeout(HTTP_TIMEOUT_S);
474503
}
504+
505+
/* If we have no backbuffer and we are connection close and we responded fully then close */
506+
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
507+
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_CONNECTION_CLOSE) {
508+
if ((httpResponseData->state & HttpResponseData<SSL>::HTTP_RESPONSE_PENDING) == 0) {
509+
if (((AsyncSocket<SSL> *) this)->getBufferedAmount() == 0) {
510+
((AsyncSocket<SSL> *) this)->shutdown();
511+
/* We need to force close after sending FIN since we want to hinder
512+
* clients from keeping to send their huge data */
513+
((AsyncSocket<SSL> *) this)->close();
514+
}
515+
}
516+
}
475517
} else {
476518
/* We are already corked, or can't cork so let's just call the handler */
477519
handler();

0 commit comments

Comments
 (0)