[H2] oh() - 对象化 http 包装

许多实用脚本和封装函数, 可以让您编写脚本更加便捷高效

Moderators: tmplinshi, arcticir

arcticir
Posts: 693
Joined: 17 Nov 2013, 11:32

[H2] oh() - 对象化 http 包装

23 Aug 2016, 01:18

基础示例:

Code: Select all

#Include <ObjTree>
f:={option:option:=[],head:head:=[]}
f.url:="http://www.bing.com/search?qs=bs&&first=50form=QBLH&q=AutoHotkey"
f.type:="get"
f.Agent:="Mozilla/5.0 (Linux; Android 6.1.1; Nexus 7 Build/JRO03S) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/48.0.1025.166 Safari/535.19"
f.end:="ObjTree"
option[6]:=70000
head["Content-Type"]:="application/x-www-form-urlencoded"
oh(f)
MsgBox,Test
输出:
  • time - 耗时
    heads - Headers
    list - 对象化 Headers 项 (f.list.Etag)
    size - 数据大小
    err - 错误信息
    txet - 网页数据
    bin - 下载二进制数据到变量
    hash - MD2/MD4/MD5/SHA1/SHA256/SHA384/SHA512, If in
    json - json-Object
    decode
    affix - 附加信息
    • gzip-size - Original size
      charset

输入:
  • url
    name - Naming
    head - 参数对象
    option - 参数对象
    type - 请求方案 (get,post,head...)
    pug - 进度回调函数
    end - 完成回调函数
    decide - 获取标头后,指定函数判断是否继续执行
    gh - (true) 获取 Headers ; OR type:="head"
    agent - user-agent settings
    file - 文件路径
    fileName - 自动获取文件名.无法时将使用它的值作为默认名称. 需要在"file"指定目录.
    fileExt - 同上
    bin - (true) (f.bin)
    decode - (true) Web 解码 (f.decode)
    json - (true) 将 Web 数据转换为对象 (f.json)
    hash - hash类型
    Verify - (true) 强制验证大小
    proxy
    charset
    referer

Image





=============




oh()

Code: Select all

oh(this,proxy:="",file:=""){
        IsObject(this)?"":this:={url:this,proxy:proxy,file:file}, this.time:=ahktime(), this.affix:=affix:=[],IsObject(this.head)?"":this.head:=[]
        ,this.post?(this.type:="post",IsObject(this.post)?oh_FormData(this,body):this.length:=StrPutVar(this.post,body,"utf-8")):""
        ,asynch := False,VarSetCapacity(callbackValue,A_PtrSize)
        ,VarSetCapacity(myStruct,60,0)
        ,numput(60,myStruct,0,"Uint") ; this dll function requires this to be set
        ,numput(1,myStruct,8,"Uint") ; SchemeLength
        ,numput(1,myStruct,20,"Uint") ; HostNameLength
        ;numput(1,myStruct,32,"Uint") ; UserNameLength
        ;numput(1,myStruct,40,"Uint") ; PasswordLength
        ,numput(1,myStruct,48,"Uint") ; UrlPathLength
        ,numput(1,myStruct,56,"Uint") ; ExtraInfoLength
        ,DllCall("Winhttp.dll\WinHttpCrackUrl","PTR",&(this.url),"UInt",StrLen(this.url),"UInt",0,"PTR",&myStruct)
        ,scheme := StrGet(NumGet(myStruct,4,"Ptr"),NumGet(myStruct,8,"UInt"))
        ;userName := StrGet(NumGet(myStruct,28,"Ptr"),NumGet(myStruct,32,"UInt"))
        ;password := StrGet(NumGet(myStruct,36,"Ptr"),NumGet(myStruct,40,"UInt"))
        ,hostName := StrGet(NumGet(myStruct,16,"Ptr"),NumGet(myStruct,20,"UInt"))
        ,port := NumGet(myStruct,24,"Int")
        ,urlPath := StrGet(NumGet(myStruct,44,"Ptr"),NumGet(myStruct,48,"UInt"))
        ,extraInfo := StrGet(NumGet(myStruct,52,"Ptr"),NumGet(myStruct,56,"UInt"))
        ,https := scheme = "https" ?(port:=port?port:443,True):False
        ,resource := urlPath . extraInfo
        if this.list
                IsObject(this.old)?"":this.old:=[],this.history.push(this.delete("list"))

;------                                                                         ------

        if (this.hs:=hSession := DllCall("Winhttp.dll\WinHttpOpen" ,uptr, &(this.Agent?this.Agent
                        :"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.2806.0 Safari/537.36")
                        ,uint, this.proxy?3:1,uptr,this.proxy?&(this.proxy):0,uptr, 0,uint,asynch))
                and (this.hc:=hConnect:=DllCall("Winhttp.dll\WinHttpConnect",uptr,hSession,uptr,&hostName,ushort,port,uint,0))
                and (this.hr:=hRequest := DllCall("Winhttp.dll\WinHttpOpenRequest" ,uptr,hConnect ,uptr,this.type ? &(this.type) : 0 ,uptr,(resource) ? &resource : 0
                                ,uptr,(httpVersion) ? &httpVersion : 0 ,uptr,this.Referer ? &(this.Referer) : 0 ,uptr, 0 ,uint,(https) ? 0x00800000 : 0))
                for i,n in this.option
                {
                        VarSetCapacity(opt,sz:=NumSize(n)),NumPut(n,&opt,NumType(n))
                        if !DllCall("Winhttp.dll\WinHttpSetOption" ,uptr,hRequest ,uint,i ,uptr,&opt ,uint,sz)
                                this.err.="SetOption`t" i "-" n ": " A_LastError "-" ErrorMessage(A_LastError) "`n"
                }
                else    Return  oh_close(this,ErrorLevel "  " A_LastError " " ErrorMessage(A_LastError))

;------                                                                         ------

        for i,n in this.head
                ah .= i ": " n "`r`n"
        for i,n in {"Accept-Encoding":(this.gh?"":"gzip, ") "deflate"}
                this.head.haskey(i)?"":ah .= i ": " n "`r`n"

        VarSetCapacity(body) ? (i:=&body,n:=this.length?this.length:StrLen(body)*2) : i:=n:=0
        if !DllCall("Winhttp.dll\WinHttpSendRequest" ,uptr,hRequest ,uptr,&ah ,uint,StrLen(ah) ,uptr,i ,uint,n ,uint,n ,uptr,&callbackValue)
                Return  oh_close(this,"Send Request")

        if !DllCall("Winhttp.dll\WinHttpReceiveResponse",uptr,hRequest,uptr,0)
                Return  oh_close(this,"Response")

;------                                                                         ------

        VarSetCapacity(s, dwSize:=60000, 0)
        if DllCall("Winhttp.dll\WinHttpQueryHeaders",uptr,hRequest,uint,22,uptr,0,uptr, &s,UIntP, dwSize,uptr, 0)
        {
                VarSetCapacity(s,-1),this.heads:=s:=trim(s,"`n`r"),i:=InStr(s,"`r`n"),f:=StrSplit(SubStr(s,1,i-1), " ")
                ,this.list:=list:={HttpVersion:f[1],StatusCode:f[2],StatusText:f[3]}
                Loop, parse, % SubStr(s,i+2), `n, `r
                        (list[s:=Trim(SubStr(A_LoopField,1,InStr(A_LoopField,": ")-1))]
                                ? list[s].="; " Trim(SubStr(A_LoopField,InStr(A_LoopField,": ")+2))
                                : list[s]:= Trim(SubStr(A_LoopField,InStr(A_LoopField,": ")+2)))
        }
        if this.gh or (this.type="head") or (this.decide and (IsObject(f:=this.decide) or (f:=func(f))) ? f.call(this):"")
                return oh_close(this)

        if (len:=list["Content-Length"]) and this.pug and (isobject(this.pug) or this.pug:=func(this.pug))
        {
                ((i:=Round(len/1024)) < 1024) ?(Size_Units:=1024,Size_Total:= "/" i " K") : (Size_Units:=1048576,Size_Total:= "/" Round(i/1024, 1) " M")
                ,DllCall("QueryPerformanceFrequency","Int64*",Frequency)
                ,DllCall("QueryPerformanceCounter","Int64*",time_Mark)
                ,this.timeMark:=time_Mark,this.Frequency:=Frequency
        }

;------                                                                         ------

        Body := "",Size:=0,VarSetCapacity(dwDownloaded,8),r:=&dwSize
        Loop
        {
                dwSize := 0
                If (!DllCall("Winhttp.dll\WinHttpQueryDataAvailable",uptr,hRequest,uptr,r))
                        Return  oh_close(this,"DataAvailable")
                Else
                        dwSize := (dwSize)+0

                If (!dwSize)
                        Break

                VarSetCapacity(pszOutBuffer,(dwSize)+1,0)
                If !DllCall("Winhttp.dll\WinHttpReadData",uptr,hRequest,uptr,&pszOutBuffer,uint,dwSize,uptr,&dwDownloaded)
                {
                        this.err.="ReadData: " ErrorMessage(A_LastError) "`n"
                }
                Else
                {
                        VarSetCapacity(data, Size+dw:=Ord(dwDownloaded))
                        ,DllCall("RtlMoveMemory", "ptr", &data+Size, "ptr", &pszOutBuffer, "ptr", dw),Size+=dw

                        if this.pug and len
                        {
                                DllCall("QueryPerformanceCounter", "Int64*", Counter)
                                time:=(Counter-time_Mark)/Frequency
                                if  (time>=1)
                                {
                                this.pug.call({this:this,event:"Progres",total:len,Current:Size,Progres:Round(Size/Size_Units,1) Size_Total
                                ,scale:(Round(Size/len*100,1) " `%"),speed:(Round((((Size-Size_Mark)/1024)/time)) " KB")})
                                Size_Mark:=Size,time_Mark:=Counter
                                }
                        }
                }
                If (!dw) or (dwSize <= 0)
                        break
        }
        if this.pug
                this.pug.call({this:this,event:"Finish"})

;------                                                                         ------

        if (this.Verify or this.file or this.bin) and (len and (Size!=len))
                return oh_close(this,"Size Err:" Size "/" len)

        if InStr(list["Content-Encoding"],"gzip")
                size:=UnZipBuffer(&data, affix["gzip-size"]:=size, "",gzip),VarSetCapacity(data, size, 0)
                ,gzip:=DllCall("RtlMoveMemory", "ptr", &data, "ptr", &gzip, "ptr", Size)

        this.size:=size
        if this.hash
                this.hash:=oh_Hash(this.hash,&data,size)

        if this.bin or this.file=1
        {
                this.Delete("Bin"),this.SetCapacity("Bin",Size),DllCall("RtlMoveMemory","ptr",this.GetAddress("Bin"),"ptr",&data, "ptr",Size)
        }
        else    if this.file
        {
                if this.fileName
                {
                        if (s:=this.list["Content-Disposition"]) and r:=InStr(s, "filename=")
                                name:=(m:=InStr(s,";",,i:=r+10))?SubStr(s, i,m-i):SubStr(s, i)
                        this.file:=this.File "\" (name ? name : f.fileName)
                }
                else if f.fileExt
                {
                        if s:=this.list["Content-Type"]
                                ext:=SubStr(s, i:=InStr(s, "/")+1,(r:=InStr(s, ";"))?r-i:22)
                        this.file:=this.File "." (ext ? ext: this.fileExt)
                }
                FileExist(d:=SubStr(this.file,1,InStr(this.file,"\","",-1)))?"":DirCreate(d),FileOpen(this.file, "w").RawWrite(&data, size)
        }
        else
        {
                affix.charset:=eg:=this.charset?this.charset:(s:=InStr(t:=list["Content-Type"],"charset="))?substr(t,r:=s+8,(u:=InStr(t,";",,r))?u-r:10):ch:="UTF-8"
                ,s:=StrGet(&data, size>>(eg="utf-16"||eg="cp1200"),eg)
                if ch and InStr(t,"text/html") and (i:=InStr(s,"charset=")) ;Recognition charset
                        and (ch:=(i:=Trim(SubStr(s, e:=i+8,RegExMatch(s,"`'|`"|>|//",,i+9)-e),"`'`"/")) ? InStr(i,"gb")?"CP936":(instr(i,"cp") or instr(i,"-"))?i: StrReplace(i,"utf","utf-") :"")
                        and (eg!=ch)
                        s:=StrGet(&data, size>>(r="utf-16"||r="cp1200"),affix.charset:=ch)
                this.text:=s
                if this.Decode
                        this.Decode:=Decode_All(s)
                if this.json and RegExMatch(s, "s)^[\[|\{].*[\]|\}]$")
                        this.json:=so(s,0)
                if !this.result
                        return oh_close(this),s
        }
        Return oh_close(this)
}

oh_close(f,s:=""){
        Loop,Parse,rcs
                if n:=f.delete("h" A_LoopField)
                        DllCall("winhttp\WinHttpCloseHandle", "Ptr", n)
        if s
        {
                f.err.=s
                if f.pug
                        f.pug.call({this:f,event:"Err"})
        }
        if f.end  and (isobject(f.end) or f.end:=func(f.end))
                f.end.call(f)
        Return f.time:=ahktime(f.time),f
}

oh_Hash(type,addr, length:=""){
	h := {MD2: 0x8001,MD4: 0x8002,MD5: 0x8003,SHA1: 0x8004,SHA256: 0x800c,SHA384: 0x800d,SHA512: 0x800e,1:0,2:1, 3:2, 4:3, 5:4, 6:5, 7:6, 8:7, 9:8, 10:9, 11:"a", 12:"b", 13:"c", 14:"d", 15:"e", 16:"f"}
	,hProv := hHash := o := "",hash := 0, hashlength := 0,(addr+0)?""
	:length?(length:=StrPutVar(addr,data,length)-1,addr:=&data)
		:(f := FileOpen(addr, "r"),VarSetCapacity(data, f.length, 0),addr:=&data,f.rawRead(&data, length:=f.length),f.Close())
	if (DllCall("advapi32\CryptAcquireContext", "Ptr*", hProv, "Ptr", 0, "Ptr", 0, "UInt", 24, "UInt", 0xf0000000))
	{
		if (DllCall("advapi32\CryptCreateHash", "Ptr", hProv, "UInt", h[type], "UInt", 0, "UInt", 0, "Ptr*", hHash))
		{
			if (DllCall("advapi32\CryptHashData", "Ptr", hHash, "Ptr", addr, "UInt", length, "UInt", 0))
			and DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", 0, "UInt*", hashlength, "UInt", 0)
			and VarSetCapacity(hash, hashlength, 0)
			and DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", &hash, "UInt*", hashlength, "UInt", 0)
				loop hashlength
					v := NumGet(hash, A_Index - 1, "UChar"),o .= h[(v >> 4) + 1] h[(v & 0xf) + 1]
			DllCall("advapi32\CryptDestroyHash", "Ptr", hHash)
		}
		DllCall("advapi32\CryptReleaseContext", "Ptr", hProv, "UInt", 0)
	}
	return o
}

oh_FormData(this,ByRef body){
        Boundary := SubStr(StrReplace(Sort("0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z","D| Random"), "|"), 1, 12)
        crlf := "`r`n",line := "--" . Boundary
        VarSetCapacity(body,0),ohfset := 0
        For k, v in this.post
                If IsObject(v)
                {
                        For i, FileName in v
                        {
                                file:=FileOpen(FileName, "r"),n := file.ReadUInt()
                                ,buffer := line crlf "Content-Disposition: form-data; name=`"" . k . "`"; filename=`"" . FileName . "`"" . crlf
                                        . "Content-Type: " . ((n        = 0x474E5089) ? "image/png"
                                        : (n        = 0x38464947) ? "image/gif"
                                        : (n&0xFFFF = 0x4D42    ) ? "image/bmp"
                                        : (n&0xFFFF = 0xD8FF    ) ? "image/jpeg"
                                        : (n&0xFFFF = 0x4949    ) ? "image/tiff"
                                        : (n&0xFFFF = 0x4D4D    ) ? "image/tiff"
                                        : "application/octet-stream") . crlf . crlf
                                ,oh_memory(body,buffer,ohfset,StrLen(buffer),1)
                                ,bufferSize := VarSetCapacity(buffer,file.Length)
                                ,File.Tell(0),file.RawRead(&buffer, bufferSize)
                                ,oh_memory(body,buffer,ohfset,bufferSize,0)
                                ,oh_memory(body,crlf,ohfset,2,1)
                        }
                }
                Else
                {
                        buffer := line . crlf . "Content-Disposition: form-data; name=`"" . k "`"" . crlf . crlf . v . crlf
                        oh_memory(body,buffer,ohfset,StrLen(buffer),1)
                }
        oh_memory(body,buffer:= line "--" crlf,ohfset,StrLen(buffer),1)
        ,this.head["Content-Type"]:="multipart/form-data; boundary=" . Boundary
        ,this.length:=ohfset
}

oh_memory(ByRef f,ByRef k,ByRef p,ByRef s,t){
        r:=p,VarSetCapacity(f,p+= s),t?StrPut(k, (&f)+r, s, "CP0"):DllCall("RtlMoveMemory", "Ptr", &f+r, "Ptr", &k, "UInt", s)
}

str_f(Str,Split,Chars,Omit:="`r `t",f:=""){
	f?"":f:=[]
	Loop, parse,% Str,% Split, % Omit
		(s:=InStr(r:=A_LoopField,Chars))
			? (f[p:=Trim(SubStr(r, 1,s-1),Omit)]?(f[p].="||" Trim(SubStr(r, s+1)),Omit):(f[p]:=Trim(SubStr(r, s+1))),Omit)
			: f[r]:=""
    return f
}

Decode_Html(ByRef str){
	oscs := A_StringCaseSense
	StringCaseSense, On
	Loop, Parse,% "middot,·/nbsp, /#160, /lt,</#60,</gt,>/#62,>/amp,&/#38,&/quot,`"/#34,`"/apos,`'/#39,`'/cent,¢/#162,¢/pound,£/#163,£/yen,¥/#165,¥/euro,€/#8364,€/sect,§/#167,§/copy,©/#169,©/reg,®/#174,®/trade,™/#8482,™/times,×/#215,×/divide,÷/#247,÷/OElig,Œ/oelig,œ/Scaron,Š/scaron,š/Yuml,Ÿ/fnof,ƒ/circ,ˆ/tilde,˜/Alpha,Α/Beta,Β/Gamma,Γ/Delta,Δ/Epsilon,Ε/Zeta,Ζ/Eta,Η/Theta,Θ/Iota,Ι/Kappa,Κ/Lambda,Λ/Mu,Μ/Nu,Ν/Xi,Ξ/Omicron,Ο/Pi,Π/Rho,Ρ/Sigma,Σ/Tau,Τ/Upsilon,Υ/Phi,Φ/Chi,Χ/Psi,Ψ/Omega,Ω/alpha,α/beta,β/gamma,γ/delta,δ/epsilon,ε/zeta,ζ/eta,η/theta,θ/iota,ι/kappa,κ/lambda,λ/mu,μ/nu,ν/xi,ξ/omicron,ο/pi,π/rho,ρ/sigmaf,ς/sigma,σ/tau,τ/upsilon,υ/phi,φ/chi,χ/psi,ψ/omega,ω/thetasym,ϑ/upsih,ϒ/piv,ϖ/ensp, /emsp, /thinsp, /zwnj,‌/zwj,‍/lrm,‎/rlm,‏/ndash,–/mdash,—/lsquo,‘/rsquo,’/sbquo,‚/ldquo,“/rdquo,”/bdquo,„/dagger,†/Dagger,‡/bull,•/hellip,…/permil,‰/prime,′/Prime,″/lsaquo,‹/rsaquo,›/oline,‾/frasl,⁄/euro,€/image,ℑ/weierp,℘/real,ℜ/trade,™/alefsym,ℵ/larr,←/uarr,↑/rarr,→/darr,↓/harr,↔/crarr,↵/lArr,⇐/uArr,⇑/rArr,⇒/dArr,⇓/hArr,⇔/forall,∀/part,∂/exist,∃/empty,∅/nabla,∇/isin,∈/ni,∋/prod,∏/sum,∑/minus,−/lowast,∗/radic,√/prop,∝/infin,∞/ang,∠/and,∧/or,∨/cap,∩/cup,∪/int,∫/there4,∴/sim,∼/cong,≅/asymp,≈/ne,≠/equiv,≡/le,≤/ge,≥/sub,⊂/sup,⊃/nsub,⊄/sube,⊆/supe,⊇/oplus,⊕/otimes,⊗/perp,⊥/sdot,⋅/lceil,⌈/rceil,⌉/lfloor,⌊/rfloor,⌋/lang,⟨/rang,⟩/loz,◊/spades,♠/clubs,♣/hearts,♥/diams,♦", /
	(InStr(str,i:="&" SubStr(s,1,(r:=InStr(s:=A_LoopField,","))-1) ";")?str:=StrReplace(str,i,SubStr(s,r+1)):"")
	Return StringCaseSense(oscs),str
}


Decode_Escape(ByRef str){
	f:=[]
	if i:=InStr(str,"\u")
	for i,n in StrSplit(SubStr(str,i+2),"\u")
		(n and !f[b:=SubStr(n, 1, 4)]
			? (f[b]:=1,(s := Abs("0x" b))?(str:=StrReplace(str,"\u" b,Chr(s))):"")
			: "")
	return str
}

Decode_Ascii(ByRef str){
	Loop, Parse,01|02|03|04|05|06|07|08|09|0a|0b|0c|0d|0e|0f|10|11|12|13|14|15|16|17|18|19|1a|1b|1c|1d|1e|1f|20|21|22|23|24|25|26|27|28|29|2a|2b|2c|2d|2e|2f|30|31|32|33|34|35|36|37|38|39|3a|3b|3c|3d|3e|3f|40|41|42|43|44|45|46|47|48|49|4a|4b|4c|4d|4e|4f|50|51|52|53|54|55|56|57|58|59|5a|5b|5c|5d|5e|5f|60|61|62|63|64|65|66|67|68|69|6a|6b|6c|6d|6e|6f|70|71|72|73|74|75|76|77|78|79|7a|7b|7c|7d|7e|7f,|
	InStr(str,"\x" A_LoopField)?str:=StrReplace(str,"\x" A_LoopField,Chr("0x" A_LoopField)):""
	return str
}

Decode_All(ByRef str){
	return Decode_Html(Decode_Escape(Decode_Ascii(str)))
}
so(s,type:="",Mark:=""){
	static y:="`"",j:="`" `t",m:={"\b":Chr(08),"\\":"\","\t":"`t","\n":"`n","\f":Chr(12),"\r":"`r"},gu:="āЁξ"
	if Isobject(s)
	{
		if !InStr(Type(s),"Object")
			Return
		if !type
			(First:=type=0?1:2,type:={&s:1})
		else if type[&s]
			Return "**"
		else type[&s]:=1
		if !Count:=s.Count()
			Return "[]"
		if w:= (Count = s.Length())
			for k in s
				if (k != A_Index)
				{
					w:=""
					Break
				}
		if w
		{
			for i,n in s
				str.=(Isobject(n)?so(n,type): n+0=""?(gu n gu):n) ","
		}
		else
		{
			for i,n in s
				str.=(Isobject(i)?so(i,type):i+0=""?(gu i gu):i) ":" (Isobject(n)?so(n,type): n+0=""?(gu n gu):n) ","
		}

		if First
		{
			if First=1
			{
				StrReplace, str, %str%,% "`n",% "``n"
				StrReplace, str, %str%,% y,% "``" y
				StrReplace, str, %str%,% gu,% y
			}
			else
			{
				StrReplace, str, %str%,/,\/
				for c,z in m
					IF InStr(str,z)
						StrReplace, str, %str%,% z,% c
				StrReplace, str, %str%,% y,% "\" y
				StrReplace, str, %str%,% gu,% y
			}
		}
		Return str:=RTrim(str,","),w?"[" str "]":"{" str "}"
	}

	f:=[],i:=1,n:=type
	if n
		b:=StrLen(s),jx:=Mark.jx,json:=Mark.json
	else
	{
		if !(s:=Trim(s," `n`r`t")) or !regexmatch(s, "[\[\{]")
			Return s


		if json:=(n=0) ; so(s,0) json
		{
			for c,z in m
				if InStr(s,c)
					StrReplace,s,% s,% c,% z
			StrReplace, s, %s%,\/,/
			if e:=InStr(s,"\u")
				for e,n in StrSplit(SubStr(s, e+2), "\u")
					IF n and !f[b:=SubStr(n, 1, 4)]
					{
						IF d := Abs("0x" b)
							StrReplace,s,% s,% "\u" b,% Chr(d)
						f[b]:=1
					}
		}

		f:=[],b:=StrLen(s),n:=SubStr(s,i,1),d:=0,jx:=json?"\":"``"
		Mark:={jx:jx,json:json,d:d}
	}

	if (n="{")
		loop
		{
			if ((r?r[0]:"") = "}") or !i or !( i:=RegExMatch(s,"\S",n,i+1) ) or ((n:=n[0]) = "}")
				Return Mark.d:=i,f

			if InStr("[{",n)
				 (k:=so(SubStr(s,i),n,Mark),i+=Mark.D,i:=RegExMatch(s,"\S",t,InStr(s,":",,i)+1),(InStr("[{",t:=i?t[0]:"")
					? (f[so_json(K,json) ""]:=so(SubStr(s,i),t,Mark),i:=RegExMatch(s,",|\}",r,i+Mark.D))
					: ( ((t=y) 	? (p:=InStr(s,y,,i+1),p:=RegExMatch(s,",|\}",r,p),z:=Trim(SubStr(s,i+1,p-i-2))) 
									: (p:=RegExMatch(s,",|\}",r,i),z:=Trim(SubStr(s,i,p-i)),z:=z+0=""?so_Try(z):z+0))
								,f[so_json(K,json) ""]:=so_json(K,json),i:=p)) )
			else
				 (x:=InStr(s,":",,(n=y)?InStr(s,y,,i,2):i))
					? (k:= ((n=y)?SubStr(s,i+1,x-i-2):SubStr(s,i,x-i))
						,k:=(n=y ? Trim(k) : n="(" ? so_Try(Trim(k,"() `t")):Trim(k)),i:=RegExMatch(s,"\S",t,x+1)
						,InStr("[{",t:=i?t[0]:"")
							? (f[so_json(K,json)  ""]:=so(SubStr(s,i),t,Mark),i:=RegExMatch(s,",|\}",r,i+Mark.D))
							: ( ((t=y) 	? (p:=RegExMatch(s,",|\}",r,so_InStr(s,i,jx)),z:=Trim(SubStr(s,i+1,InStr(s,y,,p-b-1)-i-1))) 
									: (p:=RegExMatch(s,",|\}",r,i),z:=Trim(SubStr(s,i,p-i)),z:=z+0=""?so_Try(z):z+0))
								,f[so_json(K,json)  ""]:=so_json(Z,json),i:=p))
					: i:=0
		}

	if (n = "[")
		loop
		{
			if ((r?r[0]:"") = "]") or !i or !( i:=RegExMatch(s,"\S",n,i+1) ) or ((n:=n[0]) = "]")
				Return Mark.D:=i,f
			(InStr("[{",n)
				? (f.Push(so(SubStr(s,i),n,Mark)),i:=RegExMatch(s,",|\]",r,i+Mark.D))
				: (  (n=y) ? (p:=RegExMatch(s,",|\]",r,so_InStr(s,i,jx)),z:=(SubStr(s,i+1,InStr(s,y,,p-b-1)-i-1))) 
					: (p:=RegExMatch(s,",|\]",r,i),z:=Trim(SubStr(s,i,p-i)),z:=z+0=""?so_Try(z):z+0),i:=p
					,f.Push(so_json(Z,json))))
		}

}

so_json(s,json){
	static J:="\`"",P:="`""
	Return json AND InStr(s,J)?StrReplace(S,J,P):S
}

so_InStr(s,i,jx){
	while (p:=InStr(s,"`"",,i+1)) and (SubStr(s,p-1,1)=jx)
		i:=p
	Return p
}

so_Try(f){
	global
	Try
	Return  (%f%)
}
NumType(v){
  return InStr(v,".")?"Double":v>4294967295?"UInt64":v>65535?"UInt":v>255?"UShort":v>-1?"UChar":v>-129?"Char":v>-32769?"Short":v>-2147483649?"Int":"Int64"
}
NumSize(v){
  return InStr(v,".")||v>4294967295?8:v>65535?4:v>255?2:v>-129?1:v>-32769?2:v>-2147483649?4:8
}
ahktime(s:=0,i:=6) {
	static r:=(DllCall("QueryPerformanceFrequency",Int64P,r),r)
	Return DllCall("QueryPerformanceCounter",Int64P,n),(s ? Round((n-s)/r, i) : n)
}


附:
  • 自动请求 gzip
    自动识别 charset
Last edited by arcticir on 23 Aug 2016, 22:34, edited 8 times in total.
arcticir
Posts: 693
Joined: 17 Nov 2013, 11:32

Re: [H2] oh() - Object-oriented packaging http

23 Aug 2016, 06:31

Example:


下载页面到变量

Code: Select all

MsgBox % oh("http://www.bing.com/search?qs=bs&&first=50form=QBLH&q=AutoHotkey")
; or:
f:=oh({url:"http://www.bing.com/search?qs=bs&&first=50form=QBLH&q=AutoHotkey",result:1})
MsgBox % f.text

获取 API JSON 并转换为对象

Code: Select all

f:=[]
f.url:="https://query.yahooapis.com/v1/public/yql?q=select`%20*`%20from`%20html`%20where`%20url`%3D'http`%3A`%2F`%2Fen.wikipedia.org`%2Fwiki`%2FYahoo'`%20and`%20xpath`%3D'`%2F`%2Ftable`%2F*`%5Bcontains(.`%2C`%22Founder`%22)`%5D`%2F`%2Fa'&format=json&env=store`%3A`%2F`%2Fdatatables.org`%2Falltableswithkeys"
f.json:=1
oh(f)
MsgBox % ObjTree(f.json)

下载图片并上传到 google 搜索

Code: Select all

if (f:=oh("https://autohotkey.com/boards/styles/simplicity/theme/images/logo.png",,a_ahkdir "\ahk.png")) and !f.err
MsgBox % googleImageUpload(a_ahkdir "\ahk.png")
else
MsgBox Download error
FileDelete,% a_ahkdir "\ahk.png"

googleImageUpload(File){
	f:={}
	f.url	:= "https://www.google.com/searchbyimage/upload"
	f.post:={ "encoded_image": [File],  "hl":"zh-CN"}
	oh(f)
	if s:=str_s(f.text,"sbi:","&")
	return "https://www.google.com/search?tbs=sbi:" s "&hl=zh-CN&sourceid=chrome&client=chrome&filter=0"
}
str_s(ByRef s,i,n,r:=1){
	Return si:=StrLen(i),tt:=(b:=(t:=InStr(s,i,,,r)) and (p:=InStr(s,n,,u:=t+si))?SubStr(s,u,p-u):"")?(t:=InStr(b,i,,-1))?substr(b,t+si):b:""
}

下载 ahk.exe, 并验证是否需要升级

Code: Select all

f:=[]
f.url:="https://github.com/HotKeyIt/ahkdll-v2-release/raw/master/Win32w/AutoHotkey.exe"
f.bin:=1 ;Download file into variable
f.hash:="md5"
oh(f)

if f.err
	MsgBox Download error
else
if oh_Hash("md5",A_AhkPath)=f.hash
	MsgBox Dont need to update
else
{
	FileMove,% A_AhkPath,% A_AhkPath ".delete"
	FileOpen(A_AhkPath, "w").RawWrite(f.GetAddress("bin"), f.size)
	MsgBox Update completed
}

获取 http headers

Code: Select all

f:={option:o:=[]}
f.url:="http://dwz.cn/3ZUOAQ"
f.type:="head" ;or f.gh:=1
o[63]:=0x00000002 ;Set Prohibit redirects option
oh(f)
MsgBox % "Location:`n" f.list.Location "`n`nAll headers:`n" f.heads

下载 Vivaldi 并显示进度
Image

Code: Select all

f:=[]
;f.proxy:="127.0.0.1:8118"
f.url:="http://repo.vivaldi.com/snapshot/deb/dists/stable/main/binary-i386/Packages"
s:=StrReplace(oh(f),"`r`n","`n"),v:=[],b:=[]
for i,n in f:=StrSplit(s, "`n`n")
	if n
	{
		s:=str_f(n,"`n",":")
		IsObject(b[s.Package])?"":b[s.Package]:=[]
		b[s.Package].push(n)
		v.push(s)
	}
f:={time:v,Package:b}
v:=f.time[f.time.Length()]
s:= v.Version
if !Version:=instr(s,"-")?SubStr(s, 1,instr(s,"-")-1):s
{
	MsgBox, Unable to get version information
	ExitApp
}
ToolTip Vivaldi-%Version%`nStart  download 
f:={}
;f.proxy:="127.0.0.1:8118"
f.file:=A_temp "\vivaldi.exe"
f.url:= "https://downloads.vivaldi.com/stable/Vivaldi." Version (A_Is64bitOS?".x64":"") ".exe"
f.pug:="Vivaldi_progress"
f.name:="Vivaldi-" Version
oh(f)

if f.err
MsgBox, Download error
else
MsgBox, Download complete

Vivaldi_progress(f){
	if f.event="Progres"
	ToolTip,% f.this.name "`nProgress: " f.Progres "`nspeed: " f.speed "`nscale: " f.scale
	if f.event="Finish"
	ToolTip
}

上传图片到 Photobucket

Code: Select all

; Both of these functions from "tmplinshi"
; requires registration
MsgBox % photobucket("Test.jpg", name, password)

photobucket(File, name, password){
	f	:={head:[]}
	f.agent		:= "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03S) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19"
	;f.proxy		:= "127.0.0.1:8118"

	if (d:=IniRead(A_ScriptDir "\Default.ini","photobucket","date")) and d>A_Now
	{
		f.head["Cookie"]:=IniRead(A_ScriptDir "\Default.ini","photobucket","Cookie")
		siteUrl:=IniRead(A_ScriptDir "\Default.ini","photobucket","siteUrl")
	}
	else
	{
		f.url	:= "https://secure.photobucket.com/action/auth/login"
		f.referer 	:= "https://secure.photobucket.com/login"
		f.post		:= "returnUrl=&username=" name "&password=" password "&remember=true"
		oh(f)
		if !siteUrl:=SubStr(f.list.Location, 1,InStr(f.list.Location, "/",,,3)-1)
			Return
		IniWrite(Cookie:=f.head["Cookie"]:=f.list["Set-Cookie"],A_ScriptDir "\Default.ini","photobucket","Cookie")
		IniWrite(Date_http(str_s(Cookie,"expires=Wed",";")),A_ScriptDir "\Default.ini","photobucket","date")
		IniWrite(siteUrl,A_ScriptDir "\Default.ini","photobucket","siteUrl")
	}

	if InStr(File,"//")
	{
		f.url	:= siteUrl "/action/upload/url"
		f.post	:= "mobile=true&url=" File "&location=Mobile Uploads&json=1&hash="
	}
	else
	{
		f.post	:= {json: "true", mobile: "true", location: "Mobile Uploads", file: [File] }
		f.url	:= siteUrl "/action/upload/file"
	}
	f.Referer := siteUrl "/upload"
 	data:=oh(f)

	if i:=InStr(data, "secureFullsize")
		Return StrReplace(SubStr(data, s:=i+17,InStr(data,"}",,i )-s-1),"\")
}

Date_Http(r){
	if instr(r,"-")
		r:=StrReplace(r,"-"," ") 
	Obj    := StrSplit(r, [A_Space, ":"] )
	Mon    := SubStr(  "0" Ceil( Instr("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", Obj.3) / 4 ), -2  )
	Return DateAdd(Obj.4 Mon Obj.2 Obj.5 Obj.6 Obj.7,8,"H")
}

Return to “脚本函数”

Who is online

Users browsing this forum: No registered users and 14 guests