Skip to content

Commit f2d8766

Browse files
mrodgers-witekiocarlescufi
authored andcommitted
net: lib: http_server: remove dynamic resource data buffer
After introduction of struct http_response_ctx, the dynamic resource data buffer is no longer needed for transferring data between the application callback and the server. It is therefore removed to avoid unnecessary copying of data. Signed-off-by: Matt Rodgers <[email protected]>
1 parent 9606142 commit f2d8766

File tree

5 files changed

+128
-214
lines changed

5 files changed

+128
-214
lines changed

include/zephyr/net/http/server.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,6 @@ struct http_resource_detail_dynamic {
214214
*/
215215
http_resource_dynamic_cb_t cb;
216216

217-
/** Data buffer used to exchanged data between server and the,
218-
* application.
219-
*/
220-
uint8_t *data_buffer;
221-
222-
/** Length of the data in the data buffer. */
223-
size_t data_buffer_len;
224-
225217
/** A pointer to the client currently processing resource, used to
226218
* prevent concurrent access to the resource from multiple clients.
227219
*/

samples/net/sockets/http_server/src/main.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ static uint8_t main_js_gz[] = {
4545
#include "main.js.gz.inc"
4646
};
4747

48-
static uint8_t uptime_buf[256];
49-
static uint8_t led_buf[256];
50-
static uint8_t echo_buf[1024];
51-
5248
static struct http_resource_detail_static index_html_gz_resource_detail = {
5349
.common = {
5450
.type = HTTP_RESOURCE_TYPE_STATIC,
@@ -113,8 +109,6 @@ static struct http_resource_detail_dynamic echo_resource_detail = {
113109
.bitmask_of_supported_http_methods = BIT(HTTP_GET) | BIT(HTTP_POST),
114110
},
115111
.cb = echo_handler,
116-
.data_buffer = echo_buf,
117-
.data_buffer_len = sizeof(echo_buf),
118112
.user_data = NULL,
119113
};
120114

@@ -151,8 +145,6 @@ static struct http_resource_detail_dynamic uptime_resource_detail = {
151145
.bitmask_of_supported_http_methods = BIT(HTTP_GET),
152146
},
153147
.cb = uptime_handler,
154-
.data_buffer = uptime_buf,
155-
.data_buffer_len = sizeof(uptime_buf),
156148
.user_data = NULL,
157149
};
158150

@@ -219,8 +211,6 @@ static struct http_resource_detail_dynamic led_resource_detail = {
219211
.bitmask_of_supported_http_methods = BIT(HTTP_POST),
220212
},
221213
.cb = led_handler,
222-
.data_buffer = led_buf,
223-
.data_buffer_len = sizeof(led_buf),
224214
.user_data = NULL,
225215
};
226216

subsys/net/lib/http/http_server_http1.c

Lines changed: 50 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -257,33 +257,21 @@ static int http1_dynamic_response(struct http_client_ctx *client, struct http_re
257257
static int dynamic_get_req(struct http_resource_detail_dynamic *dynamic_detail,
258258
struct http_client_ctx *client)
259259
{
260-
/* offset tells from where the GET params start */
261-
int ret, remaining, offset = dynamic_detail->common.path_len;
260+
int ret, len;
262261
char *ptr;
262+
enum http_data_status status;
263+
struct http_response_ctx response_ctx;
263264

264-
remaining = strlen(&client->url_buffer[dynamic_detail->common.path_len]);
265-
266-
/* Pass URL to the client */
267-
while (1) {
268-
int copy_len;
269-
enum http_data_status status;
270-
struct http_response_ctx response_ctx;
271-
272-
ptr = &client->url_buffer[offset];
273-
copy_len = MIN(remaining, dynamic_detail->data_buffer_len);
274-
275-
memcpy(dynamic_detail->data_buffer, ptr, copy_len);
276-
277-
if (copy_len == remaining) {
278-
status = HTTP_SERVER_DATA_FINAL;
279-
} else {
280-
status = HTTP_SERVER_DATA_MORE;
281-
}
265+
/* Start of GET params */
266+
ptr = &client->url_buffer[dynamic_detail->common.path_len];
267+
len = strlen(ptr);
268+
status = HTTP_SERVER_DATA_FINAL;
282269

270+
do {
283271
memset(&response_ctx, 0, sizeof(response_ctx));
284272

285-
ret = dynamic_detail->cb(client, status, dynamic_detail->data_buffer, copy_len,
286-
&response_ctx, dynamic_detail->user_data);
273+
ret = dynamic_detail->cb(client, status, ptr, len, &response_ctx,
274+
dynamic_detail->user_data);
287275
if (ret < 0) {
288276
return ret;
289277
}
@@ -293,13 +281,9 @@ static int dynamic_get_req(struct http_resource_detail_dynamic *dynamic_detail,
293281
return ret;
294282
}
295283

296-
if (http_response_is_final(&response_ctx, status)) {
297-
break;
298-
}
299-
300-
offset += copy_len;
301-
remaining -= copy_len;
302-
}
284+
/* URL params are passed in the first cb only */
285+
len = 0;
286+
} while (!http_response_is_final(&response_ctx, status));
303287

304288
dynamic_detail->holder = NULL;
305289

@@ -315,67 +299,66 @@ static int dynamic_get_req(struct http_resource_detail_dynamic *dynamic_detail,
315299
static int dynamic_post_req(struct http_resource_detail_dynamic *dynamic_detail,
316300
struct http_client_ctx *client)
317301
{
318-
/* offset tells from where the POST params start */
302+
int ret;
303+
char *ptr = client->cursor;
304+
enum http_data_status status;
319305
struct http_response_ctx response_ctx;
320-
char *start = client->cursor;
321-
int ret, remaining = client->data_len, offset = 0;
322-
int copy_len;
323-
char *ptr;
324306

325-
if (start == NULL) {
307+
if (ptr == NULL) {
326308
return -ENOENT;
327309
}
328310

329-
copy_len = MIN(remaining, dynamic_detail->data_buffer_len);
330-
while (1) {
331-
enum http_data_status status;
311+
if (client->parser_state == HTTP1_MESSAGE_COMPLETE_STATE) {
312+
status = HTTP_SERVER_DATA_FINAL;
313+
} else {
314+
status = HTTP_SERVER_DATA_MORE;
315+
}
332316

333-
ptr = &start[offset];
317+
memset(&response_ctx, 0, sizeof(response_ctx));
334318

335-
memcpy(dynamic_detail->data_buffer, ptr, copy_len);
319+
ret = dynamic_detail->cb(client, status, ptr, client->data_len, &response_ctx,
320+
dynamic_detail->user_data);
321+
if (ret < 0) {
322+
return ret;
323+
}
336324

337-
if (copy_len == remaining &&
338-
client->parser_state == HTTP1_MESSAGE_COMPLETE_STATE) {
339-
status = HTTP_SERVER_DATA_FINAL;
340-
} else {
341-
status = HTTP_SERVER_DATA_MORE;
325+
/* For POST the application might not send a response until all data has been received.
326+
* Don't send a default response until the application has had a chance to respond.
327+
*/
328+
if (http_response_is_provided(&response_ctx)) {
329+
ret = http1_dynamic_response(client, &response_ctx, dynamic_detail);
330+
if (ret < 0) {
331+
return ret;
342332
}
333+
}
343334

335+
/* Once all data is transferred to application, repeat cb until response is complete */
336+
while (!http_response_is_final(&response_ctx, status) && status == HTTP_SERVER_DATA_FINAL) {
344337
memset(&response_ctx, 0, sizeof(response_ctx));
345338

346-
ret = dynamic_detail->cb(client, status, dynamic_detail->data_buffer, copy_len,
347-
&response_ctx, dynamic_detail->user_data);
339+
ret = dynamic_detail->cb(client, status, ptr, 0, &response_ctx,
340+
dynamic_detail->user_data);
348341
if (ret < 0) {
349342
return ret;
350343
}
351344

352-
if (http_response_is_provided(&response_ctx)) {
353-
ret = http1_dynamic_response(client, &response_ctx, dynamic_detail);
354-
if (ret < 0) {
355-
return ret;
356-
}
357-
}
358-
359-
if (http_response_is_final(&response_ctx, status)) {
360-
break;
361-
}
362-
363-
offset += copy_len;
364-
remaining -= copy_len;
365-
copy_len = MIN(remaining, dynamic_detail->data_buffer_len);
366-
}
367-
368-
/* Ensure headers are sent if not done already */
369-
if (!client->http1_headers_sent) {
370-
memset(&response_ctx, 0, sizeof(response_ctx));
371-
response_ctx.final_chunk = true;
372345
ret = http1_dynamic_response(client, &response_ctx, dynamic_detail);
373346
if (ret < 0) {
374347
return ret;
375348
}
376349
}
377350

351+
/* At end of message, ensure response is sent and terminated */
378352
if (client->parser_state == HTTP1_MESSAGE_COMPLETE_STATE) {
353+
if (!client->http1_headers_sent) {
354+
memset(&response_ctx, 0, sizeof(response_ctx));
355+
response_ctx.final_chunk = true;
356+
ret = http1_dynamic_response(client, &response_ctx, dynamic_detail);
357+
if (ret < 0) {
358+
return ret;
359+
}
360+
}
361+
379362
ret = http_server_sendall(client, final_chunk,
380363
sizeof(final_chunk) - 1);
381364
if (ret < 0) {

0 commit comments

Comments
 (0)