URL分解之InternetCrackUrl函数——就是python的urlparse
URL分解之InternetCrackUrl函数
背景
近期使用WININET库写的一个数据上传、下载的客户端小程序,上传数据到网站服务器和从网站服务器下载数据到本地。由于,对WININET库部分用的比较少,所以,对这部分知识比较陌生。也遇到一些波折,其中一个就是URL的分解问题。
起初,使用WININET库连接服务器并发送访问请求的时候,调用这两个API函数:InternetConnect 和 HttpOpenRequest,需要填写网站的信息。我知道URL是什么,但是需要从URL中手动提取信息,比较麻烦。
后来了解到,原来WININET库专门提供了 InternetCrackUrl 函数来对URL进行分解,提取URL中的信息。现在,总结一下 InternetCrackUrl 的用法。
函数介绍
下面是 MSDN 2001 解释:
Cracks a URL into its component parts.
Syntax
BOOL InternetCrackUrl( LPCTSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags, LPURL_COMPONENTS lpUrlComponents );
Parameters
lpszUrl
[in] Pointer to a string that contains the canonical URL to crack.
dwUrlLength
[in] Unsigned long integer value that contains the length of the lpszUrl string in TCHAR, or zero if lpszUrl is an ASCIIZ string.
dwFlags
[in] Unsigned long integer value that contains the flags controlling the operation. This can be one of the following values:ICU_DECODEConverts encoded characters back to their normal form. This can be used only if the user provides buffers in the URL_COMPONENTS structure to copy the components into.ICU_ESCAPEConverts all escape sequences (%xx) to their corresponding characters. This can be used only if the user provides buffers in the URL_COMPONENTS structure to copy the components into.
lpUrlComponents
[in, out] Pointer to a URL_COMPONENTS structure that receives the URL components.
Return Value
Returns TRUE if the function succeeds, or FALSE otherwise. To get extended error information, call GetLastError.
其中,URL_COMPONENTS 结构体的内容是:
typedef struct { DWORD dwStructSize; LPTSTR lpszScheme; DWORD dwSchemeLength; INTERNET_SCHEME nScheme; LPTSTR lpszHostName; DWORD dwHostNameLength; INTERNET_PORT nPort; LPTSTR lpszUserName; DWORD dwUserNameLength; LPTSTR lpszPassword; DWORD dwPasswordLength; LPTSTR lpszUrlPath; DWORD dwUrlPathLength; LPTSTR lpszExtraInfo; DWORD dwExtraInfoLength; } URL_COMPONENTS, *LPURL_COMPONENTS;
dwStructSize用于表明该结构体大小,一般我们都是传递sizeof(URL_COMPONENTS)。
lpszSheme指向一段用于保存协议类型的内存空间。 dwSchemeLength用于描述传入空间的大小(以TCHARS为单位的大小,下面其他空间大小描述字段都是以TCHARS单位)。
lpHostName指向一段用于保存域名信息的内存空间。 dwHostNameLength用于描述传入空间的大小。 nPort用于接收端口号。 lpszUserName和lpszPassword分别用于保存URL中携带的用户名和密码。 lpszUrlPath指向保存URL的路径——不包含域名的一段内存空间。 lpszExtraInfo指向保存URL中参数信息的一段内容空间。
使用例子
1. 导入WININET库
# include <WinInet.h>
# pragma comment(lib, "Wininet.lib")
2. 调用 InternetCrackUrl 函数
传入要分解的URL链接字符串,调用 InternetCrackUrl 函数分解,并输出分解结果。
void CrackURL(char *pszURL)
{
URL_COMPONENTS uc = { 0 };
char szScheme[MAX_PATH] = { 0 };
char szHostName[MAX_PATH] = { 0 };
char szUserName[MAX_PATH] = { 0 };
char szPassword[MAX_PATH] = { 0 };
char szUrlPath[MAX_PATH] = { 0 };
char szExtraInfo[MAX_PATH] = { 0 };
// 初始化缓冲区
::RtlZeroMemory(&uc, sizeof(uc));
::RtlZeroMemory(szScheme, MAX_PATH);
::RtlZeroMemory(szHostName, MAX_PATH);
::RtlZeroMemory(szUserName, MAX_PATH);
::RtlZeroMemory(szPassword, MAX_PATH);
::RtlZeroMemory(szUrlPath, MAX_PATH);
::RtlZeroMemory(szExtraInfo, MAX_PATH);
// 设置 URL_COMPONENTS 结构体数据
uc.dwStructSize = sizeof(uc);
uc.lpszScheme = szScheme;
uc.lpszHostName = szHostName;
uc.lpszUserName = szUserName;
uc.lpszPassword = szPassword;
uc.lpszUrlPath = szUrlPath;
uc.lpszExtraInfo = szExtraInfo;
uc.dwSchemeLength = MAX_PATH;
uc.dwHostNameLength = MAX_PATH;
uc.dwUserNameLength = MAX_PATH;
uc.dwPasswordLength = MAX_PATH;
uc.dwUrlPathLength = MAX_PATH;
uc.dwExtraInfoLength = MAX_PATH;
// 调用函数
if (FALSE == ::InternetCrackUrl(pszURL, 0, 0, &uc))
{
printf("Error[%d]\n", ::GetLastError());
}
// 显示分解结果
printf("szScheme = %s\n", szScheme);
printf