debug : 下载动态url失败的原因之一
动态url的定义 : 就是每次执行一个相同的url, 下载的内容不同.
e.g. http://write.blog.csdn.net/Image/Index?r=0.7961383967708061
前几天,在工程中要下载一个动态url, 下载失败.
因为下载组件已经完成很久了,如果下载动态url失败,意味着是个BUG.
当时时间紧,捡了一个同步下载url的函数暂时搞定了.
今天有时间调试, 找出了原因.
我下载时,会判断http回答是否正确. 如果正确, 才去执行InternetReadFile.
但是动态url中没有回答 文件最后修改时间, 我就当是错的.
现在看来, http回答中必定有的元素是 HTTP_QUERY_STATUS_CODE 和 HTTP_QUERY_CONTENT_LENGTH
只有这2个元素才能作为判断http回答是否正确的标准.
ns_e_http_request_status::e_http_request_status SetResponse(HINTERNET hRequest){ns_e_http_request_status::e_http_request_status eRc = ns_e_http_request_status::unknown;std::wstring s = L"";#ifdef _DEBUGstd::wstring strAnswer = L"";
#endifdo {
#ifdef _DEBUGns_base::GetHttpServerAnswer(hRequest, strAnswer); ///< for debug
#endifm_status_code = 0;m_content_length = 0;m_hRequest = hRequest;if (NULL == m_hRequest){eRc = ns_e_http_request_status::err_set_response;break;}/// "http状态码"和"http回答的内容长度"总是有的eRc = QueryInfo(HTTP_QUERY_STATUS_CODE, s);if (!IsValidHttpStatus(eRc)){break;}if (s.size() > 0)m_status_code = _ttoi(s.c_str()) ;eRc = QueryInfo(HTTP_QUERY_CONTENT_LENGTH, s);if (!IsValidHttpStatus(eRc)){break;}if (s.size() > 0)m_content_length = _ttoi(s.c_str());eRc = ns_e_http_request_status::ok;} while (0);return eRc;}
ns_e_http_request_status::e_http_request_status QueryInfo(DWORD dwInfoLevel, std::wstring & strOut){DWORD dwLen = 0;std::vector<BYTE> buf;strOut = L"";if (!::HttpQueryInfoW(m_hRequest, dwInfoLevel, NULL, &dwLen, 0) && (dwLen > 0)){buf.resize((dwLen + 1)*sizeof(WCHAR), (BYTE)0);if (::HttpQueryInfoW(m_hRequest, dwInfoLevel, &buf[0], &dwLen, 0)){strOut = (LPCTSTR)&buf[0] ;return ns_e_http_request_status::ok;}}return ns_e_http_request_status::err_query_request;}
/**hHttp answer belowHTTP/1.1 206 Partial ContentDate: Mon, 06 Apr 2015 06:29:51 GMTServer: ApacheSet-Cookie: U_TRS1=0000002e.ee7e7f9.552227df.7fdeae8e; path=/; expires=Thu, 03-Apr-25 06:29:51 GMT; domain=.sina.com.cnSet-Cookie: U_TRS2=0000002e.ee897f9.552227df.571495c1; path=/; domain=.sina.com.cnSet-Cookie: PHPSESSID=3l4k52gd2ghr4e4a659svd0e87; path=/Expires: Thu, 19 Nov 1981 08:52:00 GMTCache-Control: private, must-revalidate, max-age=0, proxy-revalidate, no-transformPragma: no-cacheVary: Accept-EncodingDPOOL_HEADER: 10.73.48.26Content-Range: bytes 0-1983/1984Content-Length: 1984Connection: closeContent-Type: image/jpegSINA-LB:aGEuMTY2LmcxLnRjLmxiLnNpbmFub2RlLmNvbQ==Set-Cookie: dpha=usrmdinst_3; path=/SINA-TS:ZWJkMjlhY2UgMCAwIDAgOCAzMQo=*/BOOL GetHttpServerAnswer(HINTERNET hHttp, std::wstring & strAnswer){// 动态url的http回答没有文件最后修改时间 Last-Modified: Tue, 12 Aug 2014 03:13:53 GMT// 有的url的http回答没有服务器名称 Server: xxx// so 这两项不能作为http回答是否正确的标准BOOL bRc = FALSE;WCHAR* lpOutBuffer = NULL;DWORD dwSize = 0;DWORD dwErrSn = 0;do {strAnswer = L"";// This call will fail on the first pass, because// no buffer is allocated.if(HttpQueryInfo(hHttp,HTTP_QUERY_RAW_HEADERS_CRLF,(LPVOID)lpOutBuffer,&dwSize,NULL)){bRc = TRUE;break;}dwErrSn = GetLastError();if (ERROR_HTTP_HEADER_NOT_FOUND == dwErrSn){// Code to handle the case where the header isn't available.bRc = FALSE;break;}// Check for an insufficient buffer.if (ERROR_INSUFFICIENT_BUFFER == dwErrSn){// Allocate the necessary buffer.lpOutBuffer = new WCHAR[dwSize];::ZeroMemory(lpOutBuffer, dwSize * sizeof(WCHAR));// when buffer resize big, retry the call.continue;}// Error handling code.bRc = FALSE;break;} while (1);if (NULL != lpOutBuffer){strAnswer = lpOutBuffer;SAFE_DELETE_ARRAY(lpOutBuffer);bRc = TRUE;}return bRc;}
从网上捡来的同步下载url到本地的函数整理了一下.
如果是动态url, 一般文件比较小,不用异步下载, 直接同步下载就行.
因为动态url下载后的文件每次都是不同的, 所以不能用http断点续传. 只能用同步下载,每次都重新下载同一个url作为不同的下载文件任务.
BOOL dl_url_to_file_sync(const WCHAR* pcUrl, const WCHAR* pcLocalFilePathName, const WCHAR* pcAgent /*= L"myInternateUrlAgen/1.0"*/){const DWORD dwLenBufRecv = 32 * 1024;BOOL bRc = FALSE;UCHAR* pcBufRecv = NULL;DWORD dwRecv = 0;FILE* stream = NULL;HINTERNET hSession = NULL;HINTERNET hUrl = NULL;std::wstring strAgen = L"";do {if ((NULL == pcUrl)|| (NULL == pcLocalFilePathName)){break;}pcBufRecv = new UCHAR[dwLenBufRecv];if (NULL == pcBufRecv)break;::ZeroMemory(pcBufRecv, dwLenBufRecv);strAgen = (NULL != pcAgent) ? pcAgent : L"myInternateUrlAgen/1.0";hSession = InternetOpenW(strAgen.c_str(), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);if (NULL == hSession)break;hUrl = InternetOpenUrlW(hSession, pcUrl, NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);if (NULL == hUrl)break;stream = fopen(ns_base::W2Aex(pcLocalFilePathName).c_str(), "wb");if(NULL == stream)break;do{bRc = InternetReadFile(hUrl, pcBufRecv, (dwLenBufRecv - 1), &dwRecv);if (bRc && (dwRecv > 0)){fwrite(pcBufRecv, sizeof (char), dwRecv , stream);}else{break;}} while (dwRecv > 0);fclose(stream);} while (0);SAFE_CLOSE_HINTERNET(hUrl);SAFE_CLOSE_HINTERNET(hSession);SAFE_DELETE(pcBufRecv);return bRc;}
debug : 下载动态url失败的原因之一相关推荐
- MFC中LoadLibrary调用Qt动态库失败的原因
今天在不同的电脑用mfc使用LoadLibrary调用qt的动态库,在某些电脑成功,某些电脑又失败.开始以为是宽字符的原因,造成字符串乱码.可以看到在UNICODE字符编码下,LoadLibrary实 ...
- Maven下载jar包失败的原因- 解决方法汇总
前言 我个人对Maven没有多少研究,仅仅是使用层面,但是有时候在IDEA中配置好Maven,写好pom.xml文件后,经常下载一会就停止了,也就是有些jar包并没有下载成功.我从网上搜了一下,发现大 ...
- feign 使用示例:动态url、动态参数、下载文件、请求体
文章目录 构建FeignClient接口实现 动态url 带参数的请求 @Param 带动态参数的请求 @QueryMap 下载文件的请求 带请求体的请求 @Body 官方使用文档: 链接 https ...
- 1.7-1.8动态库加载失败的原因和解决办法
目录 1.动态库和静态库的原理 2.动态库加载失败的原因 3.解决方法 3.1 DT_RPATH段 3.2将libcalc.so的路径加入到环境变量LD_LIBRARY_PATH中 3.3将libca ...
- 动态参数 maven_Spring Security 动态url权限控制(三)
一.前言 本篇文章将讲述Spring Security 动态分配url权限,未登录权限控制,登录过后根据登录用户角色授予访问url权限 基本环境 spring-boot 2.1.8 mybatis-p ...
- 虚幻引擎构建光照失败的原因_如何在虚幻引擎4中构建实时动态封面系统
虚幻引擎构建光照失败的原因 by David Nadaski 大卫·纳达斯基(David Nadaski) 如何在虚幻引擎4中构建实时动态封面系统 (How to build a real-time ...
- 解决Maven下载依赖文件失败问题
在安装Maven构建工具后,Maven仓库镜像站点默认是国外的,因为网络原因,在构建项目时下载依赖文件会很慢,甚至有可能下载失败.所以我们一定要把仓库镜像站点改为国内的才能顺利下载,通常比较常用得是阿 ...
- linux直接运行程序加载动态库失败,扣丁学堂Linux培训详解程序运行时加载动态库失败解决方法...
今天扣丁学堂Linux培训老师给大家介绍一下关于Linux程序运行时加载动态库失败的解决方法,希望对同学们学习有所帮助,下面我们一起来看一下吧. Linux下不能加载动态库问题 当出现下边异常情况 . ...
- 加载动态库失败(loadLibrary返回为空)的几种解决办法
如果遇到了以下几种问题,也许可以在本文找到解决方法: 一.版本更新后,原本正常的功能突然无法使用了: 二.VS编译的时候,弹出"xxx(win32):已加载"xx.dll" ...
最新文章
- 开源 java CMS - FreeCMS2.8 模板管理
- 实验十 配置EIGRP协议
- android opencv 获取小图在大图的坐标_Android开发—基于OpenCV实现相机实时图像识别跟踪...
- 再现神人!仅仅只花4天半就解开了史上最难密码,这下整个圈子都炸开了.........
- 《Spring_Four》第一次作业:团队亮相
- Android自动打包、签名、优化、上传ANT脚本
- android 更换系统壁纸,Android使用线程更换壁纸
- 华硕电脑安装键盘灯驱动步骤
- Robo 3T安装及使用
- 软件开发人员培养计划
- 计算机蓝屏无法启动不了系统怎么办,电脑开机蓝屏死机,无法进入系统怎么办?...
- hutool的BeanUtil
- 中国驾照在美国各州开车的规定
- 微信好友数目限制突破5000人? 这点钉钉、BTchat链语早就做到了
- python 打印99乘法口诀
- 做直播|流量大时需要CDN加速
- html页面在ie上出现404怎么解决,ie浏览器网页上有错误解决方法详解
- 前端开发全家桶:UI组件 开发框架 服务端 辅助工具 应用实例 Demo示例
- 【第3篇】人工智能(AI)语音测试原理和实践
- 京东java电话面试问题_【京东Java面试】京东电话技术面试,面试题目完全没思路。-看准网...