HTTP Development Guide_Rev1.2

中文

Revision History

Version

Date

Author

Revision Content

Rev1.0

2023-09-14

CLY

Initial document creation

Rev1.1

2024-03-25

sxx

Changed document name

Rev1.2

2025-10-28

LXH

Added send/receive timeout settings
Added maximum send data size

1 Introduction

This document introduces the NT26F HTTP function interfaces. The function interfaces are declared in the file components/kernel/lierda_api/liot_http/liot_http.h.

2 API Function Overview

Function

Description

liot_httpc_new()

Create a new HTTP client handle and initialize HTTP client resources

liot_httpc_perform()

Send HTTP request

liot_httpc_stop()

Stop HTTP request

liot_httpc_release()

Release HTTP client resources

liot_httpc_setopt()

Configure HTTP client attributes

liot_httpc_getinfo()

Get HTTP message header information

liot_httpc_formadd()

Configure HTTP form attributes

liot_httpc_is_running()

Check if HTTP client is running

liot_httpc_url_parse()

Parse URL

3 Type Descriptions

3.1 liot_httpc_method_e

HTTP request methods.

  1. Declaration

typedef enum
{
    LIOT_HTTPC_METHOD_NONE   = 0,
    LIOT_HTTPC_METHOD_GET    = 1,
    LIOT_HTTPC_METHOD_POST   = 2,
    LIOT_HTTPC_METHOD_PUT    = 3,
    LIOT_HTTPC_METHOD_HEAD   = 4,
    LIOT_HTTPC_METHOD_LAST   = 5,
    LIOT_HTTPC_METHOD_DELETE = 6,
} liot_httpc_method_e;
  1. Parameters

Parameter

Description

LIOT_HTTPC_METHOD_NONE

No request

LIOT_HTTPC_METHOD_GET

HTTP GET request

LIOT_HTTPC_METHOD_POST

HTTP POST request

LIOT_HTTPC_METHOD_PUT

HTTP PUT request, currently not supported

LIOT_HTTPC_METHOD_HEAD

HTTP HEAD request

LIOT_HTTPC_METHOD_LAST

Last request, currently not supported

LIOT_HTTPC_METHOD_DELETE

HTTP DELETE request

3.2 liot_http_client_t

HTTP client handle.

  1. Declaration

typedef int liot_http_client_t;

4 API Function Details

4.1 liot_httpc_new

This function is used to create a new HTTP client handle and initialize HTTP client resources.

  1. Declaration

int liot_httpc_new(liot_http_client_t *client, liot_http_client_event_cb_t cb, void *arg);
  1. Parameters

client:

[Out] HTTP client handle.

cb:

[In] HTTP request event callback handler function. Refer to liot_http_client_event_cb_t.

arg:

[In] Parameter for HTTP request event callback handler function.

  1. Return Value

Execution result code, see liot_httpc_result_code_e for reference.

4.1.1 liot_http_client_event_cb_t

Request event callback handler function.

  1. Declaration

typedef void (*liot_http_client_event_cb_t)(liot_http_client_t *client, int evt, int evt_code, void *arg);
  1. Parameters

client:

[Out] HTTP client handle.

evt:

[In] HTTP request event type. Refer to liot_httpc_event_id_e.

evt_code:

[In] HTTP request event result type. Refer to liot_httpc_event_type_e.

arg:

[In] Parameter for HTTP request event callback handler function.

  1. Return Value

Execution result code, see liot_httpc_result_code_e for reference.

4.1.2 liot_httpc_event_id_e

HTTP API execution result error codes.

  1. Declaration

typedef enum
{
    LIOT_HTTP_EVENT_SESSION_ESTABLISH  = 0,
    LIOT_HTTP_EVENT_RESPONE_STATE_LINE = 1,
    LIOT_HTTP_EVENT_SESSION_DISCONNECT = 2,
} liot_httpc_event_id_e;
  1. Parameters

Parameter

Description

LIOT_HTTP_EVENT_SESSION_ESTABLISH

HTTP request connection established successfully

LIOT_HTTP_EVENT_RESPONE_STATE_LINE

HTTP request starts responding

LIOT_HTTP_EVENT_SESSION_DISCONNECT

HTTP request connection disconnected

4.1.3 liot_httpc_event_type_e

Status of events triggered during HTTP request process.

  1. Declaration

typedef enum
{
    LIOT_HTTPC_SESSION_OPEN      = 1,
    LIOT_HTTPC_UPLOAD_START      = 2,
    LIOT_HTTPC_UPLOAD_END        = 3,
    LIOT_HTTPC_RESPONSE_STATUS   = 4,
    LIOT_HTTPC_RESPONSE_COMPLETE = 5,
    LIOT_HTTPC_RESPONSE_TIMEOUT  = 6,
    LIOT_HTTPC_SESSION_CLOSE     = 7,
    LIOT_HTTPC_RAW_REQ_START     = 8,
    LIOT_HTTPC_RAW_REQ_END       = 9,
} liot_httpc_event_type_e;
  1. Parameters

Parameter

Description

LIOT_HTTPC_SESSION_OPEN

HTTP client connection established successfully event status

LIOT_HTTPC_UPLOAD_START

HTTP client starts uploading file event status, currently not supported

LIOT_HTTPC_UPLOAD_END

HTTP client completes uploading file event, currently not supported

LIOT_HTTPC_RESPONSE_STATUS

HTTP client starts receiving response data event

LIOT_HTTPC_RESPONSE_COMPLETE

HTTP client completes receiving response data event

LIOT_HTTPC_RESPONSE_TIMEOUT

HTTP client receives response data timeout event

LIOT_HTTPC_SESSION_CLOSE

HTTP client link closed event

LIOT_HTTPC_RAW_REQ_START

HTTP client starts uploading RAW file event, currently not supported

LIOT_HTTPC_RAW_REQ_END

HTTP client completes uploading RAW file event, currently not supported

4.1.4 liot_httpc_result_code_e

HTTP API execution result error codes.

  1. Declaration

typedef enum
{
    LIOT_HTTPC_SUCCESS            = LIOT_SUCCESS,
    LIOT_HTTPC_ERR_INVALID_PARAM  = 1 | LIOT_HTTP_ERRCODE_BASE,
    LIOT_HTTPC_ERR_UNKNOWN        = 2 | LIOT_HTTP_ERRCODE_BASE,
    LIOT_HTTPC_ERR_OUT_OF_MEM     = 3 | LIOT_HTTP_ERRCODE_BASE,
    LIOT_HTTPC_ERR_SOCKET_FAILURE = 4 | LIOT_HTTP_ERRCODE_BASE,
    LIOT_HTTPC_ERR_NOT_SUPPORT    = 5 | LIOT_HTTP_ERRCODE_BASE,
    LIOT_HTTPC_ERR_NOT_ALLOW      = 6 | LIOT_HTTP_ERRCODE_BASE,
    LIOT_HTTPC_ERR_NO_NETWORK     = 7 | LIOT_HTTP_ERRCODE_BASE,
    LIOT_HTTPC_ERR_NO_SSL_CERT    = 8 | LIOT_HTTP_ERRCODE_BASE,
    LIOT_HTTPC_ERR_TIMEOUT        = 9 | LIOT_HTTP_ERRCODE_BASE,
    LIOT_HTTPC_EMPTY_URL          = 10 | LIOT_HTTP_ERRCODE_BASE,
    LIOT_HTTPC_SSL_ERROR          = 11 | LIOT_HTTP_ERRCODE_BASE,
} liot_httpc_result_code_e;
  1. Parameters

Parameter

Description

LIOT_HTTPC_SUCCESS

Success

LIOT_HTTPC_ERR_INVALID_PARAM

Function parameter error

LIOT_HTTPC_ERR_UNKNOWN

Unknown error

LIOT_HTTPC_ERR_OUT_OF_MEM

Insufficient space

LIOT_HTTPC_ERR_SOCKET_FAILURE

Socket failure

LIOT_HTTPC_ERR_NOT_SUPPORT

Feature not supported

LIOT_HTTPC_ERR_NOT_ALLOW

Operation not allowed

LIOT_HTTPC_ERR_NO_NETWORK

No network

LIOT_HTTPC_ERR_NO_SSL_CERT

SSL no certificate

LIOT_HTTPC_ERR_TIMEOUT

Timeout

LIOT_HTTPC_EMPTY_URL

URL is empty

LIOT_HTTPC_SSL_ERROR

SSL error

4.2 liot_httpc_perform

Send HTTP request.

  1. Declaration

int liot_httpc_perform(liot_http_client_t *client);
  1. Parameters

client:

[In] HTTP request client handle.

  1. Return Value

Execution result code, see liot_httpc_result_code_e for reference.

4.3 liot_httpc_stop

This function is used to stop HTTP client request.

  1. Declaration

int liot_httpc_stop(liot_http_client_t *client);
  1. Parameters

client:

[In] HTTP request client handle.

  1. Return Value

Execution result code, see liot_httpc_result_code_e for reference.

4.4 liot_httpc_release

This function is used to release HTTP request client.

  1. Declaration

int liot_httpc_release(liot_http_client_t *client);
  1. Parameters

client:

[In] HTTP request client handle.

  1. Return Value

Execution result code, see liot_httpc_result_code_e for reference.

4.5 liot_httpc_setopt

This function is used to set HTTP-related attributes.

  1. Declaration

int liot_httpc_setopt(liot_http_client_t *client, int opt_tag, ...);
  1. Parameters

client:

[In] HTTP request client handle.

opt_tag:

[In] HTTP attribute tag. Refer to section 5.5.3, related liot_httpc_option_e description.

[In] HTTP attribute value.

  1. Return Value

Execution result code, see liot_httpc_result_code_e for reference.

4.5.1 liot_http_client_write_data_cb_t

After receiving HTTP response data, this callback function will be automatically called for data processing.

  1. Declaration

typedef int (*liot_http_client_write_data_cb_t)(
    liot_http_client_t *client, void *arg, char *data, int size, unsigned char end);
  1. Parameters

client:

[In] HTTP client handle.

arg:

[In] Parameter for HTTP callback handler function.

data:

[In] HTTP request response data.

size:

[In] Length of HTTP request response data.

end:

[In] HTTP request response terminator.

false: Data reception not finished.

true: Data reception completed.

  1. Return Value

Length of received and processed data.

4.5.2 liot_http_client_read_data_cb_t

When HTTP POST/PUT request occurs, this callback function will be automatically called to read data to be uploaded.

  1. Declaration

typedef int (*liot_http_client_read_data_cb_t)(
            liot_http_client_t *client, void *arg, char *data, int size);
  1. Parameters

client:

[In] HTTP client handle.

arg:

[In] Parameter for HTTP callback handler function.

data:

[Out] Space for storing data to be uploaded.

size:

[In] Specified length.

  1. Return Value

Actual length of data read.

4.5.3 liot_httpc_option_e

HTTP-related attributes.

  1. Declaration

typedef enum
{
    LIOT_HTTP_CLIENT_OPT_PDPCID = 1,
    LIOT_HTTP_CLIENT_OPT_BASIC_AUTH,
    LIOT_HTTP_CLIENT_OPT_REQUEST_HEADER,
    LIOT_HTTP_CLIENT_OPT_WRITE_HEADER,
    LIOT_HTTP_CLIENT_OPT_INTERVAL_TIME,
    LIOT_HTTP_CLIENT_OPT_METHOD,
    LIOT_HTTP_CLIENT_OPT_WRITE_FUNC,
    LIOT_HTTP_CLIENT_OPT_WRITE_DATA,
    LIOT_HTTP_CLIENT_OPT_READ_FUNC,
    LIOT_HTTP_CLIENT_OPT_READ_DATA,
    LIOT_HTTP_CLIENT_OPT_UPLOAD_LEN,
    LIOT_HTTP_CLIENT_OPT_URL,
    LIOT_HTTP_CLIENT_OPT_URI,
    LIOT_HTTP_CLIENT_OPT_SIM_ID,
    LIOT_HTTP_CLIENT_OPT_RAW_REQUEST,
    LIOT_HTTP_CLIENT_OPT_RAW_FILE,
    LIOT_HTTP_CLIENT_OPT_AUTH_INFO,
    LIOT_HTTP_CLIENT_OPT_RESPONSE_TIME,
    LIOT_HTTP_CLIENT_OPT_BODY_DATA_TYPE,
    LIOT_HTTP_CLIENT_OPT_FORM_OPTION,
    LIOT_HTTP_CLIENT_OPT_CUSTOME_HEADER,
    LIOT_HTTP_CLIENT_OPT_SEND_TIMEOUT,
    LIOT_HTTP_CLIENT_OPT_RECV_TIMEOUT,
    LIOT_HTTP_CLIENT_OPT_SSLCTXID,
    LIOT_HTTP_CLIENT_OPT_SSL_VERIFY_LEVEL,
    LIOT_HTTP_CLIENT_OPT_SSL_CACERT_PATH,
    LIOT_HTTP_CLIENT_OPT_SSL_OWNCERT_PATH,
    LIOT_HTTP_CLIENT_OPT_SSL_SNI,
    LIOT_HTTP_CLIENT_OPT_SSL_VERSION,
    LIOT_HTTP_CLIENT_OPT_SSL_HS_TIMEOUT,
    LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_LOCALTM,
    LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_INVALID_CERT_SIGN,
    LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_CERT_ITEM,
    LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_MULTI_CERTCHAIN_VERIFY,
} liot_httpc_option_e;
  1. Parameters

Parameter

Description

LIOT_HTTP_CLIENT_OPT_PDPCID

Set the data channel number used by HTTP client, i.e., PDP context ID used when performing data dial-up operation.
Parameter type: int, range 0 to 7.

LIOT_HTTP_CLIENT_OPT_BASIC_AUTH

Set username and password for HTTP basic authentication.
Format: Username:Password.
Maximum length is 255 bytes. Parameter type: char *.

LIOT_HTTP_CLIENT_OPT_REQUEST_HEADER

Set custom HTTP request header attribute.
This option can be configured multiple times to set multiple custom HTTP requests.
Parameter type: char *.

LIOT_HTTP_CLIENT_OPT_WRITE_HEADER

Set HTTP response header.
Parameter type: char *.

LIOT_HTTP_CLIENT_OPT_INTERVAL_TIME

Set maximum interval time for waiting HTTP response data.
Parameter type: int. Unit: seconds; Range: 1~65536.

LIOT_HTTP_CLIENT_OPT_METHOD

Set HTTP request method.
Parameter type: liot_httpc_method_e.

LIOT_HTTP_CLIENT_OPT_WRITE_FUNC

Set callback function for processing HTTP response data. Parameter type: http_client_write_data_cb_t

LIOT_HTTP_CLIENT_OPT_WRITE_DATA

Set parameter for callback function that processes HTTP response data. Parameter type: void *

LIOT_HTTP_CLIENT_OPT_READ_FUNC

Set callback function for reading HTTP request upload data.
Valid when HTTP request is LIOT_HTTPC_METHOD_POST and LIOT_HTTPC_METHOD_POST.

LIOT_HTTP_CLIENT_OPT_READ_DATA

Set input parameter for callback function that reads HTTP request upload data. Parameter type: void *

LIOT_HTTP_CLIENT_OPT_UPLOAD_LEN

Set length of HTTP request upload data to read. Latest SDK V05.03 and later versions support up to 100K, older versions support 20KB.

LIOT_HTTP_CLIENT_OPT_URL

Set URL for HTTP request, string type, maximum length不超过512 bytes.

LIOT_HTTP_CLIENT_OPT_URI

Set URI for HTTP request, string type, maximum length不超过512 bytes.

LIOT_HTTP_CLIENT_OPT_SIM_ID

(U)SIM card used when performing data dial-up operation, currently not supported.

LIOT_HTTP_CLIENT_OPT_RAW_REQUEST

Set HTTP request upload data format.
0: LIOT_HTTPC_RAW_DATA, RAW format data.
1: LIOT_HTTPC_FORM_DATA, Form format data.

LIOT_HTTP_CLIENT_OPT_RAW_FILE

Set HTTP request file name. Type: char*.

LIOT_HTTP_CLIENT_OPT_AUTH_INFO

Set auth attribute in HTTP request header, currently not supported.

LIOT_HTTP_CLIENT_OPT_RESPONSE_TIME

Set HTTP request response time. Currently not supported.

LIOT_HTTP_CLIENT_OPT_BODY_DATA_TYPE

Currently not supported.

LIOT_HTTP_CLIENT_OPT_FORM_OPTION

Currently not supported.

LIOT_HTTP_CLIENT_OPT_CUSTOME_HEADER

Currently not supported.

LIOT_HTTP_CLIENT_OPT_SEND_TIMEOUT

Set timeout for sending data, default 2s. (Supported from V05.04 and later versions)

LIOT_HTTP_CLIENT_OPT_RECV_TIMEOUT

Set timeout for receiving data, default 20s. (Supported from V05.04 and later versions)

LIOT_HTTP_CLIENT_OPT_SSLCTXID

Set SSL context ID. Range: 0~5.

LIOT_HTTP_CLIENT_OPT_SSL_VERIFY_LEVEL

Set SSL verification level. Range: 0~2. Refer to [liot_https_verify_level_e].

LIOT_HTTP_CLIENT_OPT_SSL_CACERT_PATH

Set SSL CA certificate path. String type, maximum length不超过255.

LIOT_HTTP_CLIENT_OPT_SSL_OWNCERT_PATH

Set SSL local certificate path. String type, maximum length不超过255.

LIOT_HTTP_CLIENT_OPT_SSL_SNI

Set whether SSL supports SNI extension.
0: Does not support SNI.
1: Supports SNI.

LIOT_HTTP_CLIENT_OPT_SSL_VERSION

Set SSL version for SSL context. Range 0~4.
0: SSL 3.0
1: TLS 1.0
2: TLS 2.0
3: TLS 3.0
4: All

LIOT_HTTP_CLIENT_OPT_SSL_HS_TIMEOUT

Set handshake timeout for SSL context. Range 1~65535, unit: seconds.

LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_LOCALTM

Set SSL context to ignore mismatch between local time and certificate validity period. Currently not supported.

LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_INVALID_CERT_SIGN

Set SSL context to ignore invalid certificate signature. Currently not supported.

LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_CERT_ITEM

Set SSL context to ignore certificate item verification. Currently not supported.

LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_MULTI_CERTCHAIN_VERIFY

Set SSL context to ignore verification errors when multiple certificates exist in certificate chain. Currently not supported.

4.5.4 liot_https_verify_level_e

HTTPS connection authentication types.

  1. Declaration

typedef enum
{
    LIOT_HTTPS_VERIFY_NONE          = 0,
    LIOT_HTTPS_VERIFY_SERVER        = 1,
    LIOT_HTTPS_VERIFY_SERVER_CLIENT = 2,
} liot_https_verify_level_e;
  1. Parameters

Parameter

Description

LIOT_HTTPS_VERIFY_NONE

No authentication

LIOT_HTTPS_VERIFY_SERVER

One-way authentication, i.e., server authentication

LIOT_HTTPS_VERIFY_SERVER_CLIENT

Two-way authentication, i.e., client authentication

4.6 liot_httpc_getinfo

This function is used to get HTTP request response header-related information.

  1. Declaration

int liot_httpc_getinfo(liot_http_client_t *client, int info, ...);
  1. Parameters

client:

[In] HTTP request client handle.

opt_tag:

[In] HTTP attribute tag. Refer to liot_httpc_info_type_e description.

[In] HTTP attribute value.

  1. Return Value

Execution result code, see liot_httpc_result_code_e for reference.

4.6.1 liot_httpc_info_type_e

  1. Partial attribute definitions of HTTP response header structure.

typedef enum
{
    LIOT_HTTPC_STATUS_CODE    = 1,
    LIOT_HTTPC_CHUNK_ENCODE   = 2,
    LIOT_HTTPC_CONTENT_LEN    = 3,
    LIOT_HTTPC_CONTENT_RANGE  = 4,
    LIOT_HTTPC_DATE           = 5,
    LIOT_HTTPC_LOCATION       = 6,
    LIOT_HTTPC_NREAD_DATA_LEN = 7,
} liot_httpc_info_type_e;
  1. Parameters

Parameter

Description

LIOT_HTTPC_STATUS_CODE

HTTP request response code

LIOT_HTTPC_CHUNK_ENCODE

Get whether response body data is chunk encoded format.
Parameter type: int *.
0: No
1: Yes

LIOT_HTTPC_CONTENT_LEN

Get content length. This value can only be obtained when HTTP response header contains content length.
Parameter type: int *.

LIOT_HTTPC_CONTENT_RANGE

Get full package size during分包download (supported after version 4.01)

LIOT_HTTPC_DATE

Get time. Parameter type: char*.

LIOT_HTTPC_LOCATION

Get redirected URL. This value can only be obtained when response code is 3xx.
Parameter type: char*.

LIOT_HTTPC_NREAD_DATA_LEN

Currently not supported

4.7 liot_httpc_formadd

This function is used to configure HTTP form attributes.

  1. Declaration

int liot_httpc_formadd(liot_http_client_t *client, int opt_tag, ...);
  1. Parameters

client:

[In] HTTP request client handle.

opt_tag:

[In] HTTP form attribute tag. Refer to liot_httpc_formopt_e description.

[In] HTTP form attribute value.

  1. Return Value

Execution result code, see liot_httpc_result_code_e for reference.

4.7.1 liot_httpc_formopt_e

  1. HTTP request form attribute definitions.

typedef enum
{
    LIOT_HTTP_FORM_NAME         = 1,
    LIOT_HTTP_FORM_FILENAME     = 2,
    LIOT_HTTP_FORM_CONTENT_TYPE = 3,
} liot_httpc_formopt_e;
  1. Parameters

Parameter

Description

LIOT_HTTP_FORM_NAME

Set storage format for uploaded data on server as file or image, etc.
Parameter type: char*.

LIOT_HTTP_FORM_FILENAME

Set name for saving uploaded data on server. Only valid when LIOT_HTTP_FORM_NAME is configured as file.
Parameter type: char*.

LIOT_HTTP_FORM_CONTENT_TYPE

Set content type corresponding to uploaded data. Only valid when LIOT_HTTP_FORM_NAME is configured as file.
Parameter type: char*.

4.8 liot_httpc_is_running

This function is used to check if current HTTP client is in running state.

  1. Declaration

bool liot_httpc_is_running(liot_http_client_t *client);
  1. Parameters

client:

[In] HTTP request client handle.

  1. Return Value

true: HTTP client is in running state.

false: HTTP client is in non-running state.

4.9 liot_httpc_url_parse

This function is used to parse HTTP request URL.

  1. Declaration

bool liot_httpc_url_parse(char *url_str, liot_httpc_url_s *url);
  1. Parameters

url_str:

[In] Input HTTP request URL.

url:

[Out] Parsed data format. See liot_httpc_url_s for details.

  1. Return Value

true: Parse successful.

false: Parse failed.

4.9.1 liot_httpc_url_s

  1. Selected operator information structure definition

typedef struct
{
    liot_httpc_scheme_e scheme;
    char *host;
    unsigned short port;
    char *uri;
} liot_httpc_url_s;
  1. Parameters

Type

Parameter

Description

liot_httpc_scheme_e

scheme

HTTP request type, refer to section 5.9.2 liot_httpc_scheme_e

char *

host

HTTP request host, maximum length不超过512 bytes

unsigned short

port

HTTP request address port number, range 0~65535

char *

uri

HTTP request URI, maximum length不超过512 bytes

4.9.2 liot_httpc_scheme_e

Define HTTP request types.

  1. Declaration

typedef enum
{
    LIOT_HTTPC_SCHEME_INVALID = 0,
    LIOT_HTTPC_SCHEME_HTTP    = 1,
    LIOT_HTTPC_SCHEME_HTTPS   = 2
} liot_httpc_scheme_e
  1. Parameters

Parameter

Description

LIOT_HTTPC_SCHEME_INVALID

Invalid parameter

LIOT_HTTPC_SCHEME_HTTP

HTTP protocol

LIOT_HTTPC_SCHEME_HTTPS

HTTPS protocol

5 Code Example

Sample code reference: examples/demo/src/demo_http.c file.

示例代码参考 examples/demo/src/demo_http.c 文件。


static liot_sem_t http_semp;
static liot_sem_t http_semp1;

// #define LIOT_HTTP_DEMO_SSL_TEST  1

char *liot_http_ca_cert_path   = "UFS:http_ca_cert.pem";
char *liot_http_user_cert_path = "UFS:http_user_cert.pem";
char *liot_http_user_key_path  = "UFS:http_user_key.pem";

char *liot_http_upload_path = "UFS:http_test.txt";
char *liot_http_upload_data = "http_upload_test";
int liot_http_upload_len    = 0;

char *liot_http_ca_cert_data ="...";//Configure with corresponding CA certificate content

char *liot_http_user_cert_data ="...";//Configure with corresponding user certificate

char *liot_http_user_key_data ="...";//Configure with corresponding user private key

static int http_uploadfile_init(void)
{
    int ret  = 0;
    LFILE fp = -1;

    if (liot_file_exist(liot_http_upload_path) != LIOT_FS_NOT_EXIST)
    {
        liot_remove(liot_http_upload_path);
    }
    fp = liot_fopen(liot_http_upload_path, "w+");
    if (fp < 0)
    {
        liot_trace("open file:%s failed!!!!", liot_http_upload_path);
        return -1;
    }
    ret = liot_fwrite(liot_http_upload_data, strlen(liot_http_upload_data), 1, fp);
    liot_trace("%s:%d", __FUNCTION__, __LINE__);
    liot_trace("ret:%d,%s", ret, liot_http_upload_data);
    liot_http_upload_len = liot_fsize(fp);
    liot_trace("%s:%d  liot_http_upload_len:%d", __FUNCTION__, __LINE__, liot_http_upload_len);
    if (ret != strlen(liot_http_upload_data))
    {
        liot_trace("ret:%d", ret);
        liot_fclose(fp);
        return -1;
    }
    liot_fclose(fp);
    return 0;
}

static int http_ca_cert_init(void)
{
    int ret  = 0;
    LFILE fp = -1;

    if (liot_file_exist(liot_http_ca_cert_path) != LIOT_FS_NOT_EXIST)
    {
        liot_remove(liot_http_ca_cert_path);
    }
    fp = liot_fopen(liot_http_ca_cert_path, "w+");
    if (fp < 0)
    {
        liot_trace("open file:%s failed!!!!", liot_http_ca_cert_path);
        return -1;
    }
    ret = liot_fwrite(liot_http_ca_cert_data, strlen(liot_http_ca_cert_data), 1, fp);
    liot_trace("%s:%d", __FUNCTION__, __LINE__);
    liot_trace("ret:%d", ret);
    if (ret != strlen(liot_http_ca_cert_data))
    {
        liot_trace("ret:%d", ret);
        liot_fclose(fp);
        return -1;
    }
    liot_fclose(fp);
    return 0;
}

static int http_user_cert_init(void)
{
    int ret  = 0;
    LFILE fp = -1;

    if (liot_file_exist(liot_http_user_cert_path) != LIOT_FS_NOT_EXIST)
    {
        liot_remove(liot_http_user_cert_path);
    }
    fp = liot_fopen(liot_http_user_cert_path, "w+");
    if (fp < 0)
    {
        liot_trace("open file:%s failed!!!!", liot_http_user_cert_path);
        return -1;
    }
    ret = liot_fwrite(liot_http_user_cert_data, strlen(liot_http_user_cert_data), 1, fp);
    liot_trace("%s:%d", __FUNCTION__, __LINE__);
    liot_trace("ret:%d", ret);
    if (ret != strlen(liot_http_user_cert_data))
    {
        liot_trace("ret:%d", ret);
        liot_fclose(fp);
        return -1;
    }
    liot_fclose(fp);
    return 0;
}

static int http_user_key_init(void)
{
    int ret  = 0;
    LFILE fp = -1;

    if (liot_file_exist(liot_http_user_key_path) != LIOT_FS_NOT_EXIST)
    {
        liot_remove(liot_http_user_key_path);
    }
    fp = liot_fopen(liot_http_user_key_path, "w+");
    if (fp < 0)
    {
        liot_trace("open file:%s failed!!!!", liot_http_user_key_path);
        return -1;
    }
    ret = liot_fwrite(liot_http_user_key_data, strlen(liot_http_user_key_data), 1, fp);
    liot_trace("%s:%d", __FUNCTION__, __LINE__);
    liot_trace("ret:%d", ret);
    if (ret != strlen(liot_http_user_key_data))
    {
        liot_trace("ret:%d", ret);
        liot_fclose(fp);
        return -1;
    }
    liot_fclose(fp);
    return 0;
}

static void http_event_cb(liot_http_client_t *client, int evt, int evt_code, void *arg)
{
    liot_trace("===http_event_cb===  evt:%d,evt_code:%d,%p", evt, evt_code, client);
    switch (evt)
    {
        case LIOT_HTTPC_SESSION_OPEN:
        {
            if (evt_code != LIOT_HTTPC_SUCCESS)
            {
                liot_trace("http session open fail");
                liot_rtos_semaphore_release(http_semp);
            }
        }
        break;
        case LIOT_HTTPC_UPLOAD_START:
        {
            liot_httpc_user_notify(client, LIOT_HTTPC_READ);
        }
        break;
        case LIOT_HTTPC_UPLOAD_END:
        {
        }
        break;
        case LIOT_HTTPC_RESPONSE_STATUS:
        {
            if (evt_code == LIOT_HTTPC_SUCCESS)
            {
                int resp_code      = 0;
                int content_length = 0;
                int chunk_encode   = 0;
                char *location     = NULL;
                char *date         = NULL;
                liot_httpc_getinfo(client, LIOT_HTTPC_STATUS_CODE, &resp_code);
                liot_httpc_getinfo(client, LIOT_HTTPC_CHUNK_ENCODE, &chunk_encode);
                liot_httpc_getinfo(client, LIOT_HTTPC_DATE, &date);
                if (date != NULL)
                {
                    liot_trace("===http_event_cb=== Date:%s", date);
                    free(location);
                }
                liot_trace("===http_event_cb=== resp_code:%d,chunk_encode:%d", resp_code, chunk_encode);
                if (chunk_encode == 0)
                {
                    liot_httpc_getinfo(client, LIOT_HTTPC_CONTENT_LEN, &content_length);
                    liot_trace("===http_event_cb=== content_length:%d", content_length);
                }
                else
                {
                    liot_trace("http chunk encode");
                }

                if (resp_code >= 300 && resp_code < 400)
                {
                    liot_httpc_getinfo(client, LIOT_HTTPC_LOCATION, &location);
                    liot_trace("===http_event_cb=== location:%s", location);
                    free(location);
                }
            }
        }
        break;
        case LIOT_HTTPC_RESPONSE_COMPLETE:
        {
            if (evt_code == LIOT_HTTPC_SUCCESS)
            {
                liot_trace("http transfer success");
            }
            else
            {
                liot_trace("http transfer fail");
            }
            liot_rtos_semaphore_release(http_semp);
        }
        break;
        case LIOT_HTTPC_SESSION_CLOSE:
        {
            liot_trace("http LIOT_HTTPC_SESSION_CLOSE success");
            liot_rtos_semaphore_release(http_semp1);
        }
        break;
    }
}

static int http_response_write_data_cb(liot_http_client_t *client, void *arg, char *data, int size, unsigned char end)
{
    liot_trace(">>>>>client:%p", client);
    liot_trace("===http_response_write_data_cb=== size:%d", size);
    unsigned char *recv_buf = NULL;
    recv_buf                = malloc(size + 1);
    if (recv_buf != NULL)
    {
        memset(recv_buf, 0, size + 1);
        memcpy(recv_buf, data, size);
        liot_trace("===http_response_write_data_cb=== recv_buf:%s", recv_buf);
        free(recv_buf);
        recv_buf = NULL;
    }
    return size;
}

static int http_request_read_data_cb(liot_http_client_t *client, void *arg, char *data, int size)
{
    int ret  = 0;
    LFILE fp = -1;
    liot_trace(">>>>>client:%p", client);

    if (client == NULL)
    {
        return 0;
    }

    fp = liot_fopen(liot_http_upload_path, "r+");
    if (fp < 0)
    {
        liot_trace("open file:%s failed!!!!", liot_http_upload_path);
        return 0;
    }
    ret = liot_fread(data, 1, size, fp);
    liot_fclose(fp);
    liot_trace("http_request_read_data_cb  data:%s", data);
    liot_trace("http_request_read_data_cb  size:%d", size);
    return ret;
}

void liot_http_demo_thread(void *arg)
{
    liot_http_client_t http_client = 0;
    int ret                        = 0;
    int cid                        = 1;
    liot_data_call_info_t info;
    uint8_t nSim = 0;

    int times = 0;
    while (LIOT_DATACALL_SUCCESS != (ret = liot_network_register_wait(nSim, 120)) && times < 10)
    {
        times++;
        liot_rtos_task_sleep_s(1);
    }

    if (LIOT_DATACALL_SUCCESS != ret)
    {
        liot_trace("====network register failure!!!!!====");
        if (LIOT_OSI_SUCCESS != liot_rtos_task_delete(NULL))
        {
            liot_trace("task deleted failed");
        }
        return;
    }

    ret = liot_start_data_call(nSim, cid, LIOT_DATA_TYPE_IP, "APNTEST", "", "", LIOT_DATA_AUTH_TYPE_NONE);
    if (ret != 0)
    {
        liot_trace("====data call failure!!!!=====");
    }

    // liot_rtos_task_sleep_ms(1000);

    ret = liot_get_data_call_info(nSim, cid, &info);
    if (ret != 0)
    {
        liot_trace("liot_get_data_call_info ret: %d", ret);
        liot_stop_data_call(nSim, cid);
        goto exit;
    }

    liot_rtos_semaphore_create(&http_semp, 0);
    liot_rtos_semaphore_create(&http_semp1, 0);

    liot_trace("info->profile_idx: %d", info.cid);
    liot_trace("info->ip_version: %d", info.ip_version);

    liot_trace("info->v4.state: %d", info.v4.state);

    liot_ip4addr_ntoa(&info.v4.addr.ip);
    liot_trace("info.v4.addr.ip: %s\r\n", liot_ip4addr_ntoa(&info.v4.addr.ip));

    liot_ip4addr_ntoa(&info.v4.addr.pri_dns);
    liot_trace("info.v4.addr.pri_dns: %s\r\n", liot_ip4addr_ntoa(&info.v4.addr.pri_dns));

    liot_ip4addr_ntoa(&info.v4.addr.sec_dns);
    liot_trace("info.v4.addr.sec_dns: %s\r\n", liot_ip4addr_ntoa(&info.v4.addr.sec_dns));

    http_ca_cert_init();
    http_user_cert_init();
    http_user_key_init();
    http_uploadfile_init();

    int http_method       = LIOT_HTTPC_METHOD_POST;
    liot_httpc_url_s *url = NULL;

    url = malloc(sizeof(liot_httpc_url_s));

#if LIOT_HTTP_DEMO_SSL_TEST
    int verify_level = LIOT_HTTPS_VERIFY_SERVER_CLIENT;

    url->host   = "112.31.84.164";
    url->scheme = LIOT_HTTPC_SCHEME_HTTPS;

    if (verify_level == LIOT_HTTPS_VERIFY_SERVER_CLIENT)
    {
        url->port = 8303;
        url->uri  = "/1K.txt";
    }
    else
    {
        url->port = 8301;
        url->uri  = "/9X07-QAT/1K.txt";
    }
#else
    url->host   = "cmp-net-monitor.xiot.senthink.com";
    url->port   = 0;
    url->scheme = LIOT_HTTPC_SCHEME_HTTP;
    url->uri    = "/getData-1";
#endif
    if (liot_httpc_new(&http_client, http_event_cb, NULL) != LIOT_HTTPC_SUCCESS)
    {
        liot_trace("http client create failed!!!!");
        goto exit;
    }
    liot_trace("%s:%d  %p,%p", __FUNCTION__, __LINE__, &http_client, http_client);

    if (http_method == LIOT_HTTPC_METHOD_POST)
    {
        url->host = "cmp-net-monitor.xiot.senthink.com";
        url->port = 0;
        url->uri  = "/pushData-1";

        liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_REQUEST_HEADER, "Content-type: multipart/form-data");
        liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_READ_FUNC, http_request_read_data_cb);
        // liot_trace("%s:%d  %p  %p", __FUNCTION__, __LINE__,&http_client,(void *)&http_client);
        liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_READ_DATA, (void *)&http_client);
        liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_UPLOAD_LEN, liot_http_upload_len);
        liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_BODY_DATA_TYPE, LIOT_HTTPC_FORM_DATA);
        liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_RAW_REQUEST, 0);
        liot_httpc_formadd(&http_client, LIOT_HTTP_FORM_NAME, "file");
        liot_httpc_formadd(&http_client, LIOT_HTTP_FORM_FILENAME, "http_upload.txt", liot_http_upload_len);
        //设置上传数据在服务器保存的名字 和本地文件的名字无关
        liot_httpc_formadd(&http_client, LIOT_HTTP_FORM_CONTENT_TYPE, "text/plain");
    }

    liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SIM_ID, nSim);
    liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_PDPCID, cid);
    liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_METHOD, http_method);
    liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_URL, url);
    liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_WRITE_FUNC, http_response_write_data_cb);

#if LIOT_HTTP_DEMO_SSL_TEST
    unsigned short hs_timeout    = 300;
    char *ca_cert_path           = liot_http_ca_cert_path;
    liot_ssl_user_cert user_cert = {liot_http_user_cert_path, liot_http_user_key_path, NULL};

    liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSLCTXID, 1);
    liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_VERSION, LIOT_SSL_VERSION_3);
    liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_HS_TIMEOUT, hs_timeout);
    // liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_SNI, 0);

    liot_trace("%s:%d  verify_level:%d ", __FUNCTION__, __LINE__, verify_level);
    switch (verify_level)
    {
        case LIOT_HTTPS_VERIFY_SERVER:
        {
            liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_VERIFY_LEVEL, LIOT_HTTPS_VERIFY_SERVER);
            liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_CACERT_PATH, ca_cert_path);
            liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_INVALID_CERT_SIGN, 1);
            liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_CERT_ITEM, MBEDTLS_X509_BADCERT_FUTURE);
        }
        break;
        case LIOT_HTTPS_VERIFY_SERVER_CLIENT:
        {
            liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_VERIFY_LEVEL, LIOT_HTTPS_VERIFY_SERVER_CLIENT);
            liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_CACERT_PATH, ca_cert_path);
            liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_OWNCERT_PATH, user_cert);
            liot_httpc_setopt(&http_client, LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_INVALID_CERT_SIGN, 1);
            liot_httpc_setopt(&http_client,
                              LIOT_HTTP_CLIENT_OPT_SSL_IGNORE_CERT_ITEM,
                              MBEDTLS_X509_BADCERT_FUTURE | MBEDTLS_X509_BADCERT_NOT_TRUSTED);
        }
        break;
    }
    liot_trace(">>>>>verify_level:%d ", verify_level);

#endif

    if (liot_httpc_perform(&http_client) == LIOT_HTTPC_SUCCESS)
    {
        liot_trace(">>>>>%p", http_semp);
        liot_rtos_semaphore_wait(http_semp, LIOT_WAIT_FOREVER);
        liot_trace("http perform success");
    }
    else
    {
        liot_trace("http perform fail");
    }

    liot_httpc_stop(&http_client);
    liot_rtos_semaphore_wait(http_semp1, LIOT_WAIT_FOREVER);
    liot_httpc_release(&http_client);

exit:
    liot_rtos_semaphore_delete(http_semp);
    liot_rtos_semaphore_delete(http_semp1);
    liot_trace("===liot_http_app_thread exit===");
    liot_rtos_task_delete(NULL);
}

运行结果:

_images/http-guide/image_1.png

其他疑问补充需确认