@@ -90,19 +90,93 @@ void WebServerTemplate<ServerType, DefaultPort>::handleClient() {
90
90
_currentClient = nullptr ;
91
91
}
92
92
93
- ClientType client = _server.available ();
94
- if (!client ) {
93
+ _currentClient = new ClientType ( _server.available () );
94
+ if (!_currentClient ) {
95
95
if (_nullDelay) {
96
96
delay (1 );
97
97
}
98
98
return ;
99
99
}
100
-
101
- _currentClient = new ClientType (client);
102
100
_currentStatus = HC_WAIT_READ;
103
101
_statusChange = millis ();
104
102
}
105
- httpHandleClient ();
103
+ bool keepCurrentClient = false ;
104
+ bool callYield = false ;
105
+
106
+ if (_currentClient->connected ()) {
107
+ switch (_currentStatus) {
108
+ case HC_NONE:
109
+ // No-op to avoid C++ compiler warning
110
+ break ;
111
+ case HC_WAIT_READ:
112
+ // Wait for data from client to become available
113
+ if (_currentClient->available ()) {
114
+ switch (_parseRequest (_currentClient)) {
115
+ case CLIENT_REQUEST_CAN_CONTINUE:
116
+ // Because HTTP_MAX_SEND_WAIT is expressed in milliseconds, it must be divided by 1000
117
+ _currentClient->setTimeout (HTTP_MAX_SEND_WAIT / 1000 );
118
+ _contentLength = CONTENT_LENGTH_NOT_SET;
119
+ _handleRequest ();
120
+ /* fallthrough */
121
+ case CLIENT_REQUEST_IS_HANDLED:
122
+ if (_currentClient->connected () || _currentClient->available ()) {
123
+ _currentStatus = HC_WAIT_CLOSE;
124
+ _statusChange = millis ();
125
+ keepCurrentClient = true ;
126
+ } else {
127
+ // log_v("webserver: peer has closed after served\n");
128
+ }
129
+ break ;
130
+ case CLIENT_MUST_STOP:
131
+ // log_v("Close client\n");
132
+ _currentClient->stop ();
133
+ break ;
134
+ case CLIENT_IS_GIVEN:
135
+ // client must not be stopped but must not be handled here anymore
136
+ // (example: tcp connection given to websocket)
137
+ // log_v("Give client\n");
138
+ break ;
139
+ } // switch _parseRequest()
140
+ } else {
141
+ // !_currentClient.available(): waiting for more data
142
+ unsigned long timeSinceChange = millis () - _statusChange;
143
+ // Use faster connection drop timeout if any other client has data
144
+ // or the buffer of pending clients is full
145
+ if ((_server.hasClientData () || _server.hasMaxPendingClients ())
146
+ && timeSinceChange > HTTP_MAX_DATA_AVAILABLE_WAIT) {
147
+ // log_v("webserver: closing since there's another connection to read from\r\n");
148
+ } else {
149
+ if (timeSinceChange > HTTP_MAX_DATA_WAIT) {
150
+ // log_v("webserver: closing after read timeout\r\n");
151
+ } else {
152
+ keepCurrentClient = true ;
153
+ }
154
+ }
155
+ callYield = true ;
156
+ }
157
+ break ;
158
+ case HC_WAIT_CLOSE:
159
+ // Wait for client to close the connection
160
+ if (millis () - _statusChange <= HTTP_MAX_CLOSE_WAIT) {
161
+ keepCurrentClient = true ;
162
+ callYield = true ;
163
+ }
164
+ }
165
+ }
166
+
167
+ if (!keepCurrentClient) {
168
+ if (_currentClient) {
169
+ delete _currentClient;
170
+ _currentClient = nullptr ;
171
+ }
172
+ _currentStatus = HC_NONE;
173
+ _currentUpload.reset ();
174
+ }
175
+
176
+ if (callYield) {
177
+ yield ();
178
+ }
179
+
106
180
}
107
181
108
182
template <typename ServerType, int DefaultPort>
0 commit comments