Remove network specific default and max log level setting and start to use the zephyr logging values for those. Remove LOG_MODULE_REGISTER() from net_core.h and place the calls into .c files. This is done in order to avoid weird compiler errors in some cases and to make the code look similar as other subsystems. Fixes #11343 Fixes #11659 Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
739 lines
16 KiB
C
739 lines
16 KiB
C
/*
|
|
* Copyright (c) 2017 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <logging/log.h>
|
|
LOG_MODULE_DECLARE(net_http, CONFIG_HTTP_LOG_LEVEL);
|
|
|
|
#include <zephyr.h>
|
|
#include <string.h>
|
|
#include <strings.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <version.h>
|
|
|
|
#include <net/net_core.h>
|
|
#include <net/net_ip.h>
|
|
#include <net/http.h>
|
|
|
|
#include "../../ip/net_private.h"
|
|
|
|
#define BUF_ALLOC_TIMEOUT 100
|
|
|
|
#define RC_STR(rc) (rc == 0 ? "OK" : "ERROR")
|
|
|
|
#define HTTP_EOF "\r\n\r\n"
|
|
|
|
#define HTTP_HOST "Host"
|
|
#define HTTP_CONTENT_TYPE "Content-Type"
|
|
#define HTTP_CONTENT_LEN "Content-Length"
|
|
#define HTTP_CONT_LEN_SIZE 6
|
|
|
|
/* Default network activity timeout in seconds */
|
|
#define HTTP_NETWORK_TIMEOUT K_SECONDS(CONFIG_HTTP_CLIENT_NETWORK_TIMEOUT)
|
|
|
|
int client_reset(struct http_ctx *ctx)
|
|
{
|
|
http_parser_init(&ctx->http.parser, HTTP_RESPONSE);
|
|
|
|
(void)memset(ctx->http.rsp.http_status, 0,
|
|
sizeof(ctx->http.rsp.http_status));
|
|
|
|
ctx->http.rsp.cl_present = 0;
|
|
ctx->http.rsp.content_length = 0;
|
|
ctx->http.rsp.processed = 0;
|
|
ctx->http.rsp.body_found = 0;
|
|
ctx->http.rsp.message_complete = 0;
|
|
ctx->http.rsp.body_start = NULL;
|
|
|
|
(void)memset(ctx->http.rsp.response_buf, 0,
|
|
ctx->http.rsp.response_buf_len);
|
|
ctx->http.rsp.data_len = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int http_request(struct http_ctx *ctx, struct http_request *req, s32_t timeout,
|
|
void *user_data)
|
|
{
|
|
const char *method = http_method_str(req->method);
|
|
int ret;
|
|
|
|
if (ctx->pending) {
|
|
net_pkt_unref(ctx->pending);
|
|
ctx->pending = NULL;
|
|
}
|
|
|
|
ret = http_add_header(ctx, method, NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
|
|
ret = http_add_header(ctx, " ", NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
|
|
ret = http_add_header(ctx, req->url, NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
|
|
ret = http_add_header(ctx, req->protocol, NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
|
|
ret = http_add_header(ctx, HTTP_CRLF, NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
|
|
if (req->host) {
|
|
ret = http_add_header_field(ctx, HTTP_HOST, req->host,
|
|
NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (req->header_fields) {
|
|
ret = http_add_header(ctx, req->header_fields, NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (req->content_type_value) {
|
|
ret = http_add_header_field(ctx, HTTP_CONTENT_TYPE,
|
|
req->content_type_value,
|
|
NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (req->payload && req->payload_size) {
|
|
char content_len_str[HTTP_CONT_LEN_SIZE];
|
|
|
|
ret = snprintk(content_len_str, HTTP_CONT_LEN_SIZE,
|
|
"%u", req->payload_size);
|
|
if (ret <= 0 || ret >= HTTP_CONT_LEN_SIZE) {
|
|
ret = -ENOMEM;
|
|
goto out;
|
|
}
|
|
|
|
ret = http_add_header_field(ctx, HTTP_CONTENT_LEN,
|
|
content_len_str,
|
|
NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
|
|
ret = http_add_header(ctx, HTTP_CRLF, NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
|
|
ret = http_prepare_and_send(ctx, req->payload,
|
|
req->payload_size,
|
|
NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
} else {
|
|
ret = http_add_header(ctx, HTTP_EOF, NULL, user_data);
|
|
if (ret < 0) {
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
http_send_flush(ctx, user_data);
|
|
|
|
out:
|
|
if (ctx->pending) {
|
|
net_pkt_unref(ctx->pending);
|
|
ctx->pending = NULL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void sprint_addr(char *buf, int len,
|
|
sa_family_t family,
|
|
struct sockaddr *addr)
|
|
{
|
|
if (family == AF_INET6) {
|
|
net_addr_ntop(AF_INET6, &net_sin6(addr)->sin6_addr, buf, len);
|
|
} else if (family == AF_INET) {
|
|
net_addr_ntop(AF_INET, &net_sin(addr)->sin_addr, buf, len);
|
|
} else {
|
|
NET_DBG("Invalid protocol family");
|
|
}
|
|
}
|
|
|
|
static inline void print_info(struct http_ctx *ctx,
|
|
enum http_method method)
|
|
{
|
|
if (CONFIG_HTTP_LOG_LEVEL >= LOG_LEVEL_INF) {
|
|
char local[NET_IPV6_ADDR_LEN];
|
|
char remote[NET_IPV6_ADDR_LEN];
|
|
|
|
sprint_addr(local, NET_IPV6_ADDR_LEN,
|
|
ctx->app_ctx.default_ctx->local.sa_family,
|
|
&ctx->app_ctx.default_ctx->local);
|
|
|
|
sprint_addr(remote, NET_IPV6_ADDR_LEN,
|
|
ctx->app_ctx.default_ctx->remote.sa_family,
|
|
&ctx->app_ctx.default_ctx->remote);
|
|
|
|
NET_DBG("HTTP %s (%s) %s -> %s port %d",
|
|
http_method_str(method),
|
|
log_strdup(ctx->http.req.host), log_strdup(local),
|
|
log_strdup(remote),
|
|
ntohs(net_sin(&ctx->app_ctx.default_ctx->remote)->
|
|
sin_port));
|
|
}
|
|
}
|
|
|
|
int http_client_send_req(struct http_ctx *ctx,
|
|
struct http_request *req,
|
|
http_response_cb_t cb,
|
|
u8_t *response_buf,
|
|
size_t response_buf_len,
|
|
void *user_data,
|
|
s32_t timeout)
|
|
{
|
|
int ret;
|
|
|
|
if (!response_buf || response_buf_len == 0) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
ctx->http.rsp.response_buf = response_buf;
|
|
ctx->http.rsp.response_buf_len = response_buf_len;
|
|
|
|
client_reset(ctx);
|
|
|
|
if (!req->host) {
|
|
req->host = ctx->server;
|
|
}
|
|
|
|
ctx->http.req.host = req->host;
|
|
ctx->http.req.method = req->method;
|
|
ctx->http.req.user_data = user_data;
|
|
|
|
ctx->http.rsp.cb = cb;
|
|
|
|
ret = net_app_connect(&ctx->app_ctx, HTTP_NETWORK_TIMEOUT);
|
|
if (ret < 0) {
|
|
NET_DBG("Cannot connect to server (%d)", ret);
|
|
return ret;
|
|
}
|
|
|
|
/* We might wait longer than timeout if the first connection
|
|
* establishment takes long time (like with HTTPS)
|
|
*/
|
|
if (k_sem_take(&ctx->http.connect_wait, HTTP_NETWORK_TIMEOUT)) {
|
|
NET_DBG("Connection timed out");
|
|
ret = -ETIMEDOUT;
|
|
goto out;
|
|
}
|
|
|
|
print_info(ctx, ctx->http.req.method);
|
|
|
|
ret = http_request(ctx, req, timeout, user_data);
|
|
if (ret < 0) {
|
|
NET_DBG("Send error (%d)", ret);
|
|
goto out;
|
|
}
|
|
|
|
if (timeout != 0 && k_sem_take(&ctx->http.req.wait, timeout)) {
|
|
ret = -ETIMEDOUT;
|
|
goto out;
|
|
}
|
|
|
|
if (timeout == 0) {
|
|
return -EINPROGRESS;
|
|
}
|
|
|
|
return 0;
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static void print_header_field(size_t len, const char *str)
|
|
{
|
|
if (CONFIG_HTTP_LOG_LEVEL >= LOG_LEVEL_INF) {
|
|
#define MAX_OUTPUT_LEN 128
|
|
char output[MAX_OUTPUT_LEN];
|
|
|
|
/* The value of len does not count \0 so we need to increase it
|
|
* by one.
|
|
*/
|
|
if ((len + 1) > sizeof(output)) {
|
|
len = sizeof(output) - 1;
|
|
}
|
|
|
|
snprintk(output, len + 1, "%s", str);
|
|
|
|
NET_DBG("[%zd] %s", len, log_strdup(output));
|
|
}
|
|
}
|
|
|
|
static int on_url(struct http_parser *parser, const char *at, size_t length)
|
|
{
|
|
ARG_UNUSED(parser);
|
|
|
|
print_header_field(length, at);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int on_status(struct http_parser *parser, const char *at, size_t length)
|
|
{
|
|
u16_t len;
|
|
struct http_ctx *ctx = CONTAINER_OF(parser,
|
|
struct http_ctx,
|
|
http.parser);
|
|
|
|
len = min(length, sizeof(ctx->http.rsp.http_status) - 1);
|
|
memcpy(ctx->http.rsp.http_status, at, len);
|
|
ctx->http.rsp.http_status[len] = 0;
|
|
|
|
NET_DBG("HTTP response status %s",
|
|
log_strdup(ctx->http.rsp.http_status));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int on_header_field(struct http_parser *parser, const char *at,
|
|
size_t length)
|
|
{
|
|
const char *content_len = HTTP_CONTENT_LEN;
|
|
struct http_ctx *ctx = CONTAINER_OF(parser,
|
|
struct http_ctx,
|
|
http.parser);
|
|
u16_t len;
|
|
|
|
len = strlen(content_len);
|
|
if (length >= len && memcmp(at, content_len, len) == 0) {
|
|
ctx->http.rsp.cl_present = true;
|
|
}
|
|
|
|
print_header_field(length, at);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define MAX_NUM_DIGITS 16
|
|
|
|
static int on_header_value(struct http_parser *parser, const char *at,
|
|
size_t length)
|
|
{
|
|
char str[MAX_NUM_DIGITS];
|
|
struct http_ctx *ctx = CONTAINER_OF(parser,
|
|
struct http_ctx,
|
|
http.parser);
|
|
|
|
if (ctx->http.rsp.cl_present) {
|
|
if (length <= MAX_NUM_DIGITS - 1) {
|
|
long int num;
|
|
|
|
memcpy(str, at, length);
|
|
str[length] = 0;
|
|
|
|
num = strtol(str, NULL, 10);
|
|
if (num == LONG_MIN || num == LONG_MAX) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
ctx->http.rsp.content_length = num;
|
|
}
|
|
|
|
ctx->http.rsp.cl_present = false;
|
|
}
|
|
|
|
print_header_field(length, at);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int on_body(struct http_parser *parser, const char *at, size_t length)
|
|
{
|
|
struct http_ctx *ctx = CONTAINER_OF(parser,
|
|
struct http_ctx,
|
|
http.parser);
|
|
|
|
ctx->http.rsp.body_found = 1;
|
|
ctx->http.rsp.processed += length;
|
|
|
|
NET_DBG("Processed %zd length %zd", ctx->http.rsp.processed, length);
|
|
|
|
if (!ctx->http.rsp.body_start &&
|
|
(u8_t *)at != (u8_t *)ctx->http.rsp.response_buf) {
|
|
ctx->http.rsp.body_start = (u8_t *)at;
|
|
}
|
|
|
|
if (ctx->http.rsp.cb) {
|
|
NET_DBG("Calling callback for partitioned %zd len data",
|
|
ctx->http.rsp.data_len);
|
|
|
|
ctx->http.rsp.cb(ctx,
|
|
ctx->http.rsp.response_buf,
|
|
ctx->http.rsp.response_buf_len,
|
|
ctx->http.rsp.data_len,
|
|
HTTP_DATA_MORE,
|
|
ctx->http.req.user_data);
|
|
|
|
/* Re-use the result buffer and start to fill it again */
|
|
ctx->http.rsp.data_len = 0;
|
|
ctx->http.rsp.body_start = NULL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int on_headers_complete(struct http_parser *parser)
|
|
{
|
|
struct http_ctx *ctx = CONTAINER_OF(parser,
|
|
struct http_ctx,
|
|
http.parser);
|
|
|
|
if (parser->status_code >= 500 && parser->status_code < 600) {
|
|
NET_DBG("Status %d, skipping body", parser->status_code);
|
|
|
|
return 1;
|
|
}
|
|
|
|
if ((ctx->http.req.method == HTTP_HEAD ||
|
|
ctx->http.req.method == HTTP_OPTIONS)
|
|
&& ctx->http.rsp.content_length > 0) {
|
|
NET_DBG("No body expected");
|
|
return 1;
|
|
}
|
|
|
|
if ((ctx->http.req.method == HTTP_PUT ||
|
|
ctx->http.req.method == HTTP_POST)
|
|
&& ctx->http.rsp.content_length == 0) {
|
|
NET_DBG("No body expected");
|
|
return 1;
|
|
}
|
|
|
|
NET_DBG("Headers complete");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int on_message_begin(struct http_parser *parser)
|
|
{
|
|
if (CONFIG_HTTP_LOG_LEVEL >= LOG_LEVEL_INF) {
|
|
struct http_ctx *ctx = CONTAINER_OF(parser,
|
|
struct http_ctx,
|
|
http.parser);
|
|
|
|
NET_DBG("-- HTTP %s response (headers) --",
|
|
http_method_str(ctx->http.req.method));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int on_message_complete(struct http_parser *parser)
|
|
{
|
|
struct http_ctx *ctx = CONTAINER_OF(parser,
|
|
struct http_ctx,
|
|
http.parser);
|
|
|
|
NET_DBG("-- HTTP %s response (complete) --",
|
|
http_method_str(ctx->http.req.method));
|
|
|
|
if (ctx->http.rsp.cb) {
|
|
ctx->http.rsp.cb(ctx,
|
|
ctx->http.rsp.response_buf,
|
|
ctx->http.rsp.response_buf_len,
|
|
ctx->http.rsp.data_len,
|
|
HTTP_DATA_FINAL,
|
|
ctx->http.req.user_data);
|
|
}
|
|
|
|
ctx->http.rsp.message_complete = 1;
|
|
|
|
k_sem_give(&ctx->http.req.wait);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int on_chunk_header(struct http_parser *parser)
|
|
{
|
|
ARG_UNUSED(parser);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int on_chunk_complete(struct http_parser *parser)
|
|
{
|
|
ARG_UNUSED(parser);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void http_received(struct net_app_ctx *app_ctx,
|
|
struct net_pkt *pkt,
|
|
int status,
|
|
void *user_data)
|
|
{
|
|
struct http_ctx *ctx = user_data;
|
|
size_t start = ctx->http.rsp.data_len;
|
|
u16_t len = 0U;
|
|
struct net_buf *frag, *prev_frag = NULL;
|
|
size_t recv_len;
|
|
size_t pkt_len;
|
|
|
|
recv_len = net_pkt_appdatalen(pkt);
|
|
if (recv_len == 0) {
|
|
/* don't print info about zero-length app data buffers */
|
|
goto quit;
|
|
}
|
|
|
|
if (status) {
|
|
NET_DBG("[%p] Status %d <%s>", ctx, status, RC_STR(status));
|
|
goto out;
|
|
}
|
|
|
|
/* Get rid of possible IP headers in the first fragment. */
|
|
frag = pkt->frags;
|
|
|
|
pkt_len = net_pkt_get_len(pkt);
|
|
|
|
if (recv_len < pkt_len) {
|
|
net_buf_pull(frag, pkt_len - recv_len);
|
|
net_pkt_set_appdata(pkt, frag->data);
|
|
}
|
|
|
|
NET_DBG("[%p] Received %zd bytes http data", ctx, recv_len);
|
|
|
|
while (frag) {
|
|
/* If this fragment cannot be copied to result buf,
|
|
* then parse what we have which will cause the callback to be
|
|
* called in function on_body(), and continue copying.
|
|
*/
|
|
if ((ctx->http.rsp.data_len + frag->len) >
|
|
ctx->http.rsp.response_buf_len) {
|
|
|
|
/* If the caller has not supplied a callback, then
|
|
* we cannot really continue if the request buffer
|
|
* overflows. Set the data_len to mark how many bytes
|
|
* should be needed in the response_buf.
|
|
*/
|
|
if (!ctx->cb.recv) {
|
|
ctx->http.rsp.data_len = recv_len;
|
|
goto out;
|
|
}
|
|
|
|
http_parser_execute(&ctx->http.parser,
|
|
&ctx->http.parser_settings,
|
|
ctx->http.rsp.response_buf + start,
|
|
len);
|
|
|
|
ctx->http.rsp.data_len = 0;
|
|
len = 0U;
|
|
start = 0;
|
|
}
|
|
|
|
memcpy(ctx->http.rsp.response_buf + ctx->http.rsp.data_len,
|
|
frag->data, frag->len);
|
|
|
|
ctx->http.rsp.data_len += frag->len;
|
|
len += frag->len;
|
|
|
|
prev_frag = frag;
|
|
frag = frag->frags;
|
|
pkt->frags = frag;
|
|
|
|
prev_frag->frags = NULL;
|
|
net_pkt_frag_unref(prev_frag);
|
|
}
|
|
|
|
out:
|
|
http_parser_execute(&ctx->http.parser,
|
|
&ctx->http.parser_settings,
|
|
ctx->http.rsp.response_buf + start,
|
|
len);
|
|
|
|
net_pkt_unref(pkt);
|
|
return;
|
|
|
|
quit:
|
|
http_parser_init(&ctx->http.parser, HTTP_RESPONSE);
|
|
ctx->http.rsp.data_len = 0;
|
|
net_pkt_unref(pkt);
|
|
}
|
|
|
|
static void http_data_sent(struct net_app_ctx *app_ctx,
|
|
int status,
|
|
void *user_data_send,
|
|
void *user_data)
|
|
{
|
|
struct http_ctx *ctx = user_data;
|
|
|
|
if (!user_data_send) {
|
|
/* This is the token field in the net_context_send().
|
|
* If this is not set, then it is TCP ACK messages
|
|
* that are generated by the stack. We just ignore those.
|
|
*/
|
|
return;
|
|
}
|
|
|
|
if (ctx->cb.send) {
|
|
ctx->cb.send(ctx, status, user_data_send, ctx->user_data);
|
|
}
|
|
}
|
|
|
|
static void http_connected(struct net_app_ctx *app_ctx,
|
|
int status,
|
|
void *user_data)
|
|
{
|
|
struct http_ctx *ctx = user_data;
|
|
|
|
if (status < 0) {
|
|
return;
|
|
}
|
|
|
|
if (ctx->cb.connect && app_ctx->default_ctx) {
|
|
ctx->cb.connect(ctx, HTTP_CONNECTION,
|
|
&app_ctx->default_ctx->remote,
|
|
ctx->user_data);
|
|
}
|
|
|
|
if (ctx->is_connected) {
|
|
return;
|
|
}
|
|
|
|
ctx->is_connected = true;
|
|
|
|
k_sem_give(&ctx->http.connect_wait);
|
|
}
|
|
|
|
static void http_closed(struct net_app_ctx *app_ctx,
|
|
int status,
|
|
void *user_data)
|
|
{
|
|
struct http_ctx *ctx = user_data;
|
|
|
|
ARG_UNUSED(app_ctx);
|
|
ARG_UNUSED(status);
|
|
|
|
NET_DBG("[%p] connection closed", ctx);
|
|
|
|
ctx->is_connected = false;
|
|
|
|
if (ctx->cb.close) {
|
|
ctx->cb.close(ctx, 0, ctx->user_data);
|
|
}
|
|
}
|
|
|
|
int http_client_init(struct http_ctx *ctx,
|
|
const char *server,
|
|
u16_t server_port,
|
|
struct sockaddr *server_addr,
|
|
s32_t timeout)
|
|
{
|
|
int ret;
|
|
|
|
(void)memset(ctx, 0, sizeof(*ctx));
|
|
|
|
ret = net_app_init_tcp_client(&ctx->app_ctx,
|
|
NULL, /* use any local address */
|
|
server_addr,
|
|
server,
|
|
server_port,
|
|
timeout,
|
|
ctx);
|
|
if (ret < 0) {
|
|
NET_DBG("Cannot init HTTP client (%d)", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = net_app_set_cb(&ctx->app_ctx, http_connected, http_received,
|
|
http_data_sent, http_closed);
|
|
if (ret < 0) {
|
|
NET_ERR("Cannot set callbacks (%d)", ret);
|
|
return ret;
|
|
}
|
|
|
|
ctx->http.parser_settings.on_body = on_body;
|
|
ctx->http.parser_settings.on_chunk_complete = on_chunk_complete;
|
|
ctx->http.parser_settings.on_chunk_header = on_chunk_header;
|
|
ctx->http.parser_settings.on_headers_complete = on_headers_complete;
|
|
ctx->http.parser_settings.on_header_field = on_header_field;
|
|
ctx->http.parser_settings.on_header_value = on_header_value;
|
|
ctx->http.parser_settings.on_message_begin = on_message_begin;
|
|
ctx->http.parser_settings.on_message_complete = on_message_complete;
|
|
ctx->http.parser_settings.on_status = on_status;
|
|
ctx->http.parser_settings.on_url = on_url;
|
|
|
|
k_sem_init(&ctx->http.req.wait, 0, 1);
|
|
k_sem_init(&ctx->http.connect_wait, 0, 1);
|
|
|
|
ctx->server = server;
|
|
ctx->is_init = true;
|
|
ctx->is_client = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int http_request_cancel(struct http_ctx *ctx)
|
|
{
|
|
if (!ctx->is_init) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (!ctx->is_client) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
client_reset(ctx);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if defined(CONFIG_HTTPS)
|
|
int http_client_set_tls(struct http_ctx *ctx,
|
|
u8_t *request_buf,
|
|
size_t request_buf_len,
|
|
u8_t *personalization_data,
|
|
size_t personalization_data_len,
|
|
net_app_ca_cert_cb_t cert_cb,
|
|
const char *cert_host,
|
|
net_app_entropy_src_cb_t entropy_src_cb,
|
|
struct k_mem_pool *pool,
|
|
k_thread_stack_t *https_stack,
|
|
size_t https_stack_size)
|
|
{
|
|
int ret;
|
|
|
|
ret = net_app_client_tls(&ctx->app_ctx,
|
|
request_buf,
|
|
request_buf_len,
|
|
personalization_data,
|
|
personalization_data_len,
|
|
cert_cb,
|
|
cert_host,
|
|
entropy_src_cb,
|
|
pool,
|
|
https_stack,
|
|
https_stack_size);
|
|
if (ret < 0) {
|
|
NET_DBG("Cannot init TLS (%d)", ret);
|
|
return ret;
|
|
}
|
|
|
|
ctx->is_tls = true;
|
|
|
|
return 0;
|
|
}
|
|
#endif /* CONFIG_HTTPS */
|