解析URL, 从中解出来host, path

来源:https://help.aliyun.com/document_detail/163755.html
阿里云物联网平台,C Link SDK中的aiot_ota_api.c

/* 解析URL, 从中解出来host, path */
static int32_t _download_parse_url(const char *url, char *host, uint32_t max_host_len, char *path,
                                   uint32_t max_path_len)
{
    char *host_ptr = (char *) strstr(url, "://");
    uint32_t host_len = 0;
    uint32_t path_len;
    char *path_ptr;
    char *fragment_ptr;

    if (host_ptr == NULL) {
        return STATE_OTA_PARSE_URL_HOST_IS_NULL;
    }
    host_ptr += 3;

    path_ptr = strchr(host_ptr, '/');
    if (NULL == path_ptr) {
        return STATE_OTA_PARSE_URL_PATH_IS_NULL;
    }

    if (host_len == 0) {
        host_len = path_ptr - host_ptr;
    }

    if (host_len >= max_host_len) {
        return STATE_OTA_HOST_STRING_OVERFLOW;
    }

    memcpy(host, host_ptr, host_len);
    host[host_len] = '\0';
    fragment_ptr = strchr(host_ptr, '#');
    if (fragment_ptr != NULL) {
        path_len = fragment_ptr - path_ptr;
    } else {
        path_len = strlen(path_ptr);
    }

    if (path_len >= max_path_len) {
        return STATE_OTA_PATH_STRING_OVERFLOW;
    }

    memcpy(path, path_ptr, path_len);
    path[path_len] = '\0';
    return STATE_SUCCESS;
}

来源参考: 合宙csdk

/* 解析URL, 从中解出来host, port, path */
#include <stdio.h>
#include <stdint.h>
#include <string.h>

typedef enum
{
    HTTP_OK,
    HTTP_PARSE
} HTTPResult;

#define DBG(...)         \
    printf(__VA_ARGS__); \
    printf("\n")

static HTTPResult parseURL(const char *url, char *scheme, int32_t maxSchemeLen, char *host, int32_t maxHostLen, uint16_t *port, char *path, int32_t maxPathLen);

int main()
{
    const char *url = "http://www.example.com:8080/path/to/file";
    char scheme[10];
    char host[100];
    uint16_t port;
    char path[100];

    HTTPResult result = parseURL(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path));

    if (result == HTTP_OK)
    {
        printf("Scheme: %s\n", scheme);
        printf("Host: %s\n", host);
        printf("Port: %hu\n", port);
        printf("Path: %s\n", path);
    }
    else
    {
        printf("URL parsing failed.\n");
    }

    return 0;
}
static HTTPResult parseURL(const char *url, char *scheme, int32_t maxSchemeLen, char *host, int32_t maxHostLen, uint16_t *port, char *path, int32_t maxPathLen) // Parse URL
{
    DBG("url=%s", (uint8_t *)url);
    char *schemePtr = (char *)url;
    char *hostPtr = (char *)strstr(url, "://");
    if (hostPtr == NULL)
    {
        DBG("Could not find host");
        return HTTP_PARSE; // URL is invalid
    }

    if ((uint16_t)maxSchemeLen < hostPtr - schemePtr + 1)
    { // including NULL-terminating char
        DBG("Scheme str is too small (%d >= %d)", maxSchemeLen, hostPtr - schemePtr + 1);
        return HTTP_PARSE;
    }
    memcpy(scheme, schemePtr, hostPtr - schemePtr);
    scheme[hostPtr - schemePtr] = '\0';

    hostPtr += 3;

    int32_t hostLen = 0;

    char *portPtr = strchr(hostPtr, ':');
    if (portPtr != NULL)
    {
        hostLen = portPtr - hostPtr;
        portPtr++;
        if (sscanf(portPtr, "%hu", port) != 1)
        {
            DBG("Could not find port");
            return HTTP_PARSE;
        }
        DBG("has port=%d, hostLen= %d", *port, hostLen);
    }
    else
    {
        hostLen = strlen(hostPtr);
        DBG("no port, hostLen=%d", hostLen);
        *port = 0;
    }
    char *pathPtr = strchr(hostPtr, '/');
    if (pathPtr != 0 && portPtr == 0)
    {
        hostLen = pathPtr - hostPtr;
        DBG("has path, hostLen=%d", hostLen);
    }
    if (maxHostLen < hostLen + 1)
    { // including NULL-terminating char
        DBG("Host str is too small (%d >= %d)", maxHostLen, hostLen + 1);
        return HTTP_PARSE;
    }
    memcpy(host, hostPtr, hostLen);
    host[hostLen] = '\0';
    DBG("host=%s", (uint8_t *)host);

    int32_t pathLen;
    char *fragmentPtr = strchr(hostPtr, '#');
    if (fragmentPtr != NULL)
    {
        pathLen = fragmentPtr - pathPtr;
    }
    else
    {
        if (pathPtr != NULL)
        {
            pathLen = strlen(pathPtr);
        }
        else
        {
            pathLen = 0;
        }
    }

    if (maxPathLen < pathLen + 1)
    { // including NULL-terminating char
        DBG("Path str is too small (%d >= %d)", maxPathLen, pathLen + 1);
        return HTTP_PARSE;
    }
    if (pathPtr != NULL && pathLen > 0)
    {
        memcpy(path, pathPtr, pathLen);
        path[pathLen] = '\0';
    }
    DBG("path=%s", (uint8_t *)path);
    DBG("parseURL{url(%s),host(%s),maxHostLen(%d),port(%d),path(%s),maxPathLen(%d)}\r\n",
        url, host, maxHostLen, *port, path, maxPathLen);

    return HTTP_OK;
}

PS E:\Code\test> .\a.exe
url=http://www.example.com:8080/path/to/file
has port=8080, hostLen= 15
host=www.example.com
path=/path/to/file
parseURL{url(http://www.example.com:8080/path/to/file),host(www.example.com),maxHostLen(100),port(8080),path(/path/to/file),maxPathLen(100)}

Scheme: http
Host: www.example.com
Port: 8080
Path: /path/to/file
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值