HTTP(S) with WININET

Share your advanced PureBasic knowledge/code with the community.
roleg
User
User
Posts: 51
Joined: Wed Feb 24, 2010 2:07 pm

HTTP(S) with WININET

Post by roleg »

I coded simple procedure for self usage.
This can GET,POST with SecureLayer,Cookies,User-Agent,Referer,Proxy,Timeout and can disable autoredirect.

Code: Select all

Procedure.s do_request(host.s, page.s="", post_data.s="",  cookie.s="", is_secure.b=#False, user_agent.s="", referer.s="", proxy.s="", timeout.l=1000, redirect.b=#True)
  If Not proxy="" : access_type.i=3 : Else : access_type.i=1 : EndIf
  open_handle = InternetOpen_(user_agent,access_type,proxy,"",0)
  InternetSetOption_(open_handle, 2,timeout,4)
  If is_secure
    port.i=443
    flag.l=$00800000|$00001000|$00002000|$00080000|$00000100|$04000000
  Else
    port.i=80
    flag.l=$00080000|$00000100|$04000000
  EndIf
  If Not redirect : flag|$00200000 : EndIf
  If Not post_data="" : verb.s="POST" : Else : verb.s="GET" : EndIf
  If page="" : page="/" : EndIf
  If user_agent="" : user_agent="Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)" : EndIf
  connect_handle = InternetConnect_(open_handle,host,port,"","",3,0,0)
  request_handle = HttpOpenRequest_(connect_handle,verb,page,"",referer,0,flag,0)
  If verb="POST"
    headers.s = "Content-Type: application/x-www-form-urlencoded" +Chr(13)+Chr(10)
    HttpAddRequestHeaders_(request_handle,headers,Len(headers), $80000000|$20000000)
  EndIf
  If Not cookie=""
    headers.s = "Cookie: "+cookie+Chr(13)+Chr(10)
    HttpAddRequestHeaders_(request_handle,headers,Len(headers), $80000000|$20000000)
  EndIf
  send_handle = HttpSendRequest_(request_handle,"",0,post_data,Len(post_data))
  buffer.s = Space(1024)
  Repeat
    InternetReadFile_(request_handle,@buffer,1024,@bytes_read.l)
    result.s + Left(buffer,bytes_read)
    buffer = Space(1024)
  Until bytes_read=0
  InternetCloseHandle_(open_handle)
  InternetCloseHandle_(connect_handle)
  InternetCloseHandle_(request_handle)
  InternetCloseHandle_(send_handle)
  ProcedureReturn result
EndProcedure

Debug do_request("google.com");short call, only GET request for index file on http://google.com
Debug do_request("google.com","/xxx.php","her=vam","vam=her",#True,"Anonym browser 0.1","http://rambler.ru/ref.php","127.0.0.1:8888",2000,#False);full call,
;POST data with cookies,User-Agent:modiffed,referer,proxy,timeout,autoredirect:off to /xxx.php file on https://google.com
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: HTTP(S) with WININET

Post by jesperbrannmark »

Oh that is very nice! simple and nice.
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: HTTP(S) with WININET

Post by jesperbrannmark »

Spontanous look like it is allowing threading as well (compile threadsafe)

Code: Select all

Procedure.s do_request(thread.i,host.s, page.s="", post_data.s="",  cookie.s="", is_secure.b=#False, user_agent.s="", referer.s="", proxy.s="", timeout.l=1000, redirect.b=#True)
  Debug "THREAD STARTED:"+Str(thread)
  If Not proxy="" : access_type.i=3 : Else : access_type.i=1 : EndIf
  open_handle = InternetOpen_(user_agent,access_type,proxy,"",0)
  InternetSetOption_(open_handle, 2,timeout,4)
  If is_secure
    port.i=443
    flag.l=$00800000|$00001000|$00002000|$00080000|$00000100|$04000000
  Else
    port.i=80
    flag.l=$00080000|$00000100|$04000000
  EndIf
  If Not redirect : flag|$00200000 : EndIf
  If Not post_data="" : verb.s="POST" : Else : verb.s="GET" : EndIf
  If page="" : page="/" : EndIf
  If user_agent="" : user_agent="Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)" : EndIf
  connect_handle = InternetConnect_(open_handle,host,port,"","",3,0,0)
  request_handle = HttpOpenRequest_(connect_handle,verb,page,"",referer,0,flag,0)
  If verb="POST"
    headers.s = "Content-Type: application/x-www-form-urlencoded" +Chr(13)+Chr(10)
    HttpAddRequestHeaders_(request_handle,headers,Len(headers), $80000000|$20000000)
  EndIf
  If Not cookie=""
    headers.s = "Cookie: "+cookie+Chr(13)+Chr(10)
    HttpAddRequestHeaders_(request_handle,headers,Len(headers), $80000000|$20000000)
  EndIf
  send_handle = HttpSendRequest_(request_handle,"",0,post_data,Len(post_data))
  buffer.s = Space(1024)
  Repeat
    InternetReadFile_(request_handle,@buffer,1024,@bytes_read.l)
    result.s + Left(buffer,bytes_read)
    buffer = Space(1024)
  Until bytes_read=0
  InternetCloseHandle_(open_handle)
  InternetCloseHandle_(connect_handle)
  InternetCloseHandle_(request_handle)
  InternetCloseHandle_(send_handle)
  Debug "THREAD DONE "+Str(thread)
  ProcedureReturn result
EndProcedure
Procedure req(dummy.i)
  Debug do_request(dummy.i,"google.com","","","",#True);short call, only GET request for index file on http://google.comen
EndProcedure
OpenWindow(0,100,100,640,480,"")
Debug "START"
For i=1 To 50
  CreateThread(@req(),i)
Next
Debug "DONE"
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
;Debug do_request("google.com","/xxx.php","her=vam","vam=her",#True,"Anonym browser 0.1","http://rambler.ru/ref.php","127.0.0.1:8888",2000,#False);full call,
;POST data with cookies,User-Agent:modiffed,referer,proxy,timeout,autoredirect:off to /xxx.php file on https://google.com
roleg
User
User
Posts: 51
Joined: Wed Feb 24, 2010 2:07 pm

Re: HTTP(S) with WININET

Post by roleg »

jesperbrannmark, yes
I use it in my SQL vulnerability scanner, about 40 threads without any problem.
roleg
User
User
Posts: 51
Joined: Wed Feb 24, 2010 2:07 pm

Re: HTTP(S) with WININET

Post by roleg »

there is a some problem
randomly, after 4-7 hours of work in multithreaded mode
we get a memory error

Image

20 threads
safe threads: ON

tested:
XP, Core2Duo 3 Ghz, 2 Gb
XP, Core i7 3 Ghz, 4 Gb
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: HTTP(S) with WININET

Post by jesperbrannmark »

What PB version are you using? And do you notice anything on mem/cpu usage along the way?
roleg
User
User
Posts: 51
Joined: Wed Feb 24, 2010 2:07 pm

Re: HTTP(S) with WININET

Post by roleg »

PB 5.0
CPU: 10-25%
RAM: 100-200 Mb
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: HTTP(S) with WININET

Post by jesperbrannmark »

Is the ram constant or does it "grow by the hour"?
roleg
User
User
Posts: 51
Joined: Wed Feb 24, 2010 2:07 pm

Re: HTTP(S) with WININET

Post by roleg »

The number of sites checked grows, filling Map() + content sites temporarily loaded into RAM, and expands by about 100 Mb constantly

P.S. I add small timeout Delay(100) after CloseHandle and it was less falling out with an error.
it seems that the handles do not have time to close and to free :lol:

8 hours, normal flight...
infratec
Always Here
Always Here
Posts: 7576
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: HTTP(S) with WININET

Post by infratec »

Hi,

since I needed it:

I implemented that an invalid (homemade) certificate is tolerated.

Code: Select all

; http://support.microsoft.com/kb/q182888

EnableExplicit

#INTERNET_DEFAULT_HTTP_PORT = 80
#INTERNET_DEFAULT_HTTPS_PORT = 443

#INTERNET_OPEN_TYPE_DIRECT = 1
#INTERNET_OPEN_TYPE_PROXY = 3

#INTERNET_SERVICE_HTTP = 3

#INTERNET_FLAG_PRAGMA_NOCACHE =           $00000100
#INTERNET_FLAG_IGNORE_CERT_CN_INVALID =   $00001000
#INTERNET_FLAG_IGNORE_CERT_DATE_INVALID = $00002000
#INTERNET_FLAG_NO_COOKIES =               $00080000
#INTERNET_FLAG_NO_AUTO_REDIRECT =         $00200000
#INTERNET_FLAG_SECURE =                   $00800000
#INTERNET_FLAG_DONT_CACHE =               $04000000


#HTTP_ADDREQ_FLAG_ADD =     $20000000
#HTTP_ADDREQ_FLAG_REPLACE = $80000000


#ERROR_INTERNET_INVALID_CA = 12045

#INTERNET_OPTION_SECURITY_FLAGS = 31

#SECURITY_FLAG_IGNORE_UNKNOWN_CA = $00000100



Procedure.s do_request(host.s, page.s="", post_data.s="",  cookie.s="", is_secure.i=#False, user_agent.s="", referer.s="", proxy.s="", timeout.l=1000, redirect.i=#True)
  
  Protected.l flags, bytes_read, dwFlags, dwBuffLen
  Protected.i open_handle, port, connect_handle, request_handle, send_handle, Ok, access_type, LastError
  Protected.s verb, headers, buffer, result
  
  
  If proxy = "" : access_type =  #INTERNET_OPEN_TYPE_DIRECT : Else : access_type = #INTERNET_OPEN_TYPE_PROXY : EndIf
  If user_agent = "" : user_agent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)" : EndIf
  open_handle = InternetOpen_(user_agent, access_type, "", "", 0)
  
  InternetSetOption_(open_handle, 2, timeout, 4)
  
  flags = #INTERNET_FLAG_PRAGMA_NOCACHE
  flags | #INTERNET_FLAG_NO_COOKIES
  flags | #INTERNET_FLAG_DONT_CACHE
  
  If is_secure
    port = #INTERNET_DEFAULT_HTTPS_PORT
    
    flags | #INTERNET_FLAG_SECURE
    flags | #INTERNET_FLAG_IGNORE_CERT_CN_INVALID
    flags | #INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
  Else
    port = #INTERNET_DEFAULT_HTTP_PORT
  EndIf
  
  Debug host
  connect_handle = InternetConnect_(open_handle, host, port, "", "", #INTERNET_SERVICE_HTTP, 0, 0)
  ;Debug connect_handle
  
  
  If Not redirect : flags | #INTERNET_FLAG_NO_AUTO_REDIRECT : EndIf
  If post_data = "" : verb = "GET" : Else : verb = "POST" : EndIf
  Debug verb
  If page = "" : page = "/" : EndIf
  Debug page
  request_handle = HttpOpenRequest_(connect_handle, verb, page, "", referer, #Null, flags, 0)
  ;Debug request_handle
  
  If verb = "POST"
    ;headers = "Content-Type: application/x-www-form-urlencoded" + #CRLF$
    headers = "Content-Type: text/html" + #CRLF$
    HttpAddRequestHeaders_(request_handle, headers, Len(headers), #HTTP_ADDREQ_FLAG_ADD | #HTTP_ADDREQ_FLAG_REPLACE)
  EndIf
  If cookie <> ""
    headers = "Cookie: "+ cookie + #CRLF$
    HttpAddRequestHeaders_(request_handle, headers, Len(headers), #HTTP_ADDREQ_FLAG_ADD | #HTTP_ADDREQ_FLAG_REPLACE)
  EndIf
  
  
  Ok = 0
  Repeat
    send_handle = HttpSendRequest_(request_handle, #Null, 0, post_data, Len(post_data))
    
    If send_handle = 0
      LastError = GetLastError_()
      
      Debug "Error " + Str(LastError)
      
      If LastError = #ERROR_INTERNET_INVALID_CA
        
        dwBuffLen = SizeOf(dwFlags)
        
        InternetQueryOption_(request_handle, #INTERNET_OPTION_SECURITY_FLAGS, @dwFlags, @dwBuffLen)
        
        dwFlags | #SECURITY_FLAG_IGNORE_UNKNOWN_CA
        InternetSetOption_(request_handle, #INTERNET_OPTION_SECURITY_FLAGS, @dwFlags, SizeOf(dwFlags))
        Ok + 1
      Else
        Ok = 2
      EndIf
    Else
      Ok = 2
    EndIf
  Until Ok = 2
  
  
  buffer = Space(1024)
  Repeat
    InternetReadFile_(request_handle, @buffer, 1024, @bytes_read)
    result + Left(buffer, bytes_read)
    buffer = Space(1024)
  Until bytes_read = 0
  
  InternetCloseHandle_(open_handle)
  InternetCloseHandle_(connect_handle)
  InternetCloseHandle_(request_handle)
  InternetCloseHandle_(send_handle)
  
  ProcedureReturn result
  
EndProcedure
Bernd
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: HTTP(S) with WININET

Post by ricardo »

This fails for me as soon as i add the proxy, why? The proxy works fine (tested with ScrapeBox)

Code: Select all

Debug do_request("google.com","","","",#True,"","","182.253.48.166:80",2000)
ARGENTINA WORLD CHAMPION
User avatar
ostapas
Enthusiast
Enthusiast
Posts: 192
Joined: Thu Feb 18, 2010 11:10 pm

Re: HTTP(S) with WININET

Post by ostapas »

I've slightly modified this procedure for my needs(return cookies, download/upload file, etc.) http://pastebin.com/sh6qZq8m Didn't investigate where the problem is, but it seems to work with the version I posted, e.g.

Code: Select all

Debug HttpRequest("https://google.com", 1, "", "", "", "", "", "195.171.194.91:80")
However, TimeOut parameter does not work when using a proxy(seems to be a MS bug)
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: HTTP(S) with WININET

Post by ricardo »

ostapas wrote:I've slightly modified this procedure for my needs(return cookies, download/upload file, etc.) http://pastebin.com/sh6qZq8m Didn't investigate where the problem is, but it seems to work with the version I posted, e.g.

Code: Select all

Debug HttpRequest("https://google.com", 1, "", "", "", "", "", "195.171.194.91:80")
However, TimeOut parameter does not work when using a proxy(seems to be a MS bug)

Works in Google, but not with all sites, why? I will test more.
This slightly modification is great indeed.
ARGENTINA WORLD CHAMPION
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: HTTP(S) with WININET

Post by coco2 »

What sort of encoding does it return the data in?
Post Reply