sample: net: Add https-client sample application
This https-client sample starts to send HTTP GET/HEAD/POST requests same way as http-client, to https server that can be found in net-tools repository. Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
1b82463dee
commit
e90f4e1486
9 changed files with 797 additions and 0 deletions
11
samples/net/https_client/Makefile
Normal file
11
samples/net/https_client/Makefile
Normal file
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# Copyright (c) 2017 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
BOARD ?= qemu_x86
|
||||
CONF_FILE ?= prj_$(BOARD).conf
|
||||
|
||||
include $(ZEPHYR_BASE)/Makefile.inc
|
||||
include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack
|
123
samples/net/https_client/README.rst
Normal file
123
samples/net/https_client/README.rst
Normal file
|
@ -0,0 +1,123 @@
|
|||
.. _https-client-sample:
|
||||
|
||||
HTTPS Client
|
||||
############
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This sample application shows how to create encrypted HTTP 1.1 requests
|
||||
to an HTTPS server and how to parse the incoming responses.
|
||||
Supported HTTP 1.1 methods are: GET, HEAD, OPTIONS and POST.
|
||||
|
||||
The source code for this sample application can be found at:
|
||||
:file:`samples/net/https_client`.
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
- :ref:`networking_with_qemu`
|
||||
- Terminal emulator software
|
||||
- HTTPS Server
|
||||
- DNS server (optional)
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
Open the project configuration file for your platform, for example:
|
||||
:file:`prj_qemu_x86.conf` is the configuration file for QEMU.
|
||||
|
||||
To use QEMU for testing, follow the :ref:`networking_with_qemu` guide.
|
||||
|
||||
For IPv4 networks, set the following variables:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
CONFIG_NET_IPV4=y
|
||||
CONFIG_NET_IPV6=n
|
||||
|
||||
IPv6 is the preferred routing technology for this sample application,
|
||||
|
||||
In this sample application, both static IP addresses and DHCPv4 are supported.
|
||||
Static IP addresses are specified in the project configuration file,
|
||||
for example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
|
||||
CONFIG_NET_APP_PEER_IPV6_ADDR="2001:db8::2"
|
||||
|
||||
are the IPv6 addresses for the HTTPS client running Zephyr and the
|
||||
HTTPS server, respectively. The application also supports DNS resolving so the
|
||||
peer address is resolved automatically if host name is given, so you
|
||||
can also write the HTTPS server name like this:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
|
||||
CONFIG_NET_APP_PEER_IPV6_ADDR="6.zephyr.test"
|
||||
|
||||
Open the :file:`src/config.h` file and set the server port
|
||||
to match the HTTP server setup, for example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define SERVER_PORT 443
|
||||
|
||||
assumes that the HTTPS server is listening at the TCP port 443.
|
||||
If the default example HTTPS server is used (described in the next section),
|
||||
then the default port is 4443.
|
||||
|
||||
HTTPS Server
|
||||
============
|
||||
|
||||
Sample code for a very simple HTTPS server can be downloaded from the
|
||||
zephyrproject-rtos/net-tools project area:
|
||||
https://github.com/zephyrproject-rtos/net-tools
|
||||
|
||||
Open a terminal window and type:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd net-tools
|
||||
$ ./https-server.sh
|
||||
|
||||
|
||||
DNS setup
|
||||
=========
|
||||
|
||||
The net-tools project provides a simple DNS resolver. You can activate
|
||||
it like this if you want to test DNS resolving with the HTTP client.
|
||||
|
||||
Open a terminal window and type:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd net-tools
|
||||
$ ./dnsmasq.sh
|
||||
|
||||
|
||||
Sample Output
|
||||
=============
|
||||
|
||||
This sample application loops a specified number of times doing several
|
||||
HTTP 1.1 requests and printing some output. The requests are:
|
||||
|
||||
- GET "/index.html"
|
||||
- HEAD "/"
|
||||
- OPTIONS "/index.html"
|
||||
- POST "/post_test.php"
|
||||
|
||||
The terminal window where QEMU is running will show something similar
|
||||
to the following:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
[https-client] [INF] response: Received 364 bytes piece of data
|
||||
[https-client] [INF] response: HTTP server response status: OK
|
||||
[https-client] [INF] response: HTTP body: 178 bytes, expected: 178 bytes
|
||||
[https-client] [INF] response: HTTP server response status: OK
|
||||
[https-client] [INF] response: HTTP server response status: Unsupported method ('OPTIONS')
|
||||
[https-client] [INF] response: Received 163 bytes piece of data
|
||||
[https-client] [INF] response: HTTP server response status: OK
|
||||
[https-client] [INF] response: HTTP body: 24 bytes, expected: 24 bytes
|
44
samples/net/https_client/prj_frdm_k64f.conf
Normal file
44
samples/net/https_client/prj_frdm_k64f.conf
Normal file
|
@ -0,0 +1,44 @@
|
|||
CONFIG_RANDOM_GENERATOR=y
|
||||
|
||||
CONFIG_NETWORKING=y
|
||||
CONFIG_NET_TCP=y
|
||||
CONFIG_NET_ARP=y
|
||||
CONFIG_NET_L2_ETHERNET=y
|
||||
CONFIG_NET_LOG=y
|
||||
CONFIG_NET_SHELL=y
|
||||
|
||||
CONFIG_NET_IFACE_UNICAST_IPV4_ADDR_COUNT=2
|
||||
CONFIG_NET_IFACE_UNICAST_IPV6_ADDR_COUNT=2
|
||||
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=5
|
||||
|
||||
CONFIG_INIT_STACKS=y
|
||||
|
||||
CONFIG_NET_PKT_RX_COUNT=64
|
||||
CONFIG_NET_PKT_TX_COUNT=64
|
||||
CONFIG_NET_BUF_RX_COUNT=64
|
||||
CONFIG_NET_BUF_TX_COUNT=64
|
||||
|
||||
CONFIG_NET_IPV4=y
|
||||
CONFIG_NET_DHCPV4=y
|
||||
CONFIG_NET_IPV6=y
|
||||
|
||||
CONFIG_HTTP_CLIENT=y
|
||||
CONFIG_HTTPS=y
|
||||
CONFIG_MBEDTLS=y
|
||||
CONFIG_MBEDTLS_BUILTIN=y
|
||||
CONFIG_MBEDTLS_CFG_FILE="config-mini-tls1_2.h"
|
||||
|
||||
CONFIG_STDOUT_CONSOLE=y
|
||||
CONFIG_NET_SHELL=y
|
||||
|
||||
# Set the IP addresses here or in the
|
||||
# src/config.h file
|
||||
#
|
||||
CONFIG_NET_APP_SETTINGS=y
|
||||
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
|
||||
CONFIG_NET_APP_PEER_IPV6_ADDR="2001:db8::2"
|
||||
CONFIG_NET_APP_MY_IPV4_ADDR="192.0.2.1"
|
||||
CONFIG_NET_APP_PEER_IPV4_ADDR="192.0.2.2"
|
||||
|
||||
CONFIG_NET_MGMT=y
|
||||
CONFIG_NET_MGMT_EVENT=y
|
54
samples/net/https_client/prj_qemu_x86.conf
Normal file
54
samples/net/https_client/prj_qemu_x86.conf
Normal file
|
@ -0,0 +1,54 @@
|
|||
CONFIG_NETWORKING=y
|
||||
CONFIG_NET_TCP=y
|
||||
CONFIG_RANDOM_GENERATOR=y
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NET_LOG=y
|
||||
CONFIG_NET_SLIP_TAP=y
|
||||
CONFIG_INIT_STACKS=y
|
||||
|
||||
CONFIG_NET_PKT_RX_COUNT=64
|
||||
CONFIG_NET_PKT_TX_COUNT=64
|
||||
CONFIG_NET_BUF_RX_COUNT=64
|
||||
CONFIG_NET_BUF_TX_COUNT=64
|
||||
|
||||
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=2
|
||||
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=5
|
||||
|
||||
CONFIG_INIT_STACKS=y
|
||||
|
||||
CONFIG_SYS_LOG_SHOW_COLOR=y
|
||||
CONFIG_SYS_LOG_NET_LEVEL=4
|
||||
#CONFIG_NET_DEBUG_HTTP=y
|
||||
|
||||
CONFIG_HTTP_CLIENT=y
|
||||
CONFIG_HTTPS=y
|
||||
CONFIG_MBEDTLS=y
|
||||
CONFIG_MBEDTLS_BUILTIN=y
|
||||
CONFIG_MBEDTLS_CFG_FILE="config-mini-tls1_2.h"
|
||||
|
||||
CONFIG_NET_IPV6=y
|
||||
CONFIG_NET_IPV4=y
|
||||
CONFIG_NET_DHCPV4=y
|
||||
|
||||
CONFIG_NET_APP_SETTINGS=y
|
||||
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
|
||||
CONFIG_NET_APP_PEER_IPV6_ADDR="2001:db8::2"
|
||||
|
||||
CONFIG_NET_APP_MY_IPV4_ADDR="192.0.2.1"
|
||||
CONFIG_NET_APP_PEER_IPV4_ADDR="192.0.2.2"
|
||||
|
||||
CONFIG_NET_SHELL=y
|
||||
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
CONFIG_DNS_RESOLVER_ADDITIONAL_BUF_CTR=2
|
||||
CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES=2
|
||||
CONFIG_DNS_RESOLVER_MAX_SERVERS=2
|
||||
CONFIG_DNS_SERVER_IP_ADDRESSES=y
|
||||
CONFIG_DNS_NUM_CONCUR_QUERIES=2
|
||||
|
||||
CONFIG_NET_MGMT=y
|
||||
CONFIG_NET_MGMT_EVENT=y
|
||||
|
||||
# Example DNS servers running in linux using dnsmasq
|
||||
CONFIG_DNS_SERVER1="192.0.2.2:5353"
|
||||
CONFIG_DNS_SERVER2="[2001:db8::2]:5353"
|
9
samples/net/https_client/src/Makefile
Normal file
9
samples/net/https_client/src/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# Copyright (c) 2017 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
include $(ZEPHYR_BASE)/samples/net/common/Makefile.common
|
||||
|
||||
obj-y += main.o
|
25
samples/net/https_client/src/config.h
Normal file
25
samples/net/https_client/src/config.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define APP_REQ_TIMEOUT K_SECONDS(5)
|
||||
|
||||
/* The startup time needs to be longish if DHCP is enabled as setting
|
||||
* DHCP up takes some time.
|
||||
*/
|
||||
#define APP_STARTUP_TIME K_SECONDS(20)
|
||||
|
||||
#define POST_CONTENT_TYPE "application/x-www-form-urlencoded"
|
||||
#define POST_PAYLOAD "os=ZephyrRTOS&arch=" CONFIG_ARCH
|
||||
|
||||
#define SERVER_PORT 4443
|
||||
|
||||
#define HOSTNAME "localhost" /* for cert verification if that is enabled */
|
||||
|
||||
#if defined(CONFIG_NET_IPV6)
|
||||
#define SERVER_ADDR CONFIG_NET_APP_PEER_IPV6_ADDR
|
||||
#else
|
||||
#define SERVER_ADDR CONFIG_NET_APP_PEER_IPV4_ADDR
|
||||
#endif
|
406
samples/net/https_client/src/main.c
Normal file
406
samples/net/https_client/src/main.c
Normal file
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#if 1
|
||||
#define SYS_LOG_DOMAIN "https-client"
|
||||
#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
|
||||
#define NET_LOG_ENABLED 1
|
||||
#endif
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <net/net_core.h>
|
||||
#include <net/net_ip.h>
|
||||
|
||||
#include <net/http.h>
|
||||
|
||||
#include <net_sample_app.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define INSTANCE_INFO "Zephyr HTTPS example client #1"
|
||||
|
||||
#define MAX_ITERATIONS 20
|
||||
#define WAIT_TIME (APP_REQ_TIMEOUT * 2)
|
||||
|
||||
#define RESULT_BUF_SIZE 2048
|
||||
static u8_t result[RESULT_BUF_SIZE];
|
||||
|
||||
/* Note that each HTTPS context needs its own stack as there will be
|
||||
* a separate thread for each HTTPS context.
|
||||
*/
|
||||
NET_STACK_DEFINE(HTTPS_CLIENT, https_stack,
|
||||
CONFIG_HTTPS_STACK_SIZE, CONFIG_HTTPS_STACK_SIZE);
|
||||
|
||||
#define RX_FIFO_DEPTH 4
|
||||
K_MEM_POOL_DEFINE(ssl_rx_pool, 4, 64, RX_FIFO_DEPTH, 4);
|
||||
|
||||
/*
|
||||
* Note that the http_client_ctx is quite large so be careful if that is
|
||||
* allocated from stack.
|
||||
*/
|
||||
static struct http_client_ctx https_ctx;
|
||||
|
||||
struct waiter {
|
||||
struct http_client_ctx *ctx;
|
||||
struct k_sem wait;
|
||||
size_t total_len;
|
||||
size_t header_len;
|
||||
};
|
||||
|
||||
#include "test_certs.h"
|
||||
|
||||
void panic(const char *msg)
|
||||
{
|
||||
if (msg) {
|
||||
NET_ERR("%s", msg);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
k_sleep(K_FOREVER);
|
||||
}
|
||||
}
|
||||
|
||||
/* Load the certificates etc. In this sample app, we verify that
|
||||
* the server is the test server we are communicating against to.
|
||||
*/
|
||||
static int setup_cert(struct http_client_ctx *ctx, void *cert)
|
||||
{
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
|
||||
mbedtls_ssl_conf_psk(&ctx->https.mbedtls.conf,
|
||||
client_psk, sizeof(client_psk),
|
||||
(const unsigned char *)client_psk_id,
|
||||
sizeof(client_psk_id) - 1);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
{
|
||||
mbedtls_x509_crt *ca_cert = cert;
|
||||
int ret;
|
||||
|
||||
ret = mbedtls_x509_crt_parse_der(ca_cert,
|
||||
ca_certificate,
|
||||
sizeof(ca_certificate));
|
||||
if (ret != 0) {
|
||||
NET_ERR("mbedtls_x509_crt_parse_der failed "
|
||||
"(-0x%x)", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_ca_chain(&ctx->https.mbedtls.conf,
|
||||
ca_cert, NULL);
|
||||
mbedtls_ssl_conf_authmode(&ctx->https.mbedtls.conf,
|
||||
MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
|
||||
mbedtls_ssl_conf_cert_profile(&ctx->https.mbedtls.conf,
|
||||
&mbedtls_x509_crt_profile_default);
|
||||
}
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_sync_http_req(struct http_client_ctx *ctx,
|
||||
enum http_method method,
|
||||
const char *url,
|
||||
const char *content_type,
|
||||
const char *payload)
|
||||
{
|
||||
struct http_client_request req = {};
|
||||
int ret;
|
||||
|
||||
req.method = method;
|
||||
req.url = url;
|
||||
req.protocol = " " HTTP_PROTOCOL HTTP_CRLF;
|
||||
|
||||
ret = http_client_send_req(ctx, &req, NULL, result, sizeof(result),
|
||||
NULL, APP_REQ_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
NET_ERR("Cannot send %s request (%d)", http_method_str(method),
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ctx->rsp.data_len > sizeof(result)) {
|
||||
NET_ERR("Result buffer overflow by %zd bytes",
|
||||
ctx->rsp.data_len - sizeof(result));
|
||||
|
||||
ret = -E2BIG;
|
||||
} else {
|
||||
NET_INFO("HTTP server response status: %s",
|
||||
ctx->rsp.http_status);
|
||||
|
||||
if (ctx->parser.http_errno) {
|
||||
if (method == HTTP_OPTIONS) {
|
||||
/* Ignore error if OPTIONS is not found */
|
||||
goto out;
|
||||
}
|
||||
|
||||
NET_INFO("HTTP parser status: %s",
|
||||
http_errno_description(ctx->parser.http_errno));
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Our example server does not support OPTIONS so check that
|
||||
* here too.
|
||||
*/
|
||||
if (method != HTTP_HEAD && method != HTTP_OPTIONS) {
|
||||
if (ctx->rsp.body_found) {
|
||||
NET_INFO("HTTP body: %zd bytes, "
|
||||
"expected: %zd bytes",
|
||||
ctx->rsp.processed,
|
||||
ctx->rsp.content_length);
|
||||
} else {
|
||||
NET_ERR("Error detected during HTTP msg "
|
||||
"processing");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void response(struct http_client_ctx *ctx,
|
||||
u8_t *data, size_t buflen,
|
||||
size_t datalen,
|
||||
enum http_final_call data_end,
|
||||
void *user_data)
|
||||
{
|
||||
struct waiter *waiter = user_data;
|
||||
int ret;
|
||||
|
||||
if (data_end == HTTP_DATA_MORE) {
|
||||
NET_INFO("Received %zd bytes piece of data", datalen);
|
||||
|
||||
/* Do something with the data here. For this example
|
||||
* we just ignore the received data.
|
||||
*/
|
||||
waiter->total_len += datalen;
|
||||
|
||||
if (ctx->rsp.body_start) {
|
||||
/* This fragment contains the start of the body
|
||||
* Note that the header length is not proper if
|
||||
* the header is spanning over multiple recv
|
||||
* fragments.
|
||||
*/
|
||||
waiter->header_len = ctx->rsp.body_start -
|
||||
ctx->rsp.response_buf;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
waiter->total_len += datalen;
|
||||
|
||||
NET_INFO("HTTP server response status: %s", ctx->rsp.http_status);
|
||||
|
||||
if (ctx->parser.http_errno) {
|
||||
if (ctx->req.method == HTTP_OPTIONS) {
|
||||
/* Ignore error if OPTIONS is not found */
|
||||
goto out;
|
||||
}
|
||||
|
||||
NET_INFO("HTTP parser status: %s",
|
||||
http_errno_description(ctx->parser.http_errno));
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ctx->req.method != HTTP_HEAD && ctx->req.method != HTTP_OPTIONS) {
|
||||
if (ctx->rsp.body_found) {
|
||||
NET_INFO("HTTP body: %zd bytes, expected: %zd bytes",
|
||||
ctx->rsp.processed, ctx->rsp.content_length);
|
||||
} else {
|
||||
NET_ERR("Error detected during HTTP msg processing");
|
||||
}
|
||||
|
||||
if (waiter->total_len !=
|
||||
waiter->header_len + ctx->rsp.content_length) {
|
||||
NET_ERR("Error while receiving data, "
|
||||
"received %zd expected %zd bytes",
|
||||
waiter->total_len, waiter->header_len +
|
||||
ctx->rsp.content_length);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
k_sem_give(&waiter->wait);
|
||||
}
|
||||
|
||||
static int do_async_http_req(struct http_client_ctx *ctx,
|
||||
enum http_method method,
|
||||
const char *url,
|
||||
const char *content_type,
|
||||
const char *payload)
|
||||
{
|
||||
struct http_client_request req = {};
|
||||
struct waiter waiter;
|
||||
int ret;
|
||||
|
||||
req.method = method;
|
||||
req.url = url;
|
||||
req.protocol = " " HTTP_PROTOCOL HTTP_CRLF;
|
||||
|
||||
k_sem_init(&waiter.wait, 0, 1);
|
||||
|
||||
waiter.total_len = 0;
|
||||
|
||||
ret = http_client_send_req(ctx, &req, response, result, sizeof(result),
|
||||
&waiter, APP_REQ_TIMEOUT);
|
||||
if (ret < 0 && ret != -EINPROGRESS) {
|
||||
NET_ERR("Cannot send %s request (%d)", http_method_str(method),
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (k_sem_take(&waiter.wait, WAIT_TIME)) {
|
||||
NET_ERR("Timeout while waiting HTTP response");
|
||||
http_client_release(ctx);
|
||||
ret = -ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int do_sync_reqs(struct http_client_ctx *ctx, int count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* These examples use the HTTP client API synchronously so they
|
||||
* do not set the callback parameter.
|
||||
*/
|
||||
while (count--) {
|
||||
ret = do_sync_http_req(ctx, HTTP_GET, "/index.html",
|
||||
NULL, NULL);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = do_sync_http_req(ctx, HTTP_HEAD, "/",
|
||||
NULL, NULL);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = do_sync_http_req(ctx, HTTP_OPTIONS, "/index.html",
|
||||
NULL, NULL);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = do_sync_http_req(ctx, HTTP_POST, "/post_test.php",
|
||||
POST_CONTENT_TYPE, POST_PAYLOAD);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Note that we cannot receive data bigger than RESULT_BUF_SIZE
|
||||
* if we wait the buffer synchronously. If you want to receive
|
||||
* bigger data, then you need to set the callback when sending
|
||||
* the HTTP request using http_client_send_req()
|
||||
*/
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int do_async_reqs(struct http_client_ctx *ctx, int count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* These examples use the HTTP client API asynchronously so they
|
||||
* do set the callback parameter.
|
||||
*/
|
||||
while (count--) {
|
||||
ret = do_async_http_req(ctx, HTTP_GET, "/index.html",
|
||||
NULL, NULL);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = do_async_http_req(ctx, HTTP_HEAD, "/",
|
||||
NULL, NULL);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = do_async_http_req(ctx, HTTP_OPTIONS, "/index.html",
|
||||
NULL, NULL);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = do_async_http_req(ctx, HTTP_POST, "/post_test.php",
|
||||
POST_CONTENT_TYPE, POST_PAYLOAD);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* FIXME: There is a mbedtls SSL buffer size issue if we try to
|
||||
* receive large amount of data. So disable the big-file.html
|
||||
* fetch for time being.
|
||||
*/
|
||||
if (0) {
|
||||
ret = do_async_http_req(ctx, HTTP_GET,
|
||||
"/big-file.html",
|
||||
NULL, NULL);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
bool failure = false;
|
||||
int ret;
|
||||
|
||||
ret = net_sample_app_init("Run HTTPS client", 0, APP_STARTUP_TIME);
|
||||
if (ret < 0) {
|
||||
panic("Application init failed");
|
||||
}
|
||||
|
||||
ret = https_client_init(&https_ctx, SERVER_ADDR, SERVER_PORT,
|
||||
(u8_t *)INSTANCE_INFO, strlen(INSTANCE_INFO),
|
||||
setup_cert, HOSTNAME, NULL, &ssl_rx_pool,
|
||||
https_stack, sizeof(https_stack));
|
||||
if (ret < 0) {
|
||||
NET_ERR("HTTPS init failed (%d)", ret);
|
||||
panic(NULL);
|
||||
}
|
||||
|
||||
ret = do_sync_reqs(&https_ctx, MAX_ITERATIONS);
|
||||
if (ret < 0) {
|
||||
failure = true;
|
||||
}
|
||||
|
||||
ret = do_async_reqs(&https_ctx, MAX_ITERATIONS);
|
||||
if (ret < 0) {
|
||||
failure = true;
|
||||
}
|
||||
|
||||
if (failure) {
|
||||
NET_ERR("Some of the tests failed.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
http_client_release(&https_ctx);
|
||||
|
||||
NET_INFO("Done!");
|
||||
}
|
121
samples/net/https_client/src/test_certs.h
Normal file
121
samples/net/https_client/src/test_certs.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __TEST_CERTS_H__
|
||||
#define __TEST_CERTS_H__
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
/* This is the same cert as what is found in net-tools/https-server.pem file */
|
||||
static const unsigned char ca_certificate[767] = {
|
||||
0x30, 0x82, 0x02, 0xFB, 0x30, 0x82, 0x01, 0xE3,
|
||||
0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
|
||||
0xEC, 0x70, 0x51, 0xE3, 0xF9, 0x77, 0x0E, 0x3A,
|
||||
0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
|
||||
0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30,
|
||||
0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
|
||||
0x04, 0x03, 0x0C, 0x09, 0x6C, 0x6F, 0x63, 0x61,
|
||||
0x6C, 0x68, 0x6F, 0x73, 0x74, 0x30, 0x1E, 0x17,
|
||||
0x0D, 0x31, 0x37, 0x30, 0x35, 0x33, 0x31, 0x31,
|
||||
0x34, 0x31, 0x31, 0x35, 0x33, 0x5A, 0x17, 0x0D,
|
||||
0x34, 0x34, 0x31, 0x30, 0x31, 0x36, 0x31, 0x34,
|
||||
0x31, 0x31, 0x35, 0x33, 0x5A, 0x30, 0x14, 0x31,
|
||||
0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03,
|
||||
0x0C, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x68,
|
||||
0x6F, 0x73, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30,
|
||||
0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
|
||||
0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
|
||||
0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02,
|
||||
0x82, 0x01, 0x01, 0x00, 0xB1, 0x0F, 0x3F, 0x6F,
|
||||
0x4B, 0xFF, 0xA7, 0xC6, 0xBE, 0xB0, 0x3A, 0xC1,
|
||||
0x50, 0xF5, 0x91, 0xA3, 0xCC, 0x4B, 0x9A, 0x36,
|
||||
0x3B, 0xC8, 0x7B, 0x03, 0x02, 0x20, 0x9D, 0x5F,
|
||||
0x05, 0x9D, 0xEE, 0xF8, 0xAB, 0xFE, 0x4D, 0xC8,
|
||||
0xC5, 0xAB, 0x77, 0xFB, 0x39, 0x8C, 0x0C, 0xEE,
|
||||
0x83, 0xEC, 0x8C, 0x46, 0xA2, 0xC3, 0xF1, 0x46,
|
||||
0xEB, 0x03, 0x6B, 0x3D, 0xBF, 0x02, 0xB0, 0x91,
|
||||
0xF9, 0x4A, 0xC4, 0x71, 0x59, 0x78, 0x88, 0x75,
|
||||
0x06, 0xDB, 0x6D, 0x4D, 0xDD, 0xF5, 0x1E, 0x6C,
|
||||
0x8F, 0x88, 0x4E, 0x6D, 0xAA, 0x9D, 0xBF, 0x37,
|
||||
0x64, 0xAA, 0x22, 0x6E, 0x9B, 0x55, 0xBF, 0xFC,
|
||||
0x47, 0x8F, 0xA2, 0xE8, 0x29, 0x16, 0xF8, 0xAF,
|
||||
0x12, 0x5A, 0x4E, 0x3E, 0x85, 0x06, 0xC4, 0x78,
|
||||
0x06, 0x80, 0xCC, 0xDC, 0x6A, 0xD6, 0x81, 0xFF,
|
||||
0x40, 0xAA, 0xA4, 0xAB, 0x50, 0xB3, 0x56, 0xC4,
|
||||
0xE3, 0xA0, 0xB8, 0x94, 0x5B, 0x6F, 0x9D, 0x5B,
|
||||
0x0D, 0x62, 0x0B, 0x46, 0x46, 0x79, 0xFA, 0x1A,
|
||||
0x6E, 0x5C, 0x88, 0x0A, 0xE2, 0x1F, 0x04, 0x11,
|
||||
0xF8, 0x39, 0x22, 0xB9, 0x28, 0xE2, 0x80, 0xF2,
|
||||
0x82, 0x9D, 0x38, 0x7A, 0x2E, 0x71, 0x83, 0x0E,
|
||||
0x1D, 0x76, 0xD7, 0xBE, 0xC2, 0x55, 0x68, 0xD3,
|
||||
0xFE, 0xC0, 0x96, 0xBC, 0xFA, 0xA6, 0x83, 0xA2,
|
||||
0xDE, 0x39, 0xB3, 0x6B, 0x65, 0x88, 0x39, 0x63,
|
||||
0x5F, 0x4E, 0xB1, 0x37, 0x33, 0xB0, 0x49, 0x64,
|
||||
0x86, 0xCC, 0x56, 0xE3, 0x8B, 0x21, 0x26, 0xE5,
|
||||
0x8B, 0xA1, 0x3B, 0x55, 0x44, 0x22, 0x88, 0xD0,
|
||||
0xF9, 0xF7, 0xB8, 0x11, 0xF4, 0xE8, 0x0F, 0x4D,
|
||||
0x0E, 0xAC, 0x2E, 0x5E, 0x4D, 0x42, 0x36, 0x05,
|
||||
0x0E, 0x5E, 0x27, 0xB1, 0x40, 0xF2, 0xE7, 0x63,
|
||||
0xA8, 0x01, 0x3C, 0xEB, 0x19, 0xA3, 0xF5, 0xFE,
|
||||
0xB7, 0x1B, 0x14, 0xDB, 0x1E, 0xF5, 0x32, 0x5F,
|
||||
0x1D, 0xEF, 0x7B, 0xC3, 0x02, 0x03, 0x01, 0x00,
|
||||
0x01, 0xA3, 0x50, 0x30, 0x4E, 0x30, 0x1D, 0x06,
|
||||
0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14,
|
||||
0xB5, 0xBC, 0xDD, 0xB0, 0xC6, 0xED, 0x95, 0xB0,
|
||||
0x96, 0xEC, 0x96, 0x72, 0xE7, 0x92, 0x93, 0x90,
|
||||
0x3F, 0x84, 0x29, 0x3A, 0x30, 0x1F, 0x06, 0x03,
|
||||
0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
|
||||
0x14, 0xB5, 0xBC, 0xDD, 0xB0, 0xC6, 0xED, 0x95,
|
||||
0xB0, 0x96, 0xEC, 0x96, 0x72, 0xE7, 0x92, 0x93,
|
||||
0x90, 0x3F, 0x84, 0x29, 0x3A, 0x30, 0x0C, 0x06,
|
||||
0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03,
|
||||
0x01, 0x01, 0xFF, 0x30, 0x0D, 0x06, 0x09, 0x2A,
|
||||
0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B,
|
||||
0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x87,
|
||||
0xD5, 0xB4, 0x03, 0xBA, 0x54, 0xEC, 0x14, 0x43,
|
||||
0x6C, 0xE9, 0xE1, 0x02, 0x3A, 0xF7, 0xCB, 0x95,
|
||||
0xDC, 0x44, 0xB1, 0x60, 0x88, 0x35, 0x2B, 0xA9,
|
||||
0x13, 0x4D, 0x69, 0x2F, 0x5E, 0x4B, 0xD8, 0x32,
|
||||
0x51, 0xB9, 0x5A, 0xEB, 0xEC, 0x6A, 0x7F, 0x37,
|
||||
0x57, 0x8C, 0xC2, 0x4E, 0x97, 0x25, 0x29, 0x2A,
|
||||
0x9E, 0x3C, 0xFA, 0xFB, 0xDD, 0xE3, 0x7D, 0x1E,
|
||||
0x47, 0x06, 0x10, 0xE1, 0x17, 0x53, 0xEC, 0xCC,
|
||||
0xD5, 0xE4, 0xB8, 0x45, 0xF5, 0xBC, 0x4C, 0x38,
|
||||
0xFD, 0x78, 0xB6, 0xC6, 0xB7, 0x47, 0x01, 0x1B,
|
||||
0x35, 0x82, 0xE2, 0x05, 0xC9, 0x88, 0xC1, 0x31,
|
||||
0xE9, 0x1A, 0xF4, 0x56, 0x97, 0x27, 0x8C, 0x5E,
|
||||
0x6E, 0xF4, 0x8A, 0xAD, 0xCB, 0xE6, 0x16, 0x43,
|
||||
0xFF, 0x0C, 0x1F, 0x5D, 0x24, 0x4D, 0xE3, 0xA8,
|
||||
0x8E, 0xE0, 0x2D, 0x3A, 0x67, 0x2B, 0x55, 0xED,
|
||||
0xD5, 0xC0, 0x1F, 0x1B, 0x0F, 0x1F, 0x8F, 0xC0,
|
||||
0x77, 0x74, 0x65, 0x90, 0x93, 0x5B, 0x18, 0xBE,
|
||||
0xA9, 0x4F, 0xD2, 0x4F, 0x98, 0xCE, 0x12, 0x89,
|
||||
0x22, 0x8A, 0x16, 0x96, 0xEB, 0xC6, 0x87, 0x39,
|
||||
0xCE, 0x88, 0x5E, 0x03, 0x51, 0x0A, 0x13, 0xE9,
|
||||
0x23, 0x4D, 0x60, 0x65, 0x55, 0x05, 0x45, 0xEB,
|
||||
0xDA, 0x24, 0xFE, 0x60, 0xD5, 0x89, 0x38, 0xD5,
|
||||
0xC4, 0x9E, 0x80, 0x61, 0x0F, 0x92, 0x63, 0x4E,
|
||||
0xD5, 0x7F, 0x29, 0xB3, 0x6C, 0x2B, 0x23, 0x35,
|
||||
0x76, 0xF0, 0x88, 0x79, 0xBB, 0xB1, 0xA2, 0x5B,
|
||||
0x51, 0x9C, 0x6B, 0xE3, 0x30, 0x00, 0x01, 0x2B,
|
||||
0xCD, 0xFF, 0x07, 0xB1, 0xB1, 0xB0, 0x65, 0xCE,
|
||||
0x7A, 0x01, 0x79, 0xE9, 0xA8, 0xAA, 0x4C, 0xE7,
|
||||
0x94, 0xF5, 0x72, 0x67, 0xF0, 0x3D, 0x07, 0xB7,
|
||||
0xEA, 0x5C, 0x94, 0x93, 0xC0, 0xB3, 0xFD, 0x6C,
|
||||
0xE2, 0xBE, 0x6C, 0x2C, 0x7D, 0xB2, 0x25, 0x19,
|
||||
0x1A, 0xDE, 0x2B, 0xC9, 0x30, 0x0A, 0x97
|
||||
};
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
|
||||
const unsigned char client_psk[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||
};
|
||||
|
||||
const char client_psk_id[] = "Client_identity";
|
||||
#endif
|
||||
|
||||
#endif
|
4
samples/net/https_client/testcase.ini
Normal file
4
samples/net/https_client/testcase.ini
Normal file
|
@ -0,0 +1,4 @@
|
|||
[test]
|
||||
tags = net http
|
||||
build_only = true
|
||||
platform_whitelist = frdm_k64f qemu_x86
|
Loading…
Add table
Add a link
Reference in a new issue