@@ -257,33 +257,21 @@ static int http1_dynamic_response(struct http_client_ctx *client, struct http_re
257
257
static int dynamic_get_req (struct http_resource_detail_dynamic * dynamic_detail ,
258
258
struct http_client_ctx * client )
259
259
{
260
- /* offset tells from where the GET params start */
261
- int ret , remaining , offset = dynamic_detail -> common .path_len ;
260
+ int ret , len ;
262
261
char * ptr ;
262
+ enum http_data_status status ;
263
+ struct http_response_ctx response_ctx ;
263
264
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 ;
282
269
270
+ do {
283
271
memset (& response_ctx , 0 , sizeof (response_ctx ));
284
272
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 );
287
275
if (ret < 0 ) {
288
276
return ret ;
289
277
}
@@ -293,13 +281,9 @@ static int dynamic_get_req(struct http_resource_detail_dynamic *dynamic_detail,
293
281
return ret ;
294
282
}
295
283
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 ));
303
287
304
288
dynamic_detail -> holder = NULL ;
305
289
@@ -315,67 +299,66 @@ static int dynamic_get_req(struct http_resource_detail_dynamic *dynamic_detail,
315
299
static int dynamic_post_req (struct http_resource_detail_dynamic * dynamic_detail ,
316
300
struct http_client_ctx * client )
317
301
{
318
- /* offset tells from where the POST params start */
302
+ int ret ;
303
+ char * ptr = client -> cursor ;
304
+ enum http_data_status status ;
319
305
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 ;
324
306
325
- if (start == NULL ) {
307
+ if (ptr == NULL ) {
326
308
return - ENOENT ;
327
309
}
328
310
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
+ }
332
316
333
- ptr = & start [ offset ] ;
317
+ memset ( & response_ctx , 0 , sizeof ( response_ctx )) ;
334
318
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
+ }
336
324
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 ;
342
332
}
333
+ }
343
334
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 ) {
344
337
memset (& response_ctx , 0 , sizeof (response_ctx ));
345
338
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 );
348
341
if (ret < 0 ) {
349
342
return ret ;
350
343
}
351
344
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;
372
345
ret = http1_dynamic_response (client , & response_ctx , dynamic_detail );
373
346
if (ret < 0 ) {
374
347
return ret ;
375
348
}
376
349
}
377
350
351
+ /* At end of message, ensure response is sent and terminated */
378
352
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
+
379
362
ret = http_server_sendall (client , final_chunk ,
380
363
sizeof (final_chunk ) - 1 );
381
364
if (ret < 0 ) {
0 commit comments