blob: dcf44f9bc67d744649d9c69680c18b755c626a85 [file] [log] [blame]
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "http_client.h"
#include "http_client_rcv.h"
#include "http_client_cb.h"
#include "config.h"
#include <misc/printk.h>
#include <net/nbuf.h>
int http_init(struct http_client_ctx *http_ctx)
{
memset(http_ctx, 0, sizeof(struct http_client_ctx));
http_ctx->settings.on_body = on_body;
http_ctx->settings.on_chunk_complete = on_chunk_complete;
http_ctx->settings.on_chunk_header = on_chunk_header;
http_ctx->settings.on_headers_complete = on_headers_complete;
http_ctx->settings.on_header_field = on_header_field;
http_ctx->settings.on_header_value = on_header_value;
http_ctx->settings.on_message_begin = on_message_begin;
http_ctx->settings.on_message_complete = on_message_complete;
http_ctx->settings.on_status = on_status;
http_ctx->settings.on_url = on_url;
return 0;
}
int http_reset_ctx(struct http_client_ctx *http_ctx)
{
http_parser_init(&http_ctx->parser, HTTP_RESPONSE);
memset(http_ctx->http_status, 0, sizeof(http_ctx->http_status));
http_ctx->cl_present = 0;
http_ctx->content_length = 0;
http_ctx->processed = 0;
http_ctx->body_found = 0;
return 0;
}
static
int http_send_request(struct http_client_ctx *http_ctx, const char *method,
const char *url, const char *protocol,
const char *content_type_value, const char *payload)
{
const char *content_type = "Content-Type: ";
const char *sep = "\r\n\r\n";
struct net_buf *tx;
int rc;
tx = net_nbuf_get_tx(http_ctx->tcp_ctx.net_ctx, K_FOREVER);
if (tx == NULL) {
return -ENOMEM;
}
if (!net_nbuf_append(tx, strlen(method), (uint8_t *)method,
K_FOREVER)) {
goto lb_exit;
}
if (!net_nbuf_append(tx, strlen(url), (uint8_t *)url, K_FOREVER)) {
goto lb_exit;
}
if (!net_nbuf_append(tx, strlen(protocol), (uint8_t *)protocol,
K_FOREVER)) {
goto lb_exit;
}
if (!net_nbuf_append(tx, strlen(HEADER_FIELDS),
(uint8_t *)HEADER_FIELDS, K_FOREVER)) {
goto lb_exit;
}
if (content_type_value && payload) {
char content_len_str[CON_LEN_SIZE];
if (!net_nbuf_append(tx, strlen(content_type),
(uint8_t *)content_type, K_FOREVER)) {
rc = -ENOMEM;
goto lb_exit;
}
if (!net_nbuf_append(tx, strlen(content_type_value),
(uint8_t *)content_type_value,
K_FOREVER)) {
rc = -ENOMEM;
goto lb_exit;
}
rc = snprintk(content_len_str, sizeof(content_len_str),
"\r\nContent-Length: %u\r\n\r\n",
(unsigned int)strlen(payload));
if (rc <= 0 || rc >= sizeof(content_len_str)) {
rc = -ENOMEM;
goto lb_exit;
}
if (!net_nbuf_append(tx, strlen(content_len_str),
(uint8_t *)content_len_str, K_FOREVER)) {
rc = -ENOMEM;
goto lb_exit;
}
if (!net_nbuf_append(tx, strlen(payload), (uint8_t *)payload,
K_FOREVER)) {
rc = -ENOMEM;
goto lb_exit;
}
} else {
if (!net_nbuf_append(tx, strlen(sep), (uint8_t *)sep,
K_FOREVER)) {
rc = -ENOMEM;
goto lb_exit;
}
}
return net_context_send(tx, NULL, http_ctx->tcp_ctx.timeout,
NULL, NULL);
lb_exit:
net_buf_unref(tx);
return rc;
}
int http_send_get(struct http_client_ctx *http_ctx, const char *url)
{
return http_send_request(http_ctx, "GET ", url, " HTTP/1.1\r\n",
NULL, NULL);
}
int http_send_head(struct http_client_ctx *http_ctx, const char *url)
{
return http_send_request(http_ctx, "HEAD ", url, " HTTP/1.1\r\n",
NULL, NULL);
}
int http_send_options(struct http_client_ctx *http_ctx, const char *url,
const char *content_type_value, const char *payload)
{
return http_send_request(http_ctx, "OPTIONS ", url, " HTTP/1.1\r\n",
content_type_value, payload);
}
int http_send_post(struct http_client_ctx *http_ctx, const char *url,
const char *content_type_value, const char *payload)
{
return http_send_request(http_ctx, "POST ", url, " HTTP/1.1\r\n",
content_type_value, payload);
}