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" ...
最新文章
- php数组重复值销毁,如何从PHP中删除数组中的重复值
- MxGraph从入门到精通之1:运行HelloWorld示例程序
- dedecms上传图片不自动改名,以利于seo图片优化
- Android SQLite (三 ) 全面详解(一)
- OriginPro 2021安装教程(手把手式安装)
- leaflet加载离线OSM(OpenStreetMap)
- win2003服务器中:无法连接ACCESS数据库/sql数据库正常 .net程序生成的dll文件拒绝访问问题...
- STM32 ESP8266和Java服务器透传模式下的双向通信
- mangos代码阅读
- exe电子书转换txt 下载_网站能经常看到的主流电子书格式
- 在 tornado 中异步无阻塞的执行耗时任务
- java安卓开发异步任务_java – 如何从android中的任何异步操作中获...
- Iostream通用输入/输出流类
- 魅族手机Root之后如何恢复
- 【数据挖掘】PCA 主成分分析算法过程及原理讲解
- 微信小程序--基于colorui构建皮皮虾短视频去水印组件(仅供学习使用)
- 利用google搜索自己的博客
- php 导出word怎么分页,php 导出Word怎么分页
- 如何判断选择专业数字功放芯片
- php m pi 2,PHP rad2deg()函数