summaryrefslogtreecommitdiff
path: root/samples/net/http_client/src/http_client_rcv.c
blob: 5c6a220dcf4e0b4c959c312451e6e33ae0e15272 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "http_client_rcv.h"
#include "http_client_types.h"
#include "config.h"

#include <net/nbuf.h>

#ifdef LINEARIZE_BUFFER

NET_BUF_POOL_DEFINE(http_pool, HTTP_POOL_BUF_CTR, HTTP_POOL_BUF_SIZE, 0, NULL);

void http_receive_cb(struct tcp_client_ctx *tcp_ctx, struct net_buf *rx)
{
	struct http_client_ctx *http_ctx;
	struct net_buf *data_buf = NULL;
	uint16_t data_len;
	uint16_t offset;
	int rc;

	if (!rx) {
		return;
	}

	data_buf = net_buf_alloc(&http_pool, tcp_ctx->timeout);
	if (data_buf == NULL) {
		goto lb_exit;
	}

	data_len = min(net_nbuf_appdatalen(rx), HTTP_POOL_BUF_SIZE);
	offset = net_buf_frags_len(rx) - data_len;

	rc = net_nbuf_linear_copy(data_buf, rx, offset, data_len);
	if (rc != 0) {
		rc = -ENOMEM;
		goto lb_exit;
	}

	http_ctx = CONTAINER_OF(tcp_ctx, struct http_client_ctx, tcp_ctx);

	/* The parser's error can be catched outside, reading the
	 * http_errno struct member
	 */
	http_parser_execute(&http_ctx->parser, &http_ctx->settings,
			    data_buf->data, data_buf->len);

lb_exit:
	net_buf_unref(data_buf);
	net_buf_unref(rx);
}

#else

void http_receive_cb(struct tcp_client_ctx *tcp_ctx, struct net_buf *rx)
{
	struct http_client_ctx *http_ctx;
	struct net_buf *buf = rx;
	uint16_t offset;

	if (!rx) {
		return;
	}

	http_ctx = CONTAINER_OF(tcp_ctx, struct http_client_ctx, tcp_ctx);

	offset = net_buf_frags_len(buf) - net_nbuf_appdatalen(buf);

	/* find the fragment */
	while (buf && offset >= buf->len) {
		offset -= buf->len;
		buf = buf->frags;
	}

	while (buf) {
		(void)http_parser_execute(&http_ctx->parser,
					  &http_ctx->settings,
					  buf->data + offset,
					  buf->len - offset);

		/* after the first iteration, we set offset to 0 */
		offset = 0;

		/* The parser's error can be catched outside, reading the
		 * http_errno struct member
		 */
		if (http_ctx->parser.http_errno != HPE_OK) {
			goto lb_exit;
		}

		buf = buf->frags;
	}

lb_exit:
	net_buf_unref(rx);
}

#endif