//whttp 网络传输协议 
import inet.url 
namespace inet

var toUnicode = ..string.toUnicode

whttp = class{
		
    ctor( agent = "Mozilla/4.0", proxy,proxyBypass="",flags=0,shareName ){
    	/* 
		HTTP=HTTP://proxyserver:port    
		FTP=FTP://proxyserver:port   
		GOPHER=HTTP://proxyserver:port   
		SOCKS=proxyserver:port 
		多个代理请以空格分开,空字符串表示使用默认代理设置，null表示不使用代理 
		*/ 
		var accessType = (!proxy)? 0x1/*_WINHTTP_ACCESS_TYPE_NO_PROXY*/:0x0/*_WINHTTP_ACCESS_TYPE_DEFAULT_PROXY*/ 
	    if( #proxy ){
	    	accessType = 3/*WINHTTP_ACCESS_TYPE_NAMED_PROXY*/;
	    	proxy = toUnicode(proxy)
	    	proxyBypass = toUnicode(proxyBypass)
	    }
	    agent = toUnicode(agent);
	    
	    if(shareName){
	    	shareName += "{BA1EA509-AD92-4595-8E63-89BFCE2ECD01}"
	    	this.session = thread.shareHandle.create(shareName,Open,agent,accessType,proxy,proxyBypass,flags);
	    }
	    else{
	   		this.session = Open(agent,accessType,proxy,proxyBypass,flags);
	   	}
	   
	    if(!this.session)
			error("inet.whttp初始化失败",2) 
			
		..table.add_gc(this,"close"); 
	};  
	close = function(){  
	    if(this.session){
	    	this.endRequest();
	    	
	    	if( shareName ){ 
				thread.shareHandle.delete( shareName,CloseHandle)
			}
			else{
				CloseHandle( this.session );
			} 
	    	this.session = null;  
	    }
	};
	endRequest =  function(){
		if(this.connect){
			CloseHandle(this.connect);
			this.connect = null;
		}
		if(this.request){
			CloseHandle(this.request); 
			this.request = null;
		}
	};
	
	beginRequest = function(url,method="GET",referer,accept,flags=0,openFlags=0){
		if( ! (#url) )
	    	return null,"未指定网址"
	 
		//分析网址
		var tUrl = ..inet.url.split(url);  
		if(!tUrl)
			return null,"地址格式不正确"

		this.connect = Connect(this.session,toUnicode(tUrl.host) ,tUrl.port,openFlags)  
        if( ! this.connect ) 
        	return null,..lasterr(,"beginRequest->Connect")
	
	    //开启HTTPS支持					
	    if( tUrl.schemeNum == 0x4/*_INTERNET_SCHEME_HTTPS*/)
	    	flags |=  0x800000 /*_WINHTTP_FLAG_SECURE*/;
		
		var lplpszAcceptTypes = {};
	    if(accept){
	    	var tAccept = ..string.split(accept,",");
	    	for(k,v in tAccept){
	    		 tAccept[k] = toUnicode(v);
	    	} 
	    	lplpszAcceptTypes = ..raw.toarray( #tAccept+1,"pointer","array" );
	    	lplpszAcceptTypes.array = tAccept;
	    }
	    this.request = OpenRequest(this.connect, toUnicode(method),toUnicode( ..string.concat(tUrl.path ,tUrl.extraInfo) ) ,null,toUnicode(referer:this.referer),lplpszAcceptTypes,flags||this.flags||0 ) 
		
		if( ! this.request ){ 
			return null,..lasterr(,"beginRequest->OpenRequest");
		} 
		this.referer = url;  
		this.headers = null;
		return true;
	};
	queryNumber = function(flag=0){
		if(!this.request)
			error("无效调用",2) 
		var ok,num = QueryHeadersByInt( this.request,0x20000000 /*_HTTP_QUERY_FLAG_NUMBER*/ | flag,null,0,4,0)
		if(ok)return num;
	};
	securityFlagIgnoreUnknownCa = true ;
	securityFlagIgnoreCertCnInvalid = true;
	securityFlagIgnoreCertDateInvalid = true;
	securityFlagIgnoreWrongUsage = true;
	_defaultRequestErrHandle = {
		[12175/*_ERROR_WINHTTP_SECURE_FAILURE*/ ] = function() { 
	 		var flag = {INT feature};
	 		if (! QueryOption(this.request,0x1F/*_WINHTTP_OPTION_SECURITY_FLAGS*/,flag,4) ){
	 			return null,..lasterr(,"_defaultRequestErrHandle->12175->QueryOption")
	 		}
	 		var security_flags = flag.feature & ( 0x100/*_SECURITY_FLAG_IGNORE_UNKNOWN_CA*/ |
                   0x2000/*_SECURITY_FLAG_IGNORE_CERT_DATE_INVALID*/ |
                   0x1000/*_SECURITY_FLAG_IGNORE_CERT_CN_INVALID*/ |
                   0x200/*_SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE*/ );

    		if ( this.securityFlagIgnoreCertCnInvalid)
      		security_flags |= 0x1000/*_SECURITY_FLAG_IGNORE_CERT_CN_INVALID*/;
		
    		if ( this.securityFlagIgnoreCertDateInvalid )
      		security_flags |= 0x2000/*_SECURITY_FLAG_IGNORE_CERT_DATE_INVALID*/;
		
    		if ( this.securityFlagIgnoreUnknownCa )
      		security_flags |= 0x100/*_SECURITY_FLAG_IGNORE_UNKNOWN_CA*/;
		
    		if ( this.securityFlagIgnoreWrongUsage )
      		security_flags |= 0x200/*_SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE*/;

			flag.feature = security_flags;
	 		if( ! SetOption(this.request,0x1F/*_WINHTTP_OPTION_SECURITY_FLAGS*/,flag,4) ){
	 			return null,..lasterr(,"_defaultRequestErrHandle->12175->SetOption")
	 		} 
	 		return true; 
	 	}
	};
	beginSendData = function(bufferTotal=0){
		if(!this.request)
			error("无效调用",2) 
			 
		var headers = this.headers;
		if(#this.addHeaders)
			headers = ..string.concat(headers,'\r\n',this.addHeaders); 

		this.bufferTotal = bufferTotal;
		var sendstat = SendRequest(this.request,toUnicode(headers),-1,null,0,bufferTotal ,0);
	 	if( !sendstat ) {  
	 		var err,code = ..lasterr(,"beginSendData");
	 		var handle = this._defaultRequestErrHandle[code];
	 		if( handle ){
	 			var ok,err,code = handle();
	 			if(!ok)
	 				return null,err,code;
	 				
	 			var sendstat = SendRequest(this.request,toUnicode(headers),-1,null,0,bufferTotal ,0);
	 			if( !sendstat ){
	 				return null,..lasterr(,"beginSendData->retry");
	 			} 
	 		}
	 		else {
	 			return null,err,code;
	 		} 
		}
		return true;  
	};
	writeData = function(str,...){
		if(!this.request) error("无效调用",2);
		var ok,len = WriteData( this.request,str,#str,0);
		if(!ok)return null,"上传文件出错";
		if(!...)return len;
		return len + writeFile( this.request,...);
	};
	endSendData = function(){
		if( !this.request ) error("无效调用",2);
		if( !ReceiveResponse(this.request) ){
			return null,..lasterr(,"endSendData");
		};
		
		this.statusCode = this.queryNumber(0x13)
    	if(!this.statusCode){  
			return null,..lasterr(,"send->queryNumber");
		}
		this.contentLength = this.queryNumber(  0x5/*_HTTP_QUERY_CONTENT_LENGTH*/ );
		return true,this.statusCode,this.contentLength	
	};
	send = function(postData){
		if(!this.request) error("无效调用",2);
		var ok,err,code = this.beginSendData(#postData);
		if(!ok)return null,err,code;
		
		if( postData ? ( ! this.writeData( postData ) ) ){
			return null,"上传数据出错"
		}
		return this.endSendData(); 
	}; 
	read = function(){
		var ok,str,size;
		 
        ok,size = QueryDataAvailable( this.request,0);
        if (!ok)   
			return null,..lasterr(,"read->QueryDataAvailable");
			
        if (!size)
            return null;
            
		ok,str,size = ReadData(this.request,size+1 ,size,0); 
		
		if(!ok)   
			return null,..lasterr(,"read->ReadData"); 
        
		if ( size ) 
			return ..string.left(str,size),size; 
	};
	readHeader = function(name,index=1){
		if(!this.request)
			error("无效调用",2) 
			
		var lev = name?65535:0x16
		name = ..string.toUnicode(name);
		var ok,headers,len,next =QueryHeadersByString(this.request,lev,name,0,0,index-1);
		ok,headers,len = QueryHeadersByString(this.request,lev,name,len+1,len+1,index-1);
		
		if(!ok) 
			return null,..lasterr(,"readHeader->QueryHeadersByString");  
		 
		return ..string.fromUnicode( headers ),next!=12150?next+1:null; 
	};  
	writeHeader = function(header,modifiers = -1610612736/*_WINHTTP_ADDREQ_FLAG_REPLACE | _WINHTTP_ADDREQ_FLAG_ADD*/ ){
		if(!this.request)
			error("无效调用",2) 
		header = ..string.toUnicode(header);	 
		return AddRequestHeaders(this.request,header,-1,modifiers)
	}; 
	replaceHeader = function(header){
		return this.writeHeader(header,0x80000000/*_WINHTTP_ADDREQ_FLAG_REPLACE*/);
	}; 
	mergeHeader = function(header,sep=","){
		return this.writeHeader( header,sep=="," ? 0x40000000/*_WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA*/ : 0x1000000/*_WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON*/ );
	};
	readHeaderRange = function(){
		if(!this.request)
			error("无效调用",2)
			
		return {
			acceptRanges = owner.readHeader("Accept-Ranges:");
			eTag = owner.readHeader("ETag:");
			lastModified = owner.readHeader("Last-Modified:"); 
			buildRequestHeaders = function(from=0,to){
				return ..string.concat("If-Range:",owner.eTag,
					'\r\nUnless-Modified-Since:',owner.lastModified,
					'\r\nRange:bytes=',from , "-",to
				);
			}  
		}
	}; 
	writeHeaderRange = function(rangeInfo,from=0,to){
		if(!this.request)
			error("无效调用",2);
		
		owner.writeHeader( ..string.concat("If-Range:",rangeInfo.eTag,
					'\r\nUnless-Modified-Since:',rangeInfo.lastModified,
					'\r\nRange:bytes=',from , "-",to
				) 
		)
	};	
	readHeaderContent = function(){
		var ret = {
			type = owner.readHeader("Content-Type"); 
		}
		var disposition = owner.readHeader("Content-disposition")
		if( disposition ){
			var _type,filename = ..string.match(disposition,"([^;\s]+)\s*\;\s*filename\s*=\s*(.+)");
			ret.disposition ={ type = _type;filename=filename} 
		}
		return ret;
	};
	post = function(url,postdata,headers,referer,accept,flags,openFlags){ 
		if( !(headers && ..string.find( headers,"@Content-Type:") ) ){  
		    headers = ..string.concat( headers 
		    	, ( postdata[1]=='{'# or  postdata[1]=='['#) 
		    	? '\r\nContent-Type:application/json; charset=utf-8' : '\r\nContent-Type:application/x-www-form-urlencoded'
		    	);
		} 
		
		return this.down(url,postdata,headers ,referer,accept,"POST",flags)
	};
	get = function(url,headers,referer,accept,flags){
		return this.down(url, ,headers,referer,accept,"GET",flags,openFlags)
	};
	down = function(url,postdata,headers,referer,accept,method,flags,openFlags){ 
	    var ok,err,code = this.beginRequest(url,method,referer,accept,flags,openFlags); 
	    if(!ok)
	    	return ok,err,code;
	    
	    this.headers = ..string.concat( this.headers,headers);
	    var ok,status,total = this.send( postdata );
	  	if(!ok)
    	   return ok,status,total/*errCode*/;
      
      	if( (status != 200) && (status != 206) ) { 
    		this.endRequest()
			return null,status;   
    	}  
    	
		var ret;
    	if( this.onRecive ){
    		if( this.onReciveBegin )
    			this.onReciveBegin( status,total );
    			
    		for(str,size in this.eachRead() ){
    			if( this.onRecive( str,size,total ) === false )
    				break;
    		} 
    		ret = true;
    	}
    	else{
    		var tbuffer = {}; 
		 	//开始下载数据
			for(str,size in this.eachRead() ){ 
				..table.push(tbuffer,str ) ; 
			}  
			ret =  ..string.join(tbuffer)
		}
		this.endRequest();  
		return ret;
	};
	eachRead = function(){
		return this.read 
	}; 
	disable = function(feature){
		return SetOption(this.request : this.session ,0x3F/*_WINHTTP_OPTION_DISABLE_FEATURE*/,{int feature=feature},4);
	}; 
	disableRedirects = function(){
		return this.disable(0x2/*_WINHTTP_DISABLE_REDIRECTS*/)  
	};
	setTimeouts = function(connect=60000,send=30000,receive=30000,resolve=0){
		return SetTimeouts(this.session,resolve,connect,send,receive) 
	}; 
 }
		
namespace whttp{ 
	import thread.shareHandle;
		
	dll = ..raw.loadDll("winhttp.dll") 
	
	CloseHandle = dll.api("WinHttpCloseHandle","bool(POINTER innet)")
	Open = dll.api("WinHttpOpen","pointer(string agent, int dwAccessType,string proxy,str byPass,int flags)" )
	Connect = dll.api("WinHttpConnect","pointer(POINTER innet,str serverName,WORD port,INT reserved)")
	OpenRequest = dll.api("WinHttpOpenRequest","pointer(POINTER conn,string verb,string objectName,string version,string referrer,struct acceptTypes,INT flags )")
	SendRequest = dll.api("WinHttpSendRequest","int(POINTER request,str headers,INT headersLength,pointer optional,INT optionalLength,INT totalLength,INT context)")
	ReceiveResponse= dll.api("WinHttpReceiveResponse","int(POINTER request,pointer reserved)" );
	 
	AddRequestHeaders  = dll.api("WinHttpAddRequestHeaders","bool(POINTER request,string headers,INT len,INT modifiers)")
	QueryHeadersByString  = dll.api("WinHttpQueryHeaders","int(POINTER request, INT infoLevel,string name,string& buffer,INT &bufferLength, INT & index)")
	QueryHeadersByInt  = dll.api("WinHttpQueryHeaders","int(POINTER request, INT infoLevel,string name,int& buffer,INT &bufferLength, INT & index)")
	
	ReadData  = dll.api("WinHttpReadData","int(POINTER file, string &buffer, INT numberOfBytesToRead, INT &lpdwNumberOfBytesRead)")
	QueryDataAvailable  =  dll.api("WinHttpQueryDataAvailable","int(POINTER hFile,INT &size)")
	WriteData  = dll.api("WinHttpWriteData","bool(POINTER hRequest,string buffer, INT bytesToWrite, INT &bytesWritten)")
  
	SetTimeouts = dll.api("WinHttpSetTimeouts","int(POINTER innet,int resolve,int connect,int send,int receive)");
	
	/*intellisense(inet.whttp)*/
	SetOptionByPtr =  dll.api("WinHttpSetOption","bool(POINTER hInternet,INT option,pointer buffer,INT length)")
	SetOption =  dll.api("WinHttpSetOption","bool(POINTER hInternet,INT option,struct buffer,INT length)")  
	QueryOption =  dll.api("WinHttpQueryOption","bool(POINTER hInternet,INT option,struct &buffer,INT &length)") 
	/*end intellisense*/ 
	
}

/**intellisense()
inet.whttp() = !whttp.
!whttp.setTimeouts(.(连接超时,请示超时,接收超收) = 设置超时,以亳秒为单位(1秒为1000毫秒)
!whttp.flags = @.flags = _WINHTTP_FLAG___ 
!whttp.accept = 指定可选择的文件类型\n默认无需指定,也可以在参数中指定
!whttp.referer = 引用页地址,此属性会自动设置为上次打开的网址\n建议在参数中指定
!whttp.addHeaders = 默认HTTP头\n请求结束时不会清空此属性
!whttp.headers = 直接设置HTTP头\n此属性会在每次请求一个url时,初始化为空值
!whttp.queryNumber(_HTTP_QUERY_FLAG__/*指定要返回的头信息*/) = 取HTTP头数值
!whttp.readHeader() = 获取返回的HTTP头\n以回车换行'\r\n'分隔
!whttp.readHeader("Date") = 获取指定的HTTP头\n参数可以是头信息任意行的任意长度开始部分
!whttp.readHeader("Date",1) = 获取指定的HTTP头\n同名头信息可以使用第二个参数指定索引\n返回读取的头,以及下一个有效索引
!whttp.writeHeader("Name:value__") = 写入HTTP头\n如果存在则覆盖，否则添加\n成功返回true
!whttp.replaceHeader("Name:value__") = 写入HTTP头\n如果存在则覆盖，否则忽略
!whttp.mergeHeader("Name:value__") = 写入HTTP头\n如果存在同名HTTP头则合并\n可使用第二个参数指定分隔符为逗号或分号\n默认为逗号
!whttp.beginRequest(.(url,method,referer,accept,flags) = 除URL以外,所有参数可选\n参数(URL,"GET"或"POST",引用页,MIME,选项)
!whttp.endRequest() = 关闭请求,与beginRequest配对使用.
!whttp.statusCode = send()函数执行后返回的HTTP状态码\n200表示正常,206表示断点续传,404表示找不到页面\n403表示禁止访问,401表示未授权,400表示无效请求\n更多参考相关文档
!whttp.contentLength = send()函数执行后返回的文件长度
!whttp.bufferTotal = 上传数据总长度\n即beginSendData()参数传入的数值
!whttp.beginSendData(数据总长度) = 发送请求,参数为待上传的数据总长度,默认为0\n失败返回:null,错误信息,错误代码
!whttp.endSendData() = wirte()函数写完所有上传数据以后,\n必须调用此函数结束上传,\n成功返回: true,状态码,文件长度\n出错返回:null,错误信息,错误代码
!whttp.writeData(上传数据) = 上传文件数据,支持一个或多个参数,\n返回写入数据的总长度,失败返回空或0\n调用此函数前必须调用beginSendData()\n写完所有数据后 必须调用 endSendData();
!http.send(__/*可选输入postdata*/) =  此函数顺序调用 beginSendData() writeData() endSendData() 发送请求\n成功返回: true,状态码,文件长度\n出错返回:null,错误信息,错误代码
!whttp.disableRedirects() = 禁止重定向\n必须在beginRequest()之后调用
!whttp.disable(_WINHTTP_DISABLE__) = 禁用指定功能\n必须在beginRequest()之后调用
!whttp.eachRead = @for(str,size in ??.eachRead() ){ 
	table.push(__,str ) ; 
} 
!whttp.onRecive = @.onRecive = function(str,size,contentLength){
	
}
!whttp.onReciveBegin = @.onReciveBegin = function(statusCode,contentLength){
	if( statusCode == 206 /*断点续传*/  ){ 
		__
	}
}
!whttp.get(.(url,http头,引用网址,MIME) = 下载网页\n除URL外,其他为可选参数\n默认使用上一次访问的网址作为下一次的引用网址\n出错返回值为:null,错误信息,错误代码,\n成功返回字符串对象.
!whttp.post(.(url,post数据,http头,引用网址,MIME) = 自动提交数据并返回页面\n除除URL与post数据以外,其他为可选参数\n默认使用上一次访问的网址作为下一次的引用网址\n出错返回值为:null,错误信息,错误代码\n成功返回字符串对象.
!whttp.close(.() =  释放资源\nwhttp对象支持自动析构,即使不调用此函数资源也会自动释放. 
!whttp.securityFlagIgnoreUnknownCa = HTTPS请求自动忽略无效CA证书 ;
!whttp.securityFlagIgnoreCertCnInvalid = HTTPS请求自动忽略无效CN名称
!whttp.securityFlagIgnoreCertDateInvalid = HTTPS请求自动忽略过期证书;
!whttp.securityFlagIgnoreWrongUsage = true;
!whttp._defaultRequestErrHandle = @._defaultRequestErrHandle[12175/*_ERROR_WINHTTP_SECURE_FAILURE*/ ] = function() { 
	__/*添加 send() 函数错误处理程序*/
	return false,"错误",错误代码;
}
inet.whttp(__) = inet.http("Mozilla/4.0", "HTTP://proxyserver:port" ) 
inet.whttp = winhttp支持库
?inet.whttp = !whttp.

!whttp.readHeaderRange() = 读取HTTP头中断点续传相关验证信息
!whttp.writeHeaderRange(.(rangeHeaderInfo,开始位置,结束位置) = rangeHeaderInfo使用readHeaderRange()函数读取,\n其它参数可选,开始位置默认为0,结束位置默认为文件尾
!whttp.readHeaderContent() = 读取HTTP头中文件下载相关信息\n!httpheadercontent.
end intellisense**/

 
/**intellisense()
_WINHTTP_FLAG_ESCAPE_PERCENT=@0x4/*_WINHTTP_FLAG_ESCAPE_PERCENT*/
_WINHTTP_FLAG_NULL_CODEPAGE=@0x8/*_WINHTTP_FLAG_NULL_CODEPAGE*/
_WINHTTP_FLAG_ESCAPE_DISABLE=@0x40/*_WINHTTP_FLAG_ESCAPE_DISABLE*/
_WINHTTP_FLAG_ESCAPE_DISABLE_QUERY=@0x80/*_WINHTTP_FLAG_ESCAPE_DISABLE_QUERY*/
_WINHTTP_FLAG_BYPASS_PROXY_CACHE=@0x100/*_WINHTTP_FLAG_BYPASS_PROXY_CACHE*/
_WINHTTP_FLAG_REFRESH=@0x100/*_WINHTTP_FLAG_REFRESH*/
_WINHTTP_FLAG_SECURE=@0x800000/*_WINHTTP_FLAG_SECURE*/
_SECURITY_FLAG_IGNORE_UNKNOWN_CA=@0x100/*_SECURITY_FLAG_IGNORE_UNKNOWN_CA*/
_SECURITY_FLAG_IGNORE_CERT_DATE_INVALID=@0x2000/*_SECURITY_FLAG_IGNORE_CERT_DATE_INVALID*/
_SECURITY_FLAG_IGNORE_CERT_CN_INVALID=@0x1000/*_SECURITY_FLAG_IGNORE_CERT_CN_INVALID*/
_SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE=@0x200/*_SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE*/

_WINHTTP_OPTION_CALLBACK=@0x1/*_WINHTTP_OPTION_CALLBACK*/
_WINHTTP_OPTION_RESOLVE_TIMEOUT=@0x2/*_WINHTTP_OPTION_RESOLVE_TIMEOUT*/
_WINHTTP_OPTION_CONNECT_TIMEOUT=@0x3/*_WINHTTP_OPTION_CONNECT_TIMEOUT*/
_WINHTTP_OPTION_CONNECT_RETRIES=@0x4/*_WINHTTP_OPTION_CONNECT_RETRIES*/
_WINHTTP_OPTION_SEND_TIMEOUT=@0x5/*_WINHTTP_OPTION_SEND_TIMEOUT*/
_WINHTTP_OPTION_RECEIVE_TIMEOUT=@0x6/*_WINHTTP_OPTION_RECEIVE_TIMEOUT*/
_WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT=@0x7/*_WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT*/
_WINHTTP_OPTION_HANDLE_TYPE=@0x9/*_WINHTTP_OPTION_HANDLE_TYPE*/
_WINHTTP_OPTION_READ_BUFFER_SIZE=@0xC/*_WINHTTP_OPTION_READ_BUFFER_SIZE*/
_WINHTTP_OPTION_WRITE_BUFFER_SIZE=@0xD/*_WINHTTP_OPTION_WRITE_BUFFER_SIZE*/
_WINHTTP_OPTION_PARENT_HANDLE=@0x15/*_WINHTTP_OPTION_PARENT_HANDLE*/
_WINHTTP_OPTION_EXTENDED_ERROR=@0x18/*_WINHTTP_OPTION_EXTENDED_ERROR*/
_WINHTTP_OPTION_SECURITY_FLAGS=@0x1F/*_WINHTTP_OPTION_SECURITY_FLAGS*/
_WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT=@0x20/*_WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT*/
_WINHTTP_OPTION_URL=@0x22/*_WINHTTP_OPTION_URL*/
_WINHTTP_OPTION_SECURITY_KEY_BITNESS=@0x24/*_WINHTTP_OPTION_SECURITY_KEY_BITNESS*/
_WINHTTP_OPTION_PROXY=@0x26/*_WINHTTP_OPTION_PROXY*/
_WINHTTP_FIRST_OPTION=@0x1/*_WINHTTP_FIRST_OPTION*/
_WINHTTP_OPTION_USER_AGENT=@0x29/*_WINHTTP_OPTION_USER_AGENT*/
_WINHTTP_OPTION_CONTEXT_VALUE=@0x2D/*_WINHTTP_OPTION_CONTEXT_VALUE*/
_WINHTTP_OPTION_CLIENT_CERT_CONTEXT=@0x2F/*_WINHTTP_OPTION_CLIENT_CERT_CONTEXT*/
_WINHTTP_OPTION_REQUEST_PRIORITY=@0x3A/*_WINHTTP_OPTION_REQUEST_PRIORITY*/
_WINHTTP_OPTION_HTTP_VERSION=@0x3B/*_WINHTTP_OPTION_HTTP_VERSION*/
_WINHTTP_OPTION_DISABLE_FEATURE=@0x3F/*_WINHTTP_OPTION_DISABLE_FEATURE*/
_WINHTTP_OPTION_CODEPAGE=@0x44/*_WINHTTP_OPTION_CODEPAGE*/
_WINHTTP_OPTION_MAX_CONNS_PER_SERVER=@0x49/*_WINHTTP_OPTION_MAX_CONNS_PER_SERVER*/
_WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER=@0x4A/*_WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER*/
_WINHTTP_OPTION_AUTOLOGON_POLICY=@0x4D/*_WINHTTP_OPTION_AUTOLOGON_POLICY*/
_WINHTTP_OPTION_SERVER_CERT_CONTEXT=@0x4E/*_WINHTTP_OPTION_SERVER_CERT_CONTEXT*/
_WINHTTP_OPTION_ENABLE_FEATURE=@0x4F/*_WINHTTP_OPTION_ENABLE_FEATURE*/
_WINHTTP_OPTION_WORKER_THREAD_COUNT=@0x50/*_WINHTTP_OPTION_WORKER_THREAD_COUNT*/
_WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT=@0x51/*_WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT*/
_WINHTTP_OPTION_PASSPORT_COBRANDING_URL=@0x52/*_WINHTTP_OPTION_PASSPORT_COBRANDING_URL*/
_WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH=@0x53/*_WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH*/
_WINHTTP_OPTION_SECURE_PROTOCOLS=@0x54/*_WINHTTP_OPTION_SECURE_PROTOCOLS*/
_WINHTTP_OPTION_ENABLETRACING=@0x55/*_WINHTTP_OPTION_ENABLETRACING*/
_WINHTTP_OPTION_PASSPORT_SIGN_OUT=@0x56/*_WINHTTP_OPTION_PASSPORT_SIGN_OUT*/
_WINHTTP_OPTION_PASSPORT_RETURN_URL=@0x57/*_WINHTTP_OPTION_PASSPORT_RETURN_URL*/
_WINHTTP_OPTION_REDIRECT_POLICY=@0x58/*_WINHTTP_OPTION_REDIRECT_POLICY*/
_WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS=@0x59/*_WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS*/
_WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE=@0x5A/*_WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE*/
_WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE=@0x5B/*_WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE*/
_WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE=@0x5C/*_WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE*/
_WINHTTP_OPTION_CONNECTION_INFO=@0x5D/*_WINHTTP_OPTION_CONNECTION_INFO*/
_WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST=@0x5E/*_WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST*/
_WINHTTP_OPTION_SPN=@0x60/*_WINHTTP_OPTION_SPN*/
_WINHTTP_OPTION_GLOBAL_PROXY_CREDS=@0x61/*_WINHTTP_OPTION_GLOBAL_PROXY_CREDS*/
_WINHTTP_OPTION_GLOBAL_SERVER_CREDS=@0x62/*_WINHTTP_OPTION_GLOBAL_SERVER_CREDS*/
_WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT=@0x63/*_WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT*/
_WINHTTP_OPTION_REJECT_USERPWD_IN_URL=@0x64/*_WINHTTP_OPTION_REJECT_USERPWD_IN_URL*/
_WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS=@0x65/*_WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS*/
_WINHTTP_OPTION_RECEIVE_PROXY_CONNECT_RESPONSE=@0x67/*_WINHTTP_OPTION_RECEIVE_PROXY_CONNECT_RESPONSE*/
_WINHTTP_OPTION_IS_PROXY_CONNECT_RESPONSE=@0x68/*_WINHTTP_OPTION_IS_PROXY_CONNECT_RESPONSE*/
_WINHTTP_OPTION_SERVER_SPN_USED=@0x6A/*_WINHTTP_OPTION_SERVER_SPN_USED*/
_WINHTTP_OPTION_PROXY_SPN_USED=@0x6B/*_WINHTTP_OPTION_PROXY_SPN_USED*/
_WINHTTP_OPTION_SERVER_CBT=@0x6C/*_WINHTTP_OPTION_SERVER_CBT*/
_WINHTTP_LAST_OPTION=@0x6C/*_WINHTTP_LAST_OPTION*/
_WINHTTP_OPTION_USERNAME=@0x1000/*_WINHTTP_OPTION_USERNAME*/
_WINHTTP_OPTION_PASSWORD=@0x1001/*_WINHTTP_OPTION_PASSWORD*/
_WINHTTP_OPTION_PROXY_USERNAME=@0x1002/*_WINHTTP_OPTION_PROXY_USERNAME*/
_WINHTTP_OPTION_PROXY_PASSWORD=@0x1003/*_WINHTTP_OPTION_PROXY_PASSWORD*/
_WINHTTP_CONNS_PER_SERVER_UNLIMITED=@0xFFFFFFFF/*_WINHTTP_CONNS_PER_SERVER_UNLIMITED*/
_WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM=@0x0/*_WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM*/
_WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW=@0x1/*_WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW*/
_WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH=@0x2/*_WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH*/
_WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT=@0x0/*_WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT*/
_WINHTTP_OPTION_REDIRECT_POLICY_NEVER=@0x0/*_WINHTTP_OPTION_REDIRECT_POLICY_NEVER*/
_WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP=@0x1/*_WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP*/
_WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS=@0x2/*_WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS*/
_WINHTTP_OPTION_REDIRECT_POLICY_LAST=@0x2/*_WINHTTP_OPTION_REDIRECT_POLICY_LAST*/
_WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT=@0x1/*_WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT*/
_WINHTTP_DISABLE_PASSPORT_AUTH=@0x0/*_WINHTTP_DISABLE_PASSPORT_AUTH*/
_WINHTTP_ENABLE_PASSPORT_AUTH=@0x10000000/*_WINHTTP_ENABLE_PASSPORT_AUTH*/
_WINHTTP_DISABLE_PASSPORT_KEYRING=@0x20000000/*_WINHTTP_DISABLE_PASSPORT_KEYRING*/
_WINHTTP_ENABLE_PASSPORT_KEYRING=@0x40000000/*_WINHTTP_ENABLE_PASSPORT_KEYRING*/
_WINHTTP_DISABLE_COOKIES=@0x1/*_WINHTTP_DISABLE_COOKIES*/
_WINHTTP_DISABLE_REDIRECTS=@0x2/*_WINHTTP_DISABLE_REDIRECTS*/
_WINHTTP_DISABLE_AUTHENTICATION=@0x4/*_WINHTTP_DISABLE_AUTHENTICATION*/
_WINHTTP_DISABLE_KEEP_ALIVE=@0x8/*_WINHTTP_DISABLE_KEEP_ALIVE*/
_WINHTTP_ENABLE_SSL_REVOCATION=@0x1/*_WINHTTP_ENABLE_SSL_REVOCATION*/
_WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION=@0x2/*_WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION*/
_WINHTTP_DISABLE_SPN_SERVER_PORT=@0x0/*_WINHTTP_DISABLE_SPN_SERVER_PORT*/
_WINHTTP_ENABLE_SPN_SERVER_PORT=@0x1/*_WINHTTP_ENABLE_SPN_SERVER_PORT*/
_WINHTTP_OPTION_SPN_MASK=@0x1/*_WINHTTP_OPTION_SPN_MASK*/
_WINHTTP_ADDREQ_INDEX_MASK=@0xFFFF/*_WINHTTP_ADDREQ_INDEX_MASK*/
_WINHTTP_ADDREQ_FLAGS_MASK=@0xFFFF0000/*_WINHTTP_ADDREQ_FLAGS_MASK*/
_WINHTTP_ADDREQ_FLAG_ADD_IF_NEW=@0x10000000/*_WINHTTP_ADDREQ_FLAG_ADD_IF_NEW*/
_WINHTTP_ADDREQ_FLAG_ADD=@0x20000000/*_WINHTTP_ADDREQ_FLAG_ADD*/
_WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA=@0x40000000/*_WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA*/
_WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON=@0x1000000/*_WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON*/
_WINHTTP_ADDREQ_FLAG_REPLACE=@0x80000000/*_WINHTTP_ADDREQ_FLAG_REPLACE*/
end intellisense**/

/*
WinHTTP 错误代码说明
http://technet.microsoft.com/zh-cn/library/aa383770(en-us,VS.85).aspx
*/