Ich Bitte die Syntax zu Entschuldigen ! Dieser WinAPI HTTP Connection mit Timeout, Code Snippet ist eigentlich
Er ist unübersichtlich und lang (funktioniert aber hervoranged) und sieht schrecklich verschachtelt und kompliziert aus, aber er ist so geschrieben, daß kein Proxy der Welt es schafft den Code hängen zu lassen so das kein Timeout ausgelöst wird (Idle Proxys versuchen das ! Ich hasse die dinger) und da kann der blöde Kasten sich noch so sehr anstrengen !
Der Code kennt 2 Arten von Timeout, Connection & Replie Timeout, ich hab mir den vor 6-7 Jahren (als PB noch kein Timeout drauf hatte) mühevoll das erste mal zusammen gefrickelt, und über die Jahre nur für mich optimiert (soweit ich den Code verstanden hab...blöde winapi und sockets, so kompliziert der Käse)
Desshalb auch kein Declare und nur die allernötigste Kommentierung im Code, ah und unter jaPBe geschrieben, desshalb
auch [ statt diese hässlichen C artigen Affen Klammern -> { die ich auf den Tot nicht austehen kann !
Code: Alles auswählen
Global gracefull, abort_download
Global own$=GetCurrentDirectory()
#SuccessSound=0
InitNetwork()
If InitSound()
LoadSound(#SuccessSound,"c:\WINDOWS\Media\notify.wav")
EndIf
CreateRegularExpression(0,"[0-9]")
;[/ Winsock Konstanten
Global sof10038$
Global sof10052$
Global sof10053$
Global sof10054$
Global sof10060$
Global sof10061$
Debug #WSAEWOULDBLOCK
Debug"WENN 10035 DANN IST ALLES OK -> Empfangs Schleife läuft noch"
Debug ""
Debug #WSAENOTSOCK
sof10038$="Error: Socket Operation on Non-Socket -> Error Code #10035"
Debug sof10038$
Debug ""
Debug #WSAENETRESET
sof10052$="Network Dropped Connection on Reset -> Error Code #10052"
Debug sof10052$
Debug ""
Debug #WSAECONNABORTED
sof10053$="Software Caused Connection Abort -> Error Code #10053"
Debug sof10053$
Debug ""
Debug #WSAECONNRESET
sof10054$="Connection Reset by Peer -> Error Code #10054"
Debug sof10054$
Debug ""
Debug #WSAENOTCONN
sof10057$="Socket is not connected -> Error Code #10057"
Debug #WSAETIMEDOUT
sof10060$="Connection Timed Out -> Error Code #10060"
Debug sof10060$
Debug ""
Debug #WSAECONNREFUSED
sof10061$="Connection Refused -> Error Code #10061"
Debug sof10061$
Debug ""
;]
Procedure SuccessWatch(egal)
Repeat
Delay(5)
If gracefull
If IsSound(#SuccessSound)
PlaySound(#SuccessSound)
Delay(3000)
gracefull=0
Break
EndIf
EndIf
ForEver
EndProcedure
Procedure.i OpenNetworkConnectionEx(ConNameOrIP.S,ConPort,TimeOut.i,ReplieTimeout.i,use_proxy,Domain,CompletteURL.S,Referer$)
Type.i = #PB_Network_TCP
Auth_User$=GetURLPart(CompletteURL.S, #PB_URL_User)
Auth_Pass$=GetURLPart(CompletteURL.S, #PB_URL_Password)
If Auth_User$ And Auth_Pass$
Combo.S = Auth_User$+":"+Auth_Pass$
OutputAuth$ = Space(256)
Base64Encoder(@Combo.S,Len(Combo.S), @OutputAuth$, 255)
U_P$ = "Authorization: Basic "+OutputAuth$+#CRLF$
EndIf
Parameters$=GetURLPart(CompletteURL.S, #PB_URL_Parameters)
Param_CHK=CountString(CompletteURL.S,"?")
If Param_CHK
Parameters$="?"+Parameters$
EndIf
Header_Site$=GetURLPart(CompletteURL.S, #PB_URL_Site)
Header_Port$=GetURLPart(CompletteURL.S, #PB_URL_Port)
Header_Path$=GetURLPart(CompletteURL.S, #PB_URL_Path)
If use_proxy And Domain = 1
ConNameOrIP.S = StringField(GetGadgetText(6),1,":")
ConPort = Val(StringField(GetGadgetText(6),2,":"))
Debug "PX=TRUE | DOMAIN = TRUE"
bla1$="GET "+CompletteURL.S+" HTTP/1.1"+#CRLF$ ;/ GEHT AUCH MIT NUR PATH+PARAM, ABER VIELE PX GEHEN SO BESSER !
bla2$="Host: "+Header_Site$+#CRLF$
ElseIf use_proxy And Domain = 0
Debug "PX=TRUE | Domain = FALSE"
ConNameOrIP.S = StringField(GetGadgetText(6),1,":")
ConPort = Val(StringField(GetGadgetText(6),2,":"))
bla1$="GET /"+CompletteURL.S+" HTTP/1.1"+#CRLF$ ;/ GEHT AUCH MIT NUR PATH+PARAM, ABER VIELE PX GEHEN SO BESSER !
bla2$="Host: "+Header_Site$+":"+Header_Port$+#CRLF$
ElseIf use_proxy = 0 And Domain = 1
Debug "PX=FALSE | DOMAIN = TRUE"
bla1$="GET /"+Header_Path$+Parameters$+" HTTP/1.1"+#CRLF$
bla2$="Host: "+Header_Site$+#CRLF$
ConPort = 80
ElseIf use_proxy = 0 And Domain = 0
Debug "PX=FALSE | DOMAIN = FALSE"
bla1$="GET /"+Header_Path$+Parameters$+" HTTP/1.1"+#CRLF$
bla2$="Host: "+Header_Site$+":"+Header_Port$+#CRLF$
EndIf
Debug "------------1--------------"
Debug "ConNameOrIP.s="+ConNameOrIP.S
Debug "ConPort="+Str(ConPort)
Debug "---------------------------"
DisableGadget(1,1)
buffer_l.i = 65536 : *buffer_p = AllocateMemory(buffer_l)
*wri=AllocateMemory(buffer_l)
;[/ Create Socket
Protected WSAD.WSADATA, TV.TIMEVAL, Addr.SOCKADDR_IN, *HostInfo.HOSTENT, Write_FD.FD_SET
Protected S.i, Switch.i, retval.i, ConIP.S
TV\tv_sec = TimeOut : Switch = #True
If WSAStartup_($101,@WSAD)
ProcedureReturn #False
EndIf
*HostInfo = gethostbyname_(@ConNameOrIP)
If *HostInfo
ConIP.S = StrU(PeekB(PeekL(*HostInfo\h_addr_list)),#PB_Byte) + "."
ConIP.S + StrU(PeekB(PeekL(*HostInfo\h_addr_list) + 1),#PB_Byte) + "."
ConIP.S + StrU(PeekB(PeekL(*HostInfo\h_addr_list) + 2),#PB_Byte) + "."
ConIP.S + StrU(PeekB(PeekL(*HostInfo\h_addr_list) + 3),#PB_Byte)
;/ 0 vor PB 5.11 #PB_Byte ab PB 5.11
EndIf
S = SOCKET_(#AF_INET,#SOCK_STREAM,#IPPROTO_TCP)
Error.i = WSAGetLastError_()
If Error.i : Debug "---1---" : Debug Error.i : EndIf
If S = #SOCKET_ERROR : WSACleanup_() : ProcedureReturn #False : EndIf
ioctlsocket_(S,#FIONBIO,@Switch)
Error.i = WSAGetLastError_()
If Error.i : Debug "---2---" : Debug Error.i : EndIf
With Addr
\sin_addr = inet_addr_(ConIP.S)
\sin_port = htons_(ConPort)
\sin_family = #AF_INET
EndWith
With Write_FD
\fd_count = 1
\fd_array[0] = S
EndWith
;]
;[/ HTTP HEADER
bla3$="Pragma: no-cache"+#CRLF$
bla4$="User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de-AT; rv:1.7.13) Gecko/20070216"+#CRLF$
bla5$="Accept-Language: en-us,en;q=0.7,de-de;q=0.3"+#CRLF$
bla6$="Accept: text/html,image/jpeg,image/gif,text/xml,text/plain,image/png,*/*;q=0.5"+#CRLF$
bla7$="Accept-Charset: utf-8,*;q=0.7"+#CRLF$
Bla8$="Referer: "+Referer$+#CRLF$
Bla9$="Connection: close"+#CRLF$
Bla10$=#CRLF$
;]
;Debug bla1$
;Debug bla2$
;[/ Send and Receive
If Len(U_P$) > 2
Debug U_P$
message.S=bla1$+bla2$+bla3$+bla4$+bla5$+bla6$+bla7$+Bla8$+Bla9$+U_P$+Bla10$
Else
message.S=bla1$+bla2$+bla3$+bla4$+bla5$+bla6$+bla7$+Bla8$+Bla9$+Bla10$
EndIf
Debug message.S
send_len=Len(message.S)
kill_time = ElapsedMilliseconds()
kill_time = kill_time+ReplieTimeout
input_end_size=0
connect_(S,@Addr,SizeOf(Addr))
Error.i = WSAGetLastError_()
If Error.i <> 10035
Debug Error.i
EndIf
Debug "XXXXX="+message.S
Debug "----"
Repeat
retval = select_(0,0,@Write_FD,@Write_FD,@TV)
Error.i = WSAGetLastError_()
If Error.i : Debug Error.i : EndIf
If retval
send.i = send_(S,@message,send_len,0)
If send.i > 0
AddGadgetItem(2,-1,"-> Receive")
Repeat
run_time = ElapsedMilliseconds() : Delay(1)
received.i=recv_(S,*buffer_p,buffer_l,0)
Error.i = WSAGetLastError_()
If Error.i <> 10035 And Error > 0
Debug Error
EndIf
If received.i > 0
;/ SEHR WICHTIG -> WriteData(DATEI,*buffer_p,buffer_l) benutzen statt WriteString sonst
;/ ungenaue Replies !
kill_time = kill_time+ReplieTimeout
input_end_size=received.i
*buffer_p = ReAllocateMemory(*buffer_p,received.i)
If HeaderFound=0
jumbo$=(PeekS(*buffer_p,buffer_l))
header_end=FindString(jumbo$,#CRLF$+#CRLF$,1)
If header_end
jumbo$=ReplaceString(jumbo$,#CRLF$,"|") : jumbo$=Left(jumbo$,header_end-9)
AddGadgetItem(2,-1,"One Line Header with Replaced Line Break Char =>"+jumbo$)
AddGadgetItem(2,-1,"----------------------------------------------")
EndIf
;[/ Create TMP File -> CUT HEADER -> Rewrite Data to Destination File
CreateFile(1,"C:\NEW.exe.tmp") : WriteData(1,*buffer_p,received.i) : FileSeek(1,header_end+3)
*fmem=AllocateMemory(40000)
If CreateFile(2,"C:\NEW.exe")
FileBuffersSize(2,1160)
While Eof(1)=0
Result=ReadData(1,*fmem,40000) : WriteData(2,*fmem,Result)
Wend
EndIf
CloseFile(1) : DeleteFile("C:\NEW.exe.tmp")
;]
HeaderFound=1
Else
WriteData(2,*buffer_p,received.i)
EndIf
;out=1
ElseIf received.i = 0
Debug "DISCONNECT"
If input_end_size=0
AddGadgetItem(2,-1,"SHIT PROXY SEND 0 BYTE DATA")
Else
Debug "GRACEFULL DISCONNECT" : gracefull=1
EndIf
out=1
ElseIf run_time >= kill_time
AddGadgetItem(2,-1,"FORCE:"+sof10061$) : out=1
ElseIf received <= 0
;Debug "------------"
If Error=#WSAEWOULDBLOCK
; when non-blocking: no more data to read
Else
; otherwise a real problem
Debug ("Error "+Str(Error))
;[/ Winsock Error Auswertung
If Error.i = 10052
AddGadgetItem(2,-1,sof10052$)
ElseIf Error.i = 10053
AddGadgetItem(2,-1,sof10053$)
ElseIf Error.i = 10054
AddGadgetItem(2,-1,sof10054$)
ElseIf Error.i = 10057
AddGadgetItem(2,-1,sof10057$)
ElseIf Error.i = 10060
AddGadgetItem(2,-1,sof10060$)
ElseIf Error.i = 10061
AddGadgetItem(2,-1,sof10061$)
Else
undef_sock_msg$=Str(Error.i)
AddGadgetItem(2,-1,"Undef:"+undef_sock_msg$)
EndIf
;]
out=1
EndIf
EndIf
*buffer_p = ReAllocateMemory(*buffer_p,buffer_l)
Until out=1 Or abort_download = 1
Else
Error.i = WSAGetLastError_()
error_code$=Str(Error.i)
If Error.i = 10057
AddGadgetItem(2,-1,"Sending Fail: Error Code #10057 - Socket is not connected")
Else
AddGadgetItem(2,-1,"Sending Fail: Error Code #"+error_code$)
EndIf
out=1
EndIf
Else
AddGadgetItem(2,-1,"TIMEOUT")
EndIf
Until retval >= 0 Or out = 1
FreeMemory(*buffer_p)
Debug "-----------------------------"
closesocket_(S) : WSACleanup_() : out=0
;]
If IsFile(2)
CloseFile(2) ; Close Destination File
EndIf
DisableGadget(1,0)
EndProcedure
Procedure.l IpOrDomainCheck(in.S)
tmp_str1$ = GetURLPart(in.S,#PB_URL_Site)
If tmp_str1$
For tmp_p = 1 To Len(tmp_str1$)
tmp_str2$ = Mid(tmp_str1$,tmp_p,1)
If MatchRegularExpression(0,tmp_str2$) = 0
If FindString(tmp_str2$,".") = 0
tmp_domain = 1 : Debug "DOMAIN TRUE" : Break
EndIf
EndIf
Next
EndIf
ProcedureReturn tmp_domain
EndProcedure
Procedure connector (blablablabla)
Referer$=GetGadgetText(4)
url$=GetGadgetText(3) : url$=RemoveString(url$,"http://") : url$="http://"+url$
Domain = IpOrDomainCheck(url$) ; 1 1=Domain
TimeOut=Val(GetGadgetText(7)) : use_proxy = GetGadgetState(5)
ConHost$=GetURLPart(url$,#PB_URL_Site) : ConPort=Val(GetURLPart(url$,#PB_URL_Port))
AddGadgetItem(2,-1,"")
id.i = OpenNetworkConnectionEx(ConHost$,ConPort,TimeOut,5000,use_proxy,Domain,url$,Referer$)
EndProcedure
#blub=#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered
If OpenWindow(0,0,0,600,500,"Timeout Full Winapi Test",#blub)
CreateGadgetList(WindowID(0))
ButtonGadget(1,200,350,100,20,"Start")
EditorGadget(2,10,10,500,280)
#default_url="http://mirrors.ircam.fr/pub/videolan/vlc/1.0.3/win32/vlc-1.0.3-win32.exe"
StringGadget(3,10,400,480,20,#default_url)
StringGadget(4,10,430,480,20,"http://www.google.com/");Referer
CheckBoxGadget(5,200,320,100,20,"Use Proxy") : SetGadgetState(5,0)
StringGadget(6,10,300,480,20,"110.76.38.173:6666");PROXY
StringGadget(7,10,320,20,20,"5",#PB_String_Numeric);Server/Proxy CONNECTION Timeout
ButtonGadget(8,340,350,100,20,"Stop")
Repeat
WaitWindowEvent = WaitWindowEvent()
EventGadget = EventGadget()
If WaitWindowEvent = #PB_Event_Gadget
If EventGadget = 1
gracefull = 0 : abort_download = 0
SoundTH=CreateThread(@SuccessWatch(),0)
hans=CreateThread(@connector(),1)
EndIf
If EventGadget = 8
If IsThread(hans)
abort_download = 1
Debug "dsdasdsaldkölk"
EndIf
EndIf
EndIf
Until WaitWindowEvent = #PB_Event_CloseWindow
EndIf
; jaPBe Version=3.13.4.880
; FoldLines=000F003C003E004A00FB0105011C012D01500160
; Build=0
; Language=0x0000 Language Neutral
; FirstLine=108
; CursorPosition=190
; EnableThread
; EnableXP
; ExecutableFormat=Windows
; CPU=1
; DontSaveDeclare
; EOF