Code: Select all
f:=[]
f.url:="http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-mozilla-central-l10n/firefox-46.0a1.zh-CN.win64.zip"
f.bin:=1
f.Func:="test"
f.title:="firefox Download Test"
MsgBox % ObjTree(dl(f))
test(f){
if f.name="Data"
{
for i,n in f
s.= i "`t`t" n "`n"
ToolTip,% s
}
else
ToolTip
}
Code: Select all
dl(url,byref data:="",byref charset:=""){
static noerr := ComObjError(false),https
,header := {"user-agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36"}
this:=IsObject(url) ? url : {url:url, proxy:data, charset:charset}
, this.WinHttp:=http:=this.WinHttp ? this.WinHttp : this.reuse ? https : https:=ComObjCreate("WinHttp.WinHttpRequest.5.1")
, this.proxy ? http.setproxy(2, this.proxy) : ""
A_Record(this.url)
if this.Func and ((type(this.Func)="BoundFunc") or this.Func:=Func(this.Func).Bind())
{
http.Open("HEAD",this.url),http.Send(this.post),this.CallBack:=[]
WinHttp_Resolve_Header(this.Event_AllHeaders:=http.getAllResponseHeaders(),this.Event_Header:=[])
,this.Len:=this.Event_Header["Content-Length"]
,((i:= Round(this.Len/1024)) < 1024) ?(this.Promptl_Units:=1024,this.Promptl_Len:= "/" i " K") : (this.Promptl_Units:=1048576,this.Promptl_Len:= "/" Round(i/1024, 1) " M")
,this.SetCapacity("pUnk",A_PtrSize*8),Addres:=&this
,NumPut(this.GetAddress("pUnk")+A_PtrSize,pUnk:=this.GetAddress("pUnk"))
for i,n in ["query","addref","release","OnResponseStart","OnResponseDataAvailable","OnResponseFinished",this.OnError?this.OnError:"OnError"]
NumPut(this.CallBack[A_Index]:=RegisterCallback("WinHttp_Event_" n,"F",,Addres),pUnk+A_PtrSize*A_Index)
pCPC:=ComObjQuery(http,"{B196B284-BAB4-101A-B69C-00AA00341D07}"),VarSetCapacity(GUID,16,0)
,DllCall(NumGet(NumGet(pCPC+0,"ptr")+4*A_PtrSize,"ptr"),"ptr",pCPC,"ptr"
,DllCall("ole32\CLSIDFromString","wstr","{f97f4e15-b787-4212-80d1-d380cbbf982e}","ptr",&GUID)>= 0?&GUID:"","ptr*",pCP)
,DllCall(NumGet(NumGet(pCP+0,"ptr")+5*A_PtrSize,"ptr"),"ptr",pCP,"ptr",this.GetAddress("pUnk"),"uint*",Cookie)
}
http.open(this.headers or (charset=0)?"head":this.post?"post" : "get",this.url,true)
(this.page ?http.Option(2):=this.page : "")
http.option(6) := this.NoRedirect ? 0 : 1
if IsObject(this.header)
for i,n in header
this.header[i]?"":this.header[i]:=n
else
this.header:=header
for i,n in this.header
http.SetRequestHeader(i,n)
((this.post) and !this.header["Content-Type"]
? HTTP.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"):"")
,this.Timeout ? http.SetTimeouts(0, 60000, 30000, this.Timeout * 1000) : ""
,Timeout:=this.Timeout = "" ? -1 : this.Timeout
loop (this.try?this.try:1)
{
http.send(this.post)
if (this.RetCode:=http.WaitForResponse(Timeout))=-1
Break
else if A_Index>=this.try
return
}
this.Status:=http.Status,this.StatusText:=http.StatusText
WinHttp_Resolve_Header(this.AllHeaders:=http.getAllResponseHeaders(),this)
if this.headers or (charset=0)
return this
body := http.ResponseBody(), VarSetCapacity(data, size:= body.Length() + 1)
,DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(body), "ptr*",pdata)
,RtlMoveMemory(&data, pdata, size)
,DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(body))
,InStr(this["Content-Encoding"],"gzip") ? Size:=WinHttp_Gzip_Decomp(data, Size) : ""
,this.Size:=Size
return (this.file
? (FileExist(dir:=SubStr(this.File,1,InStr(this.File,"\","",-1)))?"":DirCreate(dir)
,FileOpen(this.file, "w").RawWrite(&data, size),this)
: this.bin
?(isByRef("data")?"":(this.Delete("Bin"),this.SetCapacity("Bin",Size),RtlMoveMemory(this.GetAddress("Bin"),&data,Size)),this)
: ((encoding:=this.charset?this.charset:"UTF-8")
, s:=StrGet(&data, size>>(encoding="utf-16"||encoding="cp1200"),encoding)
, this.result ? (this.text:=s,this) : s))
}
WinHttp_Event_query(self,riid,pObj){
return NumPut(self,pObj+0)*0
}
WinHttp_Event_addref(self){
return 1
}
WinHttp_Event_release(self){
return 0
}
WinHttp_Event_OnResponseStart(self,Status,ContentType){
static code:={200:"OK",404:"Not Found"}
this:=Object(A_EventInfo)
,DllCall("QueryPerformanceFrequency","Int64*",Frequency)
,DllCall("QueryPerformanceCounter","Int64*",Counter)
,this.ResponseStart := code[status]?code[status]:Status
,this.Current_Len := 0
,this.Event_Frequency := Frequency
,this.Event_Counter := Counter
}
WinHttp_Event_OnResponseDataAvailable(self,Data){
this:=Object(A_EventInfo)
SafeArrayGetUBound(NumGet(Data,"PTR"),1,getvar(sz:=0))
this.Current_Len+=sz + 1
DllCall("QueryPerformanceCounter", "Int64*", Counter)
time:=(Counter-this.Event_Counter)/this.Event_Frequency
if (time>=1)
{
this.Event_Counter:=Counter
if this.Func
this.Func.call({this:this,name:"Data",total:this.Len,Current:this.Current_Len,process:Round(this.Current_Len/this.Promptl_Units,1) this.Promptl_Len
,scale:Round(this.Current_Len/this.Len*100,1),speed:Round((((this.Current_Len-this.Current_Mark)/1024)/time)),title:this.title})
this.Current_Mark:=this.Current_Len
}
}
WinHttp_Event_OnResponseFinished(self){
this:=Object(A_EventInfo)
for k,v in this.Delete("CallBack")
GlobalFree(v)
if this.Func
this.Func.call({this:this,name:"Finished",self:self})
}
WinHttp_Event_OnError(self,ErrorNumber,ErrorDescription){
this:=Object(A_EventInfo)
if this.Func
this.Func.call({this:this,name:"Error",self:self,ErrorNumber:ErrorNumber,ErrorDescription:ErrorDescription})
}
WinHttp_Resolve_Header(ByRef Header,ByRef this){
Loop,parse,% Header,`n,`r `t
(s:=InStr(A_LoopField,":"))
? (this[p:=SubStr(A_LoopField, 1,s-1)]?(this[p].="||" Trim(SubStr(A_LoopField, s+1))):(this[p]:=Trim(SubStr(A_LoopField, s+1))))
: this[A_LoopField]:=""
}
WinHttp_Gzip_Decomp(ByRef var, nSz:=0){
static Module
if !Module
ifLoadLibrary(A_ahkDir "\Extend\Library\gzip.dll")
vSz := NumGet( var,nsz-4 ), VarSetCapacity( out,vsz,0)
,DllCall( "GZIP\InitDecompression" ),DllCall( "GZIP\CreateDecompression", UIntP,CTX, UInt,1 )
If ( DllCall( "GZIP\Decompress", UInt,CTX, UInt,&var, UInt,nsz, UInt,&Out, UInt,vsz, UIntP,input_used, UIntP,output_used ) = 0 && ( Ok := ( output_used = vsz ) ) )
VarSetCapacity( var,64 ), VarSetCapacity( var,0 ), VarSetCapacity( var,vsz,32 ), RtlMoveMemory(&var,&out,vsz )
DllCall( "GZIP\DestroyDecompression", UInt,CTX ), DllCall( "GZIP\DeInitDecompression" )
Return Ok ? vsz : 0
ifLoadLibrary(dll){
Return (Module:=DllCall("GetModuleHandle", "Str",dll, "Ptr"))?Module:DllCall("LoadLibrary","Str",dll, "Ptr")
}
}