2019-05-07 02:18:18 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
2019-11-11 23:45:21 +00:00
|
|
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2019-05-07 02:18:18 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
Enable AoT and wamr-sdk, and change arguments of call wasm API (#157)
* Implement memory profiler, optimize memory usage, modify code indent
* Implement memory.grow and limit heap space base offset to 1G; modify iwasm build type to Release and 64 bit by default
* Add a new extension library: connection
* Fix bug of reading magic number and version in big endian platform
* Re-org platform APIs: move most platform APIs from iwasm to shared-lib
* Enhance wasm loader to fix some security issues
* Fix issue about illegal load of EXC_RETURN into PC on stm32 board
* Updates that let a restricted version of the interpreter run in SGX
* Enable native/app address validation and conversion for wasm app
* Remove wasm_application_exectue_* APIs from wasm_export.h which makes confused
* Refine binary size and fix several minor issues
Optimize interpreter LOAD/STORE opcodes to decrease the binary size
Fix issues when using iwasm library: _bh_log undefined, bh_memory.h not found
Remove unused _stdin/_stdout/_stderr global variables resolve in libc wrapper
Add macros of global heap size, stack size, heap size for Zephyr main.c
Clear compile warning of wasm_application.c
* Add more strict security checks for libc wrapper API's
* Use one libc wrapper copy for sgx and other platforms; remove bh_printf macro for other platform header files
* Enhance security of libc strcpy/sprintf wrapper function
* Fix issue of call native for x86_64/arm/mips, add module inst parameter for native wrapper functions
* Remove get_module_inst() and fix issue of call native
* Refine wgl lib: remove module_inst parameter from widget functions; move function index check to runtime instantiate
* Refine interpreter call native process, refine memory boudary check
* Fix issues of invokeNative function of arm/mips/general version
* Add a switch to build simple sample without gui support
* Add BUILD_TARGET setting in makefile to replace cpu compiler flags in source code
* Re-org shared lib header files, remove unused info; fix compile issues of vxworks
* Add build target general
* Remove unused files
* Update license header
* test push
* Restore file
* Sync up with internal/feature
* Sync up with internal/feature
* Rename build_wamr_app to build_wasm_app
* Fix small issues of README
* Enhance malformed wasm file checking
Fix issue of print hex int and implement utf8 string check
Fix wasi file read/write right issue
Fix minor issue of build wasm app doc
* Sync up with internal/feature
* Sync up with internal/feature: fix interpreter arm issue, fix read leb issue
* Sync up with internal/feature
* Fix bug of config.h and rename wasi config.h to ssp_config.h
* Sync up with internal/feature
* Import wamr aot
* update document
* update document
* Update document, disable WASI in 32bit
* update document
* remove files
* update document
* Update document
* update document
* update document
* update samples
* Sync up with internal repo
2020-01-21 05:26:14 +00:00
|
|
|
#include "bi-inc/shared_utils.h"
|
2019-05-07 02:18:18 +00:00
|
|
|
|
|
|
|
/* Serialization of request and response message
|
|
|
|
*
|
|
|
|
* Choices:
|
|
|
|
* We considered a few options:
|
|
|
|
* 1. coap
|
|
|
|
* 2. flatbuffer
|
|
|
|
* 3. cbor
|
|
|
|
* 4. attr-containers of our own
|
|
|
|
* 5. customized serialization for request/response
|
|
|
|
*
|
2021-10-21 05:58:34 +00:00
|
|
|
* Now we choose the #5 mainly because we need to quickly get the URL for
|
|
|
|
* dispatching and sometimes we want to change the URL in the original packet.
|
|
|
|
* the request format: fixed part: version: (1 byte), code (1 byte), fmt(2
|
|
|
|
* byte), mid (4 bytes), sender_id(4 bytes), url_len(2 bytes),
|
|
|
|
* payload_len(4bytes) dynamic part: url (bytes in url_len), payload
|
2019-05-07 02:18:18 +00:00
|
|
|
*
|
|
|
|
* response format:
|
2021-10-21 05:58:34 +00:00
|
|
|
* fixed part: (1 byte), code (1 byte), fmt(2 byte), mid (4 bytes), sender_id(4
|
|
|
|
* bytes), payload_len(4bytes) dynamic part: payload
|
2019-05-07 02:18:18 +00:00
|
|
|
*/
|
|
|
|
#define REQUES_PACKET_VER 1
|
|
|
|
#define REQUEST_PACKET_FIX_PART_LEN 18
|
|
|
|
#define REQUEST_PACKET_URL_OFFSET REQUEST_PACKET_FIX_PART_LEN
|
2021-10-21 05:58:34 +00:00
|
|
|
#define REQUEST_PACKET_URL_LEN \
|
|
|
|
*((uint16 *)((char *)buffer + 12)) /* to ensure little endian */
|
|
|
|
#define REQUEST_PACKET_PAYLOAD_LEN \
|
|
|
|
*((uint32 *)((char *)buffer + 14)) /* to ensure little endian */
|
|
|
|
#define REQUEST_PACKET_URL(buffer) ((char *)buffer + REQUEST_PACKET_URL_OFFSET)
|
|
|
|
#define REQUEST_PACKET_PAYLOAD(buffer) \
|
|
|
|
((char *)buffer + REQUEST_PACKET_URL_OFFSET \
|
|
|
|
+ REQUEST_PACKET_URL_LEN(buffer))
|
2019-05-07 02:18:18 +00:00
|
|
|
|
|
|
|
#define RESPONSE_PACKET_FIX_PART_LEN 16
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
char *
|
|
|
|
pack_request(request_t *request, int *size)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
|
|
|
int url_len = strlen(request->url) + 1;
|
|
|
|
int len = REQUEST_PACKET_FIX_PART_LEN + url_len + request->payload_len;
|
2021-08-12 09:44:39 +00:00
|
|
|
uint16 u16;
|
|
|
|
uint32 u32;
|
|
|
|
char *packet;
|
|
|
|
|
2021-10-21 05:58:34 +00:00
|
|
|
if ((packet = (char *)WA_MALLOC(len)) == NULL)
|
2019-05-07 02:18:18 +00:00
|
|
|
return NULL;
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
/* TODO: ensure little endian for words and dwords */
|
2019-05-07 02:18:18 +00:00
|
|
|
*packet = REQUES_PACKET_VER;
|
2021-10-21 05:58:34 +00:00
|
|
|
*((uint8 *)(packet + 1)) = request->action;
|
2021-08-12 09:44:39 +00:00
|
|
|
|
|
|
|
u16 = htons(request->fmt);
|
|
|
|
memcpy(packet + 2, &u16, 2);
|
|
|
|
|
2021-10-21 05:58:34 +00:00
|
|
|
u32 = htonl(request->mid);
|
2021-08-12 09:44:39 +00:00
|
|
|
memcpy(packet + 4, &u32, 4);
|
|
|
|
|
|
|
|
u32 = htonl(request->sender);
|
|
|
|
memcpy(packet + 8, &u32, 4);
|
|
|
|
|
|
|
|
u16 = htons(url_len);
|
|
|
|
memcpy(packet + 12, &u16, 2);
|
|
|
|
|
|
|
|
u32 = htonl(request->payload_len);
|
|
|
|
memcpy(packet + 14, &u32, 4);
|
|
|
|
|
2019-05-07 02:18:18 +00:00
|
|
|
strcpy(packet + REQUEST_PACKET_URL_OFFSET, request->url);
|
|
|
|
memcpy(packet + REQUEST_PACKET_URL_OFFSET + url_len, request->payload,
|
2021-10-21 05:58:34 +00:00
|
|
|
request->payload_len);
|
2019-05-07 02:18:18 +00:00
|
|
|
|
|
|
|
*size = len;
|
|
|
|
return packet;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
void
|
|
|
|
free_req_resp_packet(char *packet)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
2020-03-10 11:54:44 +00:00
|
|
|
WA_FREE(packet);
|
2019-05-07 02:18:18 +00:00
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
request_t *
|
|
|
|
unpack_request(char *packet, int size, request_t *request)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
2021-08-12 09:44:39 +00:00
|
|
|
uint16 url_len, u16;
|
|
|
|
uint32 payload_len, u32;
|
|
|
|
|
2019-05-07 02:18:18 +00:00
|
|
|
if (*packet != REQUES_PACKET_VER) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (size < REQUEST_PACKET_FIX_PART_LEN) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
memcpy(&u16, packet + 12, 2);
|
|
|
|
url_len = ntohs(u16);
|
|
|
|
|
|
|
|
memcpy(&u32, packet + 14, 4);
|
|
|
|
payload_len = ntohl(u32);
|
|
|
|
|
|
|
|
if (size != (REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len)) {
|
2019-05-07 02:18:18 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2021-08-12 09:44:39 +00:00
|
|
|
|
2019-05-07 02:18:18 +00:00
|
|
|
if (*(packet + REQUEST_PACKET_FIX_PART_LEN + url_len - 1) != 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-10-21 05:58:34 +00:00
|
|
|
request->action = *((uint8 *)(packet + 1));
|
2021-08-12 09:44:39 +00:00
|
|
|
|
|
|
|
memcpy(&u16, packet + 2, 2);
|
|
|
|
request->fmt = ntohs(u16);
|
|
|
|
|
|
|
|
memcpy(&u32, packet + 4, 4);
|
|
|
|
request->mid = ntohl(u32);
|
|
|
|
|
|
|
|
memcpy(&u32, packet + 8, 4);
|
|
|
|
request->sender = ntohl(u32);
|
|
|
|
|
2019-05-07 02:18:18 +00:00
|
|
|
request->payload_len = payload_len;
|
|
|
|
request->url = REQUEST_PACKET_URL(packet);
|
2021-08-12 09:44:39 +00:00
|
|
|
|
2019-05-17 09:15:25 +00:00
|
|
|
if (payload_len > 0)
|
|
|
|
request->payload = packet + REQUEST_PACKET_URL_OFFSET + url_len;
|
|
|
|
else
|
|
|
|
request->payload = NULL;
|
2019-05-07 02:18:18 +00:00
|
|
|
|
|
|
|
return request;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
char *
|
|
|
|
pack_response(response_t *response, int *size)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
|
|
|
int len = RESPONSE_PACKET_FIX_PART_LEN + response->payload_len;
|
2021-08-12 09:44:39 +00:00
|
|
|
uint16 u16;
|
|
|
|
uint32 u32;
|
|
|
|
char *packet;
|
|
|
|
|
2021-10-21 05:58:34 +00:00
|
|
|
if ((packet = (char *)WA_MALLOC(len)) == NULL)
|
2019-05-07 02:18:18 +00:00
|
|
|
return NULL;
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
/* TODO: ensure little endian for words and dwords */
|
2019-05-07 02:18:18 +00:00
|
|
|
*packet = REQUES_PACKET_VER;
|
2021-10-21 05:58:34 +00:00
|
|
|
*((uint8 *)(packet + 1)) = response->status;
|
2021-08-12 09:44:39 +00:00
|
|
|
|
|
|
|
u16 = htons(response->fmt);
|
|
|
|
memcpy(packet + 2, &u16, 2);
|
|
|
|
|
|
|
|
u32 = htonl(response->mid);
|
|
|
|
memcpy(packet + 4, &u32, 4);
|
|
|
|
|
|
|
|
u32 = htonl(response->reciever);
|
|
|
|
memcpy(packet + 8, &u32, 4);
|
|
|
|
|
|
|
|
u32 = htonl(response->payload_len);
|
|
|
|
memcpy(packet + 12, &u32, 4);
|
|
|
|
|
2019-05-07 02:18:18 +00:00
|
|
|
memcpy(packet + RESPONSE_PACKET_FIX_PART_LEN, response->payload,
|
2021-10-21 05:58:34 +00:00
|
|
|
response->payload_len);
|
2019-05-07 02:18:18 +00:00
|
|
|
|
|
|
|
*size = len;
|
|
|
|
return packet;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
response_t *
|
|
|
|
unpack_response(char *packet, int size, response_t *response)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
2021-08-12 09:44:39 +00:00
|
|
|
uint16 u16;
|
|
|
|
uint32 payload_len, u32;
|
|
|
|
|
2019-05-07 02:18:18 +00:00
|
|
|
if (*packet != REQUES_PACKET_VER)
|
|
|
|
return NULL;
|
2021-08-12 09:44:39 +00:00
|
|
|
|
2019-05-07 02:18:18 +00:00
|
|
|
if (size < RESPONSE_PACKET_FIX_PART_LEN)
|
|
|
|
return NULL;
|
2021-08-12 09:44:39 +00:00
|
|
|
|
|
|
|
memcpy(&u32, packet + 12, 4);
|
|
|
|
payload_len = ntohl(u32);
|
|
|
|
if (size != (RESPONSE_PACKET_FIX_PART_LEN + payload_len))
|
2019-05-07 02:18:18 +00:00
|
|
|
return NULL;
|
|
|
|
|
2021-10-21 05:58:34 +00:00
|
|
|
response->status = *((uint8 *)(packet + 1));
|
2021-08-12 09:44:39 +00:00
|
|
|
|
|
|
|
memcpy(&u16, packet + 2, 2);
|
|
|
|
response->fmt = ntohs(u16);
|
|
|
|
|
|
|
|
memcpy(&u32, packet + 4, 4);
|
|
|
|
response->mid = ntohl(u32);
|
|
|
|
|
|
|
|
memcpy(&u32, packet + 8, 4);
|
|
|
|
response->reciever = ntohl(u32);
|
|
|
|
|
2019-05-07 02:18:18 +00:00
|
|
|
response->payload_len = payload_len;
|
2019-05-17 09:15:25 +00:00
|
|
|
if (payload_len > 0)
|
|
|
|
response->payload = packet + RESPONSE_PACKET_FIX_PART_LEN;
|
|
|
|
else
|
|
|
|
response->payload = NULL;
|
2019-05-07 02:18:18 +00:00
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
request_t *
|
|
|
|
clone_request(request_t *request)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
|
|
|
/* deep clone */
|
2021-10-21 05:58:34 +00:00
|
|
|
request_t *req = (request_t *)WA_MALLOC(sizeof(request_t));
|
2019-05-07 02:18:18 +00:00
|
|
|
if (req == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
memset(req, 0, sizeof(*req));
|
|
|
|
req->action = request->action;
|
|
|
|
req->fmt = request->fmt;
|
|
|
|
req->url = wa_strdup(request->url);
|
|
|
|
req->sender = request->sender;
|
|
|
|
req->mid = request->mid;
|
|
|
|
|
|
|
|
if (req->url == NULL)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
req->payload_len = request->payload_len;
|
|
|
|
|
|
|
|
if (request->payload_len) {
|
2021-08-12 09:44:39 +00:00
|
|
|
req->payload = (char *)WA_MALLOC(request->payload_len);
|
2019-05-07 02:18:18 +00:00
|
|
|
if (!req->payload)
|
|
|
|
goto fail;
|
|
|
|
memcpy(req->payload, request->payload, request->payload_len);
|
2021-08-12 09:44:39 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* when payload_len is 0, the payload may be used for
|
|
|
|
carrying some handle or integer */
|
2019-05-07 02:18:18 +00:00
|
|
|
req->payload = request->payload;
|
|
|
|
}
|
|
|
|
|
|
|
|
return req;
|
|
|
|
|
2019-11-20 13:16:36 +00:00
|
|
|
fail:
|
|
|
|
request_cleaner(req);
|
2019-05-07 02:18:18 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
void
|
|
|
|
request_cleaner(request_t *request)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
|
|
|
if (request->url != NULL)
|
2020-03-10 11:54:44 +00:00
|
|
|
WA_FREE(request->url);
|
2019-05-07 02:18:18 +00:00
|
|
|
if (request->payload != NULL && request->payload_len > 0)
|
2020-03-10 11:54:44 +00:00
|
|
|
WA_FREE(request->payload);
|
2019-05-07 02:18:18 +00:00
|
|
|
|
2020-03-10 11:54:44 +00:00
|
|
|
WA_FREE(request);
|
2019-05-07 02:18:18 +00:00
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
void
|
|
|
|
response_cleaner(response_t *response)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
|
|
|
if (response->payload != NULL && response->payload_len > 0)
|
2020-03-10 11:54:44 +00:00
|
|
|
WA_FREE(response->payload);
|
2019-05-07 02:18:18 +00:00
|
|
|
|
2020-03-10 11:54:44 +00:00
|
|
|
WA_FREE(response);
|
2019-05-07 02:18:18 +00:00
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
response_t *
|
|
|
|
clone_response(response_t *response)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
2021-08-12 09:44:39 +00:00
|
|
|
response_t *clone = (response_t *)WA_MALLOC(sizeof(response_t));
|
|
|
|
|
2019-05-07 02:18:18 +00:00
|
|
|
if (clone == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
memset(clone, 0, sizeof(*clone));
|
|
|
|
clone->fmt = response->fmt;
|
|
|
|
clone->mid = response->mid;
|
|
|
|
clone->status = response->status;
|
|
|
|
clone->reciever = response->reciever;
|
|
|
|
clone->payload_len = response->payload_len;
|
|
|
|
if (clone->payload_len) {
|
2021-10-21 05:58:34 +00:00
|
|
|
clone->payload = (char *)WA_MALLOC(response->payload_len);
|
2019-05-07 02:18:18 +00:00
|
|
|
if (!clone->payload)
|
|
|
|
goto fail;
|
|
|
|
memcpy(clone->payload, response->payload, response->payload_len);
|
2021-08-12 09:44:39 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* when payload_len is 0, the payload may be used for
|
|
|
|
carrying some handle or integer */
|
2019-05-07 02:18:18 +00:00
|
|
|
clone->payload = response->payload;
|
|
|
|
}
|
|
|
|
return clone;
|
|
|
|
|
2019-11-20 13:16:36 +00:00
|
|
|
fail:
|
|
|
|
response_cleaner(clone);
|
2019-05-07 02:18:18 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
response_t *
|
2021-10-21 05:58:34 +00:00
|
|
|
set_response(response_t *response, int status, int fmt, const char *payload,
|
|
|
|
int payload_len)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
2019-05-17 09:15:25 +00:00
|
|
|
response->payload = (void *)payload;
|
2019-05-07 02:18:18 +00:00
|
|
|
response->payload_len = payload_len;
|
|
|
|
response->status = status;
|
|
|
|
response->fmt = fmt;
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
response_t *
|
2021-10-21 05:58:34 +00:00
|
|
|
make_response_for_request(request_t *request, response_t *response)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
|
|
|
response->mid = request->mid;
|
|
|
|
response->reciever = request->sender;
|
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
static unsigned int mid = 0;
|
|
|
|
|
|
|
|
request_t *
|
2021-10-21 05:58:34 +00:00
|
|
|
init_request(request_t *request, char *url, int action, int fmt, void *payload,
|
|
|
|
int payload_len)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
|
|
|
request->url = url;
|
|
|
|
request->action = action;
|
|
|
|
request->fmt = fmt;
|
|
|
|
request->payload = payload;
|
|
|
|
request->payload_len = payload_len;
|
|
|
|
request->mid = ++mid;
|
|
|
|
|
|
|
|
return request;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
check if the "url" is starting with "leading_str"
|
2021-10-21 05:58:34 +00:00
|
|
|
return: 0 - not match; >0 - the offset of matched url, include any "/" at the
|
|
|
|
end notes:
|
|
|
|
1. it ensures the leading_str "/abc" can pass "/abc/cde" and "/abc/, but fail
|
|
|
|
"/ab" and "/abcd". leading_str "/abc/" can pass "/abc"
|
2019-05-07 02:18:18 +00:00
|
|
|
2. it omit the '/' at the first char
|
|
|
|
3. it ensure the leading_str "/abc" can pass "/abc?cde
|
|
|
|
*/
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
int
|
|
|
|
check_url_start(const char *url, int url_len, const char *leading_str)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
|
|
|
int offset = 0;
|
|
|
|
if (*leading_str == '/')
|
|
|
|
leading_str++;
|
|
|
|
if (url_len > 0 && *url == '/') {
|
|
|
|
url_len--;
|
|
|
|
url++;
|
|
|
|
offset++;
|
|
|
|
}
|
|
|
|
|
|
|
|
int len = strlen(leading_str);
|
|
|
|
if (len == 0)
|
|
|
|
return 0;
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
/* ensure leading_str not end with "/" */
|
2019-05-07 02:18:18 +00:00
|
|
|
if (leading_str[len - 1] == '/') {
|
|
|
|
len--;
|
|
|
|
if (len == 0)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
/* equal length */
|
2019-05-07 02:18:18 +00:00
|
|
|
if (url_len == len) {
|
|
|
|
if (memcmp(url, leading_str, url_len) == 0) {
|
|
|
|
return (offset + len);
|
2021-08-12 09:44:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2019-05-07 02:18:18 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (url_len < len)
|
|
|
|
return 0;
|
|
|
|
else if (memcmp(url, leading_str, len) != 0)
|
|
|
|
return 0;
|
|
|
|
else if (url[len] != '/' && url[len] != '?')
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return (offset + len + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// * @pattern:
|
|
|
|
// * sample 1: /abcd, match /abcd only
|
|
|
|
// * sample 2: /abcd/ match match "/abcd" and "/abcd/*"
|
|
|
|
// * sample 3: /abcd*, match any url started with "/abcd"
|
|
|
|
// * sample 4: /abcd/*, exclude "/abcd"
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
bool
|
|
|
|
match_url(char *pattern, char *matched)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
|
|
|
if (*pattern == '/')
|
|
|
|
pattern++;
|
|
|
|
if (*matched == '/')
|
|
|
|
matched++;
|
|
|
|
|
|
|
|
int matched_len = strlen(matched);
|
|
|
|
if (matched_len == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (matched[matched_len - 1] == '/') {
|
|
|
|
matched_len--;
|
|
|
|
if (matched_len == 0)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int len = strlen(pattern);
|
|
|
|
if (len == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (pattern[len - 1] == '/') {
|
|
|
|
len--;
|
|
|
|
if (strncmp(pattern, matched, len) != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (len == matched_len)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (matched_len > len && matched[len] == '/')
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
2021-08-12 09:44:39 +00:00
|
|
|
}
|
|
|
|
else if (pattern[len - 1] == '*') {
|
2019-05-07 02:18:18 +00:00
|
|
|
if (pattern[len - 2] == '/') {
|
|
|
|
if (strncmp(pattern, matched, len - 1) == 0)
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return false;
|
2021-08-12 09:44:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2019-05-07 02:18:18 +00:00
|
|
|
return (strncmp(pattern, matched, len - 1) == 0);
|
|
|
|
}
|
2021-08-12 09:44:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2019-05-07 02:18:18 +00:00
|
|
|
return (strcmp(pattern, matched) == 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get the value of the key from following format buffer:
|
|
|
|
* key1=value1;key2=value2;key3=value3
|
|
|
|
*/
|
2021-08-12 09:44:39 +00:00
|
|
|
char *
|
|
|
|
find_key_value(char *buffer, int buffer_len, char *key, char *value,
|
|
|
|
int value_len, char delimiter)
|
2019-05-07 02:18:18 +00:00
|
|
|
{
|
2021-08-12 09:44:39 +00:00
|
|
|
char *p = buffer;
|
2019-05-07 02:18:18 +00:00
|
|
|
int remaining = buffer_len;
|
|
|
|
int key_len = strlen(key);
|
|
|
|
|
|
|
|
while (*p != 0 && remaining > 0) {
|
|
|
|
while (*p == ' ' || *p == delimiter) {
|
|
|
|
p++;
|
|
|
|
remaining--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (remaining <= key_len)
|
|
|
|
return NULL;
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
/* find the key */
|
2019-05-07 02:18:18 +00:00
|
|
|
if (0 == strncmp(p, key, key_len) && p[key_len] == '=') {
|
|
|
|
p += (key_len + 1);
|
|
|
|
remaining -= (key_len + 1);
|
2021-10-21 05:58:34 +00:00
|
|
|
char *v = value;
|
2019-05-07 02:18:18 +00:00
|
|
|
memset(value, 0, value_len);
|
2021-10-21 05:58:34 +00:00
|
|
|
value_len--; /* ensure last char is 0 */
|
2019-05-07 02:18:18 +00:00
|
|
|
while (*p != delimiter && remaining > 0 && value_len > 0) {
|
|
|
|
*v++ = *p++;
|
|
|
|
remaining--;
|
|
|
|
value_len--;
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2021-08-12 09:44:39 +00:00
|
|
|
/* goto next key */
|
2019-05-07 02:18:18 +00:00
|
|
|
while (*p != delimiter && remaining > 0) {
|
|
|
|
p++;
|
|
|
|
remaining--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|