Page 1 sur 1

ReceiveHTTPFile & Proxy

Publié : mar. 03/août/2010 16:04
par DarkIchigo
Salut à tous,

j'ai un soucis avec la fonction ReceiveHTTPFile() au taf, je suis comme beaucoup bloqué par un proxy
or la fonction n'étant pas compatible avec les proxy, je suis bloqué.

D'où ma question : Comment contourner le problème?

J'ai recherché mais je n'ai rien trouvé à ma porté de compréhension.
http://www.purebasic.fr/french/viewtopic.php?f=6&t=6535
par exemple mais j'avoue que je suis encore un débutant et la moi pas comprendre.

Le but est de pouvoir récupérer une photo tout en étant "bloqué" par le proxy.
Le site qui héberge la photo n'est pas bloqué par le proxy quand à lui, ni le reste du contenu dudit site.

Si quelqu'un peut m'aider, je suis preneur :D

Merci d'avance

Re: ReceiveHTTPFile & Proxy

Publié : mar. 03/août/2010 21:18
par Le Soldat Inconnu
Alors voici l'usine à gaz, tu copie ceci dans ton code, c'est la boite noire

Code : Tout sélectionner

; PureHTTP Include - Version: 0.45b
; OS: Linux / Windows / AmigaOS / MacOSX
; Author: Marius Eckardt (Thalius)
; a lil lib for HTTP ( for now just Downloading ;)
; Last Changes: 24.12.2008
;
; PureHTTP is aimed to be a HTTP 1.0-Compatible Crossplatform Library for use in your Projects.
; This code is PublicDomain - Credits apprechiated if you use it tho ;)
;
; Thx go to mp303 who brought me on the Idea initially with some Networkquestions in the Bugsection. :)
;
; Note: This Code is supposed to be fast but not super optimized. Basically ok for the Job - if you do optimizations
; / improvements you feel the Community could benefit from feel free to post them. :)
;
; Features:
; - HTTP Download to File with :
; - HTTP HEADER Info
; - HTTP Error Handling
; - HTTP Redirect support ( should work now! )
; - Connection Timeout Handling
; - Callback Support
; - Download Timer
; - KB/s o Meter
; - Limit Download Speed
;
; Changes:
; 0.2b:
; - Added Callback Function Support
; 0.3b:
; - lil Optimization
; 0.4b:
; - more Optimizations
; - Fixed Speedlimit To a per Kb/s Value
; - Added PureHTTP_SplitURL(url.s, type.i) - Splits an URL to Host/Path/Filename
; - Extended Example a little
; 0.41 - 0.45b:
; - small Optimizations
; - Added Redirect Support
; - Download to Memory ( Weee ! ;)
; - Added fixes by "moogle"
; - Added fix by oryaaaaa
; - Modified for PB 4.30 / 64 Bit compatibility ( if you need it for an older version simply replace all .i with .l ;))
;
; Changes by Kelebrindae:
; - Added Http proxy support (code based on Num3's http-proxy-snippet)
; - Added Http authorization support


; ************************************************************
;- Constants
; ************************************************************
; Network
#PureHTTP_Name                  = "PureHTTP" ; UserAgent Name
#PureHTTP_Defaultfile           = "index.html" ; Default for index Files ( used to parse URLs )
#PureHTTP_Buffersize            = 4096   ; Chunk-/Buffersize (This Value is balanced ok for average usage. There might be a speedgain on large files increasing this, but slowdown for smaller files)
#PureHTTP_Timeout               = 10000  ; Network Timeout in ms

; Status
Enumeration
  #PureHTTP_STATUS_CONNECTING   ; Connecting
  #PureHTTP_STATUS_CONNECTED    ; Connected
  #PureHTTP_STATUS_GOTHEADER    ; Got Header info Filesize / Content-Type
  #PureHTTP_STATUS_RECEIVE      ; Receiving...
  #PureHTTP_STATUS_REDIRECT     ; HTTP Redirect
  #PureHTTP_STATUS_IDLE         ; Idle, Waiting for Data...
  #PureHTTP_STATUS_FINISHED     ; Download Finished
  #PureHTTP_STATUS_TIMEOUT      ; Timeout
  #PureHTTP_STATUS_HTTPERROR    ; HTTP Error / Return
  #PureHTTP_STATUS_FILEERROR    ; Can't create file
  #PureHTTP_STATUS_ABORT        ; Download Aborted
EndEnumeration

; HTTP URL Related
#PureHTTP_URL_Protocol = "http://"

; URL Return-Selection Konstants
Enumeration
  #PureHTTP_URL_TO_HOST    ; Host
  #PureHTTP_URL_TO_PATH    ; Path
  #PureHTTP_URL_TO_FILE    ; Filename
EndEnumeration

; HTTP Protocol Related
#HTTP_Port             = 80
#HTTP_Protocol10       = "HTTP/1.0"
#HTTP_Protocol11       = "HTTP/1.1"
#HTTP_ContentLength    = "Content-Length:"
#HTTP_ContentType      = "Content-Type:"

; HTTP Retruncodes
#HTTP_CODE_OK          = 200 ; OK
#HTTP_CODE_REDIRECT    = 301 ; Redirect
#HTTP_CODE_TREDIRECT   = 307 ; Transparent Redirect


; ************************************************************
;- Structures
; ************************************************************

; HTTP Header Struct
Structure _PureHTTP_HEADER
  Returncode.i          ; HTTP Return Code -> 200 = OK -> 404 = File Not Found
  ContentLength.i       ; Reported Content-Size
  ContentType.s         ; Reported Content-Type
  HTTPReturnString.s    ; HTTP Retrunstring -> "HTTP ERROR 404 Not Found"
EndStructure

; File Struct
Structure _PureHTTP_GET_FILE
  ; File
  id.i                  ; FileIDThread ( in case we download multiple files at once )
  *Callback             ; Callback Function
  ConID.i               ; ConnectionID  
  Host.s                ; Host to Connect to
  Path.s                ; Path to File on Host
  outputfile.s          ; Path to local Filetarget
  *DestBuffer           ; Pointer to Destination Memory Buffer ( Alternative to File Download )
  Status.i              ; Download Status
  
  ; File authorization
  userID.s              ; User name (optionnal)
  userPass.s            ; User password (optionnal)
  
  ; Proxy Data
  proxyHost.s           ; Proxy location (URL or IP) (optionnal)
  proxyPort.i           ; Proxy port (optionnal)
  proxyID.s             ; User name on proxy  (optionnal)
  proxyPass.s           ; User password on proxy  (optionnal)
  
  ; HTTP Header Meta Info
  Header._PureHTTP_HEADER
  
  ; Network
  *Buffer               ; Pointer to our Paketbuffer
  Totalbytes.i          ; Holds actual Total bytes received from this File
  StartTimer.i          ; Start Timer in ms
  Timer.i               ; Current Our Timer in ms
  Totaltime.i           ; Total DownloadTime
  limitspeed.i          ; Limit Downloadspeed in Kb/s
  kbps.f                ; KB/s
EndStructure


; ************************************************************
;- Procedures
; ************************************************************

EnableExplicit

; Builds GET HTTP Header
; Returns HTTP HeaderString
Procedure.s PureHTTP_BUILDHEADER_HTTP_GET(*this._PureHTTP_GET_FILE)
  Protected *authBuffer
  Protected userInfo.s,userInfoEncoded.s,authString.s,length.i
  Protected extras.s
	
  If Len(*this\Path) <= 1
    *this\Path = "/"
	EndIf
	
  ; If you need authorization to get the file, add it to the request
  If *this\userID <> "" And *this\userPass <> ""
		
    *authBuffer = AllocateMemory(1024)
    If *authBuffer = 0
      ProcedureReturn ""
		EndIf        
    userInfo = *this\userID + ":" + *this\userPass
    length = Len(userInfo) * 2
    If length < 64
      length = 64
		EndIf
    Base64Encoder(@userInfo, Len(userInfo), *authBuffer, length)
    userInfoEncoded = PeekS(*authBuffer)
    FreeMemory(*authBuffer)
		
    authString + "Authorization: Basic " + userInfoEncoded + #CRLF$
	EndIf
	
  ; Add more Checks & stuff here...
  extras.s = #CRLF$ + "User-Agent: " + #PureHTTP_Name
	
  ProcedureReturn "GET " + *this\Path + " " + #HTTP_Protocol10 + #CRLF$ + "host: "+ *this\Host + #CRLF$ + authString +"Connection: Close" + extras.s + #CRLF$ + #CRLF$
EndProcedure


; Set Download Status
; Can be used to send an event to thread
; for ex: PureHTTP_SET_STATUS(@mydownload, #PureHTTP_STATUS_ABORT )
; Aborts download.
Procedure PureHTTP_SET_STATUS(*this._PureHTTP_GET_FILE, Status.i)
  ; Set Status
  *this\Status = Status
	
  ; Call Callback
  If *this\Callback <> 0
    CallFunctionFast(*this\Callback,*this)
	EndIf
EndProcedure


; Func: PureHTTP_SplitURL(url.s, [ #Pure_HTTP_URL_* ])
; Desc: Little Helper Function to Extract Host/Path/Filename out of an URL
; Returns:  String: Hostname, Path, Filename
; See Types:
;  #PureHTTP_URL_HOST    ; Host
;  #PureHTTP_URL_PATH    ; Path
;  #PureHTTP_URL_FILE    ; Filename
;
; Example: Debug PureHTTP_SplitURL("http://www.wavemage.com/edscore/5-EndTitle.mp3",#PureHTTP_URL_FILE)
; See example below for more...
Procedure.s PureHTTP_SplitURL(URL.s, type.i = #PureHTTP_URL_TO_HOST)
  Protected num_slash.i
  Protected result.s = ""
	
  ; Do we have a http:// ?
  If FindString(URL,#PureHTTP_URL_Protocol,0) > 0 
    URL = Right(URL,Len(URL) - Len(#PureHTTP_URL_Protocol))
    If type >= #PureHTTP_URL_TO_HOST And type.i <= #PureHTTP_URL_TO_FILE
      ; Host   
      result = StringField(URL.s,0,"/")
			
      If type = #PureHTTP_URL_TO_FILE
        ; Filename
        ; Find File
        num_slash=CountString(URL, "/")
        result=StringField(URL, num_slash+1, "/")
        ; Sure we got a File ?
        If FindString(result,".",0) = 0 Or result = StringField(URL,0,"/")
          ; No ? Assuming its an index HTML
          result = #PureHTTP_Defaultfile
				EndIf
			EndIf
			
      ; Path   
      If type = #PureHTTP_URL_TO_PATH
        result = Right(URL,Len(URL)-Len(result))
			EndIf
			
		EndIf
	EndIf
	
  ProcedureReturn result
EndProcedure


; Func: PureHTTP_Get_File(@myfile)
; Returns: Statuscode See: #PureHTTP_STATUS_*
; Desc: Downloads File
Procedure PureHTTP_Get_File(*this._PureHTTP_GET_FILE, timeOut.i = 10000)
  Protected offset.i, eoffset.i, cloffset.i, ctoffset.i, solocoffset.i, eolocoffset.i, Bytes.i, PaketCounter.i, *SEvent, *outfile
  Protected m_mul.i, redirection.i = 0, dest_buffersize.i, tmp_redir_url.s
  Protected userInfo.s,userInfoEncoded.s,authString.s,length.i,rData.s,result.i,i.i
  Protected *authBuffer
	
  ; Set Status
  PureHTTP_SET_STATUS(*this, #PureHTTP_STATUS_CONNECTING)
	
  ; If we don't use a proxy
  If *this\proxyHost = "" And *this\proxyPort = 0
    *this\ConID = OpenNetworkConnection( *this\Host , #HTTP_Port )
	Else
    ;====================
    ; HTTP - Proxy
    ;====================
    ;Based on Num3's http-proxy-snippet , THX! ->
    ;http://jconserv.net/purebasic/viewtopic.php?t=10327
    *this\ConID = OpenNetworkConnection(*this\proxyHost, *this\proxyPort)
    If *this\ConID = 0
      PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_HTTPERROR) 
      ProcedureReturn #False
		EndIf     
    
    authString = "CONNECT " + *this\Host + ":" + Str(#HTTP_Port) + " " + #HTTP_Protocol10 + #CRLF$
		
    If *this\proxyID <> "" And *this\proxyPass <> ""
			
      *authBuffer = AllocateMemory(1024)
      If *authBuffer = 0
        ProcedureReturn #False
			EndIf        
      userInfo = *this\proxyID + ":" + *this\proxyPass
      length = Len(userInfo) * 2
      If length < 64
        length = 64
			EndIf
      Base64Encoder(@userInfo, Len(userInfo), *authBuffer, length)
      userInfoEncoded = PeekS(*authBuffer)
      FreeMemory(*authBuffer)
			
      authString + "Authorization: Basic " + userInfoEncoded + #CRLF$
      authString + "Proxy-Authorization: Basic " + userInfoEncoded + #CRLF$
		EndIf
    authString + #CRLF$
		
    ; Send connection request to proxy
    SendNetworkData(*this\ConID, @authString, Len(authString))
    *this\StartTimer = ElapsedMilliseconds()
    Repeat
      Delay(10)
      If NetworkClientEvent(*this\ConID) = 2
        rData = Space(14500)
        length = ReceiveNetworkData(*this\ConID, @rData, 14500)
        While length = 14500
          ;Clear Input-Buffer
          length = ReceiveNetworkData(*this\ConID, *authBuffer, 14500)
				Wend
        Break
			EndIf
		Until ElapsedMilliseconds() - *this\StartTimer > timeOut
    result = 0
    For i = 1 To CountString(rData, Chr(10))
      If Left(Trim(StringField(rData, i, Chr(10))), 7) = "HTTP/1."
        result = Val(StringField(rData, 2, Chr(32)))
        Break
			EndIf
		Next i
    
    ; Error: connection impossible or timeout
    If ElapsedMilliseconds() - *this\StartTimer > timeOut Or result <> 200
      CloseNetworkConnection(*this\ConID)
      PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_HTTPERROR)        
      ProcedureReturn #False
		EndIf
		
	EndIf
	
  ; If we managed to connect the host
  If *this\ConID <> 0
		
    ; Set Status
    PureHTTP_SET_STATUS(*this, #PureHTTP_STATUS_CONNECTED)
    Debug "* Connected"
    ; Allocate Receivebuffer
    *this\Buffer = AllocateMemory(#PureHTTP_Buffersize)
    ; Init Timer
    *this\StartTimer = ElapsedMilliseconds()
    *this\Timer      = *this\StartTimer
    ; Send HTTP Request
    authString = PureHTTP_BUILDHEADER_HTTP_GET(*this)
    Debug authString
    SendNetworkString(*this\ConID,authString)
    Debug "* Sending Request"
    ; Wait for incoming Data ...
    Debug "* Waiting for Reply"
    Repeat
      *SEvent = NetworkClientEvent(*this\ConID)
			
      Select *SEvent
					; We received Data!
				Case #PB_NetworkEvent_Data
          Debug "* Receiving..."
          ; Now go Fetch!
          Repeat
            Bytes = ReceiveNetworkData(*this\ConID, *this\Buffer, #PureHTTP_Buffersize)
            ; Is this the first Paket containing the Header ?
            If PaketCounter = 0
              ; PrintN(PeekS(*this\Buffer,#PureHTTP_Buffersize)) ;<- lil Debug For the header
              ; Basic Process Header - Get DataOffsets
              eoffset  = FindString(PeekS(*this\Buffer, 200), #HTTP_Protocol10, 0) + Len(#HTTP_Protocol10)
              If eoffset = Len(#HTTP_Protocol10) ; We got a HTTP1.1 response, find new offset.
                eoffset  = FindString(PeekS(*this\Buffer, 200), #HTTP_Protocol11, 0) + Len(#HTTP_Protocol11)
							EndIf
              ; We sure in for a right Response now ?
              If eoffset = Len(#HTTP_Protocol10) ; no .. still no offset
                PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_HTTPERROR)
							Else ; Yeah baby!
                cloffset = FindString(PeekS(*this\Buffer, #PureHTTP_Buffersize), #HTTP_ContentLength, eoffset) + Len(#HTTP_ContentLength)
                ctoffset = FindString(PeekS(*this\Buffer, #PureHTTP_Buffersize), #HTTP_ContentType, eoffset) + Len(#HTTP_ContentType)
                offset   = FindString(PeekS(*this\Buffer, #PureHTTP_Buffersize),#CRLF$ + #CRLF$,eoffset) + 3
                ; Do we have a Content-Length Info? if so, set Size
                If cloffset <> Len(#HTTP_ContentLength)
                  *this\Header\ContentLength = Val(LTrim(RTrim(PeekS(*this\Buffer+cloffset,FindString(PeekS(*this\Buffer+cloffset,#PureHTTP_Buffersize-cloffset),#CRLF$,0)))))
								EndIf
                ; Set Content-Type
                If ctoffset <> Len(#HTTP_ContentType)
                  *this\Header\ContentType = LTrim(RTrim(PeekS(*this\Buffer+ctoffset,FindString(PeekS(*this\Buffer+ctoffset,#PureHTTP_Buffersize-ctoffset),#CRLF$,0))))
								EndIf
                ; Select Header Response
                *this\Header\Returncode = Val(PeekS(*this\Buffer+eoffset, 3))
                Select *this\Header\Returncode
									Case #HTTP_CODE_OK
                    ; Create File
                    If Len(*this\outputfile) > 0
                      *outfile = CreateFile(#PB_Any,*this\outputfile+".part")
										EndIf
                    ;Set status
                    PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_GOTHEADER)
                    ; Write first bytes to File
                    If *outfile
                      Debug "Writing HeaderData to File..."
                      *this\Totalbytes = Bytes - offset
                      WriteData(*outfile, *this\Buffer + offset, Bytes - offset)
										Else
                      ; Check if Download to Memory & Set Status
                      If Not *this\Destbuffer
                        PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_FILEERROR)
											EndIf
										EndIf
										
                    ; -- Add
                    ; Check if Memory Reserved.
                    If *this\Destbuffer
                      dest_buffersize = MemorySize(*this\Destbuffer)
                      ; Check if Buffer is Big enough for first data...
                      If #PureHTTP_Buffersize > dest_buffersize
                        ; Reallocate Memory to Rec-Buffersize
                        *this\Destbuffer = ReAllocateMemory(*this\Destbuffer,#PureHTTP_Buffersize)
											EndIf
                      ; Download first Data to Memory Buffer
                      CopyMemory(*this\Buffer + offset,*this\Destbuffer,Bytes - offset)
                      *this\Totalbytes + ( Bytes - offset)
										EndIf
										
                    ; Process HTTP REDIRECT
									Case #HTTP_CODE_REDIRECT To #HTTP_CODE_TREDIRECT
                    Debug "302 -> Redirect"
                    ; Set Status
                    PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_GOTHEADER)
                    ; Handle Redirection - Find new Location
                    solocoffset   = FindString(PeekS(*this\Buffer),"Location:",eoffset) + 10
                    eolocoffset   = FindString(PeekS(*this\Buffer),#CRLF$,solocoffset)
                    tmp_redir_url = Mid(PeekS(*this\Buffer), solocoffset, eolocoffset - solocoffset)
                    ; Got Location ? Rewrite URL !
                    If solocoffset
											*this\Host = PureHTTP_SplitURL(tmp_redir_url,#PureHTTP_URL_TO_HOST)
											*this\Path = PureHTTP_SplitURL(tmp_redir_url,#PureHTTP_URL_TO_PATH)
                      redirection = 1
                      ; Set status
                      PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_REDIRECT)
										EndIf
									Default ; Unknown Error Code
                    ; Set Status
                    PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_HTTPERROR)
                    *this\Header\HTTPReturnString = PeekS(*this\Buffer+eoffset,FindString(PeekS(*this\Buffer+eoffset,200),#CRLF$,0))
								EndSelect
							EndIf
							
						Else  ; Download Finished ?
              If Bytes = 0
                PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_FINISHED)
                Debug "** FINISHED **"
							Else ; No? ok then write some ...
                *this\Totalbytes + Bytes
                ; Set Status
                PureHTTP_SET_STATUS(*this, #PureHTTP_STATUS_RECEIVE)
                ; write Data To File
                If *outfile
                  WriteData(*outfile,*this\Buffer,Bytes)
								Else
                  ; Set Status
                  If Not *this\Destbuffer
                    PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_FILEERROR)
									EndIf
								EndIf
								
                ; Download to Memory: Check if Memory Reserved.
                If *this\Destbuffer
                  dest_buffersize = MemorySize(*this\Destbuffer)
                  ; Check if Buffer is Big enough for coming data...
                  If *this\Totalbytes > dest_buffersize
                    ; Reallocate Memory to Fit
                    m_mul = Round(*this\Totalbytes / #PureHTTP_Buffersize,1) + 1
                    *this\Destbuffer = ReAllocateMemory(*this\Destbuffer,(#PureHTTP_Buffersize * m_mul))
									EndIf
                  ; Download first Data to Memory Buffer
                  CopyMemory(*this\Buffer,*this\Destbuffer + *this\Totalbytes - Bytes,Bytes)
								EndIf
								
                ; Update KB/s
                *this\kbps = (*this\Totalbytes / ((ElapsedMilliseconds()-*this\StartTimer)/1000)) / 1024
                Debug StrF(*this\kbps) + " kb/s"
                ; Update Timer
                *this\Timer = ElapsedMilliseconds()
							EndIf
						EndIf
            PaketCounter + 1
            ; Limit Speed to
            If *this\limitspeed <> 0
              While *this\kbps > *this\limitspeed
                ; Update KB/s & wait out our Limit...
                *this\kbps = (*this\Totalbytes / ((ElapsedMilliseconds()-*this\StartTimer)/1000)) / 1024
                Delay(10)
							Wend
						EndIf
					Until *this\Status >= #PureHTTP_STATUS_FINISHED
          ; Close File
          If *outfile
            CloseFile(*outfile)
            CopyFile(*this\outputfile+".part",*this\outputfile)
            DeleteFile(*this\outputfile+".part")
					EndIf
				Default
          ; Set Status
          PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_IDLE)
          Debug "- IDLE -"
			EndSelect
      ; Check Timeout
      If ElapsedMilliseconds() - *this\Timer > #PureHTTP_Timeout
        PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_TIMEOUT)
			EndIf
			
      ; Don't burn CPU while waiting...
      Delay(10)
		Until *this\Status >= #PureHTTP_STATUS_FINISHED
    ; Free Memory
    If *this\Buffer
      FreeMemory(*this\Buffer)
		EndIf
    *this\Totaltime = ElapsedMilliseconds() - *this\StartTimer
    If *this\ConID
      CloseNetworkConnection(*this\ConID)
		EndIf
	Else
    ; Connection Timeout
    PureHTTP_SET_STATUS(*this,#PureHTTP_STATUS_TIMEOUT)
	EndIf
	
  If redirection = 1
    PureHTTP_Get_File(*this._PureHTTP_GET_FILE)
	EndIf
	
  ProcedureReturn *this\Status
EndProcedure

DisableExplicit

Ensuite, tu l'utilises comme ceci :

Code : Tout sélectionner

	myfile._PureHTTP_GET_FILE
	
	myfile\Host = "test.lsi-dev.com"
	myfile\Path = "/" + "Truc/bidule/Machin.txt"
	myfile\outputfile = "C:\Trucbidule.txt"
	
	myfile\userID = "*******"
	myfile\userPass = "********"
	
	If Proxy
		myfile\proxyHost = "xxxxxxxx"
		myfile\proxyPort = "xxxxxxxxxxxx"
		myfile\proxyID = "xxxxxxxxxxx"
		myfile\proxyPass = "xxxxxxxxxx"
	EndIf

	PureHTTP_Get_File(@myfile)
J'espère que cela va t'aider. Je n'ai pas réussi à trouver le sujet original avec ce code alors je reposte.

Re: ReceiveHTTPFile & Proxy

Publié : dim. 08/août/2010 2:15
par Ollivier
@Le Soldat Inconnu

Merci pour l'information! Je crois bien que ça le mérite.

Ollivier