Page 1 of 1

[Crossplatform] HTTP GET / Parallels Download

Posted: Fri Dec 26, 2008 7:06 am
by oryaaaaa
This tips do parallels download.
1.CreateList
2.AddElement, and Information set
3.Call PureHTTP_Get_File(myfile())
4.Result retrun, and finish

Normal DL X 2 or 3 speed. have fun.

Library

Code: Select all

; PureHTTP Include Parallels - Version: 0.44b + custmize 0.2
; OS: Linux / Windows / AmigaOS / MacOSX
; Author: Marius Eckardt (Thalius), oryaaaa
; a lil lib for HTTP ( for now just Downloading ;)
; Last Changes: 06.08.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.l) - Splits an URL to Host/Path/Filename
; - Extended Example a little
; 0.41 - 0.44b:
; - small Optimizations
; - Added Redirect Support
; - Download to Memory ( Weee ! ;)
; - Added fixes by "moogle"
; 0.44b + Customize oryaaaaa
; - Parallels Downlads
; - Unicord Support
;
; ToDo:
;  - Bugfixes ?
;  - Extend HTTP Header Structure to support more of HTTP/1.0
;  - HTTP Resume Support
;  - GUI with Callback Example
;  - HTTP POST Functionality
;  - Manual

;- Konstants
; Network
#PureHTTP_Name                  = "PureHTTP" ; UserAgent Name
#PureHTTP_Defaultfile           = "index.html" ; Default for index Files ( used to parse URLs )
#PureHTTP_Buffersize            = 4092   ; 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.l          ; HTTP Return Code -> 200 = OK -> 404 = File Not Found
  ContentLength.l       ; 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.l                  ; FileIDThread ( in case we download multiple files at once )
  *Callback             ; Callback Function
  ConID.l               ; 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.l              ; Download Status
  ; HTTP Header Meta Info
  Header._PureHTTP_HEADER
  ; Network
  *Buffer               ; Pointer to our Paketbuffer
  Totalbytes.l          ; Holds actual Total bytes received from this File
  StartTimer.l          ; Start Timer in ms
  Timer.l               ; Current Our Timer in ms
  Totaltime.l           ; Total DownloadTime
  limitspeed.l          ; Limit Downloadspeed in Kb/s
  kbps.f                ; KB/s
EndStructure

;- Procs

; -- Semi Internal Functions

; Builds GET HTTP Header, kinda interna therefor in CAPS
; Returns HTTP HeaderString
Procedure.s PureHTTP_BUILDHEADER_HTTP_GET(*this._PureHTTP_GET_FILE)
  Protected extras.s
  
  If Len(*this\Path) <= 1
    *this\Path = "/"
  EndIf
  
  ; Add more Checks & stuff here...
  extras.s = Chr(13) + Chr(10) + "User-Agent: " + #PureHTTP_Name
  
  ProcedureReturn "GET " + *this\Path + " " + #HTTP_Protocol10 + Chr(13) + Chr(10) + "host: "+ *this\Host + Chr(13) + Chr(10) +"Connection: Close" + extras.s + Chr(13) + Chr(10) + Chr(13) + Chr(10)
EndProcedure


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

; -- User Functions

; 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.l = #PureHTTP_URL_TO_HOST)
  Protected i.l, a.l
  
  Result.s = ""
  
  ;// Do we have a http:// ?
  a.l = FindString(URL.s,#PureHTTP_URL_Protocol,0)
  If a.l
    URL.s = Right(URL.s,Len(URL.s) - Len(#PureHTTP_URL_Protocol))
    If type.l >= #PureHTTP_URL_TO_HOST And type.l <= #PureHTTP_URL_TO_FILE
      ;// Host   
      Result.s = StringField(URL.s,0,"/")
      
      If type.l = #PureHTTP_URL_TO_FILE
        ;// Filename
        ;// Find File
        num_slash=CountString(URL.s, "/")
        Result.s=StringField(URL.s, num_slash+1, "/")
        ;// Sure we got a File ?
        If FindString(Result.s,".",0) = 0 Or Result.s = StringField(URL.s,0,"/")
          ;// No ? Assuming its an index HTML
          Result.s = #PureHTTP_Defaultfile
        EndIf
      EndIf
      
      ;// Path   
      If type.l = #PureHTTP_URL_TO_PATH
        Result.s = Right(URL.s,Len(URL.s)-Len(Result.s))
      EndIf
      
    EndIf
  EndIf
  
  ProcedureReturn Result.s
EndProcedure

; Func: PureHTTP_Get_File(@myfile)
; Returns: Statuscode See: #PureHTTP_STATUS_*
; Desc: Downloads File
Procedure PureHTTP_Get_File(List this._PureHTTP_GET_FILE())

  Debug ListSize(this())
  
  Structure HttpPacket
    offset.l
    eoffset.l
    cloffset.l
    ctoffset.l
    solocoffset.l
    eolocoffset.l
    Bytes.l
    PaketCounter.l
    SEvent.l
    outfile.l
    m_mul.l
    redirection.l
    dest_buffersize.l
    tmp_redir_url.s
    retry.b
  EndStructure
  
  Protected NewList packet.HttpPacket()
  
  ForEach this._PureHTTP_GET_FILE()
    ;// Set Status
    PureHTTP_SET_STATUS(this(), #PureHTTP_STATUS_CONNECTING)
    
    this()\ConID = OpenNetworkConnection(this()\Host , #HTTP_Port )
    AddElement( packet() )
    Debug this()\ConID
    If this()\ConID
      ;// 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
      SendNetworkString(this()\ConID,PureHTTP_BUILDHEADER_HTTP_GET(this()))
      Debug "* Sending Request"
      ;// Wait for incoming Data ...
      Debug "* Waiting for Reply"
    Else
      PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_TIMEOUT)
    EndIf
  Next
  Repeat
    FirstElement(packet())
    ForEach this()
      If This()\ConID
        packet()\SEvent = NetworkClientEvent(this()\ConID)
        
        Select packet()\SEvent
            ;// We received Data!
          Case #PB_NetworkEvent_Data
            Debug "* Receiving..."
            ;// Now go Fetch!
            Repeat
              packet()\Bytes.l = ReceiveNetworkData(this()\ConID, this()\Buffer, #PureHTTP_Buffersize)
              ;// Is this the first Paket containing the Header ?
              If packet()\PaketCounter.l = 0
                ; PrintN(PeekS(*this\Buffer,#PureHTTP_Buffersize)) ;<- lil Debug For the header
                ;// Basic Process Header - Get DataOffsets
                packet()\eoffset  = FindString(PeekS(this()\Buffer, 200, #PB_Ascii), #HTTP_Protocol10, 0) + Len(#HTTP_Protocol10)
                If packet()\eoffset = Len(#HTTP_Protocol10) ;// We got a HTTP1.1 response, find new offset.
                  packet()\eoffset  = FindString(PeekS(this()\Buffer, 200, #PB_Ascii), #HTTP_Protocol11, 0) + Len(#HTTP_Protocol11)
                EndIf
                ;// We sure in for a right Response now ?
                If packet()\eoffset.l = Len(#HTTP_Protocol10) ; no .. still no offset
                  PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_HTTPERROR)
                Else ; Yeah baby!
                  packet()\cloffset.l = FindString(PeekS(this()\Buffer, #PureHTTP_Buffersize, #PB_Ascii), #HTTP_ContentLength, packet()\eoffset.l) + Len(#HTTP_ContentLength)
                  packet()\ctoffset.l = FindString(PeekS(this()\Buffer, #PureHTTP_Buffersize, #PB_Ascii), #HTTP_ContentType, packet()\eoffset.l) + Len(#HTTP_ContentType)
                  packet()\offset.l   = FindString(PeekS(this()\Buffer, #PureHTTP_Buffersize, #PB_Ascii),Chr(13) + Chr(10) + Chr(13) + Chr(10),packet()\eoffset.l) + 3
                  ;// Do we have a Content-Length Info? if so, set Size
                  If packet()\cloffset.l <> Len(#HTTP_ContentLength)
                    this()\Header\ContentLength = Val(LTrim(RTrim(PeekS(this()\Buffer+packet()\cloffset.l,FindString(PeekS(this()\Buffer+packet()\cloffset.l,#PureHTTP_Buffersize-packet()\cloffset.l, #PB_Ascii),Chr(13) + Chr(10),0), #PB_Ascii))))
                  EndIf
                  ;// Set Content-Type
                  If packet()\ctoffset.l <> Len(#HTTP_ContentType)
                    this()\Header\ContentType = LTrim(RTrim(PeekS(this()\Buffer+packet()\ctoffset.l,FindString(PeekS(this()\Buffer+packet()\ctoffset.l,#PureHTTP_Buffersize-packet()\ctoffset.l, #PB_Ascii),Chr(13) + Chr(10),0), #PB_Ascii)))
                  EndIf
                  ;// Select Header Response
                  this()\Header\Returncode = Val(PeekS(this()\Buffer+packet()\eoffset.l, 3, #PB_Ascii))
                  Select this()\Header\Returncode
                    Case #HTTP_CODE_OK
                      ;// Create File
                      If Len(this()\outputfile) > 0
                        packet()\outfile = CreateFile(#PB_Any,this()\outputfile+".part")
                      EndIf
                      ;//Set status
                      PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_GOTHEADER)
                      ;// Write first bytes to File
                      If packet()\outfile
                        Debug "Writing HeaderData to File..."
                        this()\Totalbytes = packet()\Bytes.l - packet()\offset.l
                        WriteData(packet()\outfile, this()\Buffer + packet()\offset.l, packet()\Bytes.l - packet()\offset.l)
                      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
                        packet()\dest_buffersize.l = MemorySize(this()\Destbuffer)
                        ;// Check if Buffer is Big enough for first data...
                        If #PureHTTP_Buffersize > packet()\dest_buffersize.l
                          ;// Reallocate Memory to Rec-Buffersize
                          this()\Destbuffer = ReAllocateMemory(this()\Destbuffer,#PureHTTP_Buffersize)
                        EndIf
                        ;// Download first Data to Memory Buffer
                        CopyMemory(this()\Buffer + packet()\offset.l,this()\Destbuffer,packet()\Bytes.l - packet()\offset.l)
                        this()\Totalbytes + ( packet()\Bytes.l - packet()\offset.l)
                      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
                      packet()\solocoffset.l   = FindString(PeekS(this()\Buffer,0, #PB_Ascii),"Location:",packet()\eoffset.l) + 10
                      packet()\eolocoffset.l   = FindString(PeekS(this()\Buffer,0, #PB_Ascii),Chr(13) + Chr(10),packet()\solocoffset.l)
                      packet()\tmp_redir_url.s = Mid(PeekS(this()\Buffer,0, #PB_Ascii), packet()\solocoffset, packet()\eolocoffset - packet()\solocoffset)
                      ;// Got Location ? Rewrite URL !
                      If packet()\solocoffset.l
                        this()\Host = PureHTTP_SplitURL(packet()\tmp_redir_url.s,#PureHTTP_URL_TO_HOST)
                        this()\Path = PureHTTP_SplitURL(packet()\tmp_redir_url.s,#PureHTTP_URL_TO_PATH)
                        ;// Set status
                        PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_REDIRECT)
                        ;Delay(100)
                        
                        If this()\Buffer
                          FreeMemory(this()\Buffer)
                        EndIf
                        this()\Totaltime = ElapsedMilliseconds() - this()\StartTimer
                        If this()\ConID
                          CloseNetworkConnection(this()\ConID)
                        EndIf
                        
                        PureHTTP_SET_STATUS(this(), #PureHTTP_STATUS_CONNECTING)
                        
                        this()\ConID = OpenNetworkConnection( this()\Host , #HTTP_Port )
                        AddElement( packet() )
                        
                        If this()\ConID
                          ;// 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
                          SendNetworkString(this()\ConID,PureHTTP_BUILDHEADER_HTTP_GET(this()))
                          Debug "* Sending Request"
                          ;// Wait for incoming Data ...
                          Debug "* Waiting for Reply"
                        Else
                          PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_TIMEOUT)
                        EndIf
                      EndIf                      
                    Default ; Unknown Error Code
                      ;// Set Status
                      PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_HTTPERROR)
                      this()\Header\HTTPReturnString = PeekS(this()\Buffer+packet()\eoffset.l,FindString(PeekS(this()\Buffer+packet()\eoffset.l,200, #PB_Ascii),Chr(13) + Chr(10),0), #PB_Ascii)
                  EndSelect
                EndIf
                
              Else  ;// Download Finished ?
                If packet()\Bytes.l = 0
                  PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_FINISHED)
                  Debug "** FINISHED **"
                Else ;// No? ok then write some ...
                  this()\Totalbytes + packet()\Bytes.l
                  ;// Set Status
                  PureHTTP_SET_STATUS(this(), #PureHTTP_STATUS_RECEIVE)
                  ;// write Data To File
                  If packet()\outfile
                    WriteData(packet()\outfile,this()\Buffer,packet()\Bytes.l)
                  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
                    packet()\dest_buffersize.l = MemorySize(this()\Destbuffer)
                    ;// Check if Buffer is Big enough for coming data...
                    If this()\Totalbytes > packet()\dest_buffersize.l
                      ;// Reallocate Memory to Fit
                      packet()\m_mul.l = Round(this()\Totalbytes / #PureHTTP_Buffersize,1) + 1
                      this()\Destbuffer = ReAllocateMemory(this()\Destbuffer,(#PureHTTP_Buffersize * packet()\m_mul.l))
                    EndIf
                    ;// Download first Data to Memory Buffer
                    CopyMemory(this()\Buffer,(this()\Destbuffer + this()\Totalbytes - packet()\Bytes.l),packet()\Bytes.l)
                  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
              packet()\PaketCounter.l + 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 packet()\outfile
              CloseFile(packet()\outfile)
              CopyFile(this()\outputfile+".part",this()\outputfile)
              DeleteFile(this()\outputfile+".part")
            EndIf
          Default
            ;// Set Status
            PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_IDLE)
            Debug "- IDLE -"+Str(ListIndex(this()))
        EndSelect
        ;// Check Timeout
        If ElapsedMilliseconds() - this()\Timer > #PureHTTP_Timeout
          PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_TIMEOUT)
        EndIf
        
        ;// Don't burn CPU while waiting...
      EndIf
      NextElement(packet())        
    Next
    Delay(10)
    ForEach this()
     If this()\Status >= #PureHTTP_STATUS_FINISHED
       m+1
       If ListSize(this())=<m
        Break 2
       EndIf
     EndIf
     Next
  ForEver  
  ;// Free Memory
  ForEach this()
    If this()\Buffer
      FreeMemory(this()\Buffer)
    EndIf
    this()\Totaltime = ElapsedMilliseconds() - this()\StartTimer
    If this()\ConID
      CloseNetworkConnection(this()\ConID)
    EndIf
    
    ;     If redirection.l = 1
    ;       PureHTTP_Get_File(*this())
    ;     EndIf
  Next
  ProcedureReturn this()\Status
EndProcedure
Test Code

Code: Select all

InitNetwork()

NewList myfile._PureHTTP_GET_FILE()
myurl.s = "http://www.watch.impress.co.jp/headline/rss/headline.rdf"

AddElement(myfile())
myfile()\Host = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_HOST)
myfile()\Path = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_PATH)
myfile()\Destbuffer = AllocateMemory(#PureHTTP_Buffersize)
myfile()\limitspeed = 0 

myurl.s = "http://rss.rssad.jp/rss/impresswatch/pcwatch.rdf"
AddElement(myfile())
myfile()\Host = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_HOST)
myfile()\Path = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_PATH)
myfile()\Destbuffer = AllocateMemory(#PureHTTP_Buffersize)
myfile()\limitspeed = 0 

myurl.s = "http://av.watch.impress.co.jp/sublink/av.rdf"
AddElement(myfile())
myfile()\Host = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_HOST)
myfile()\Path = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_PATH)
myfile()\Destbuffer = AllocateMemory(#PureHTTP_Buffersize)
;myfile()\Callback = @MyCallback()
myfile()\limitspeed = 0 


;// Start Download
Status.l = PureHTTP_Get_File(myfile())

;// Select Status after we are done.
Select Status.l
  Case #PureHTTP_STATUS_CONNECTING   ; Connecting
  Case #PureHTTP_STATUS_CONNECTED    ; Connected
  Case #PureHTTP_STATUS_RECEIVE      ; Receiving...
  Case #PureHTTP_STATUS_IDLE         ; Idle, Waiting for Data...
  Case #PureHTTP_STATUS_FINISHED     ; Download Finished
      Debug "Finish"
  Case #PureHTTP_STATUS_TIMEOUT      ; Timeout
   Debug "Timeout"
;    PrintN("* Connection Timeout!")
  Case #PureHTTP_STATUS_HTTPERROR    ; HTTP Error / Return
;    PrintN("HTTP ERROR "+myfile\Header\HTTPReturnString)
     Debug "HTTP ERROR "+myfile()\Header\HTTPReturnString
  Case #PureHTTP_STATUS_REDIRECT
;    PrintN("HTTP REDIRECT 302")
     Debug "302"
  Case #PureHTTP_STATUS_FILEERROR    ; Cant create file
;    PrintN("Unable to Write File: "+myfile\outputfile)
     Debug "FILE ERROR"
  Case #PureHTTP_STATUS_ABORT        ; Download Aborted
     Debug "ABORT"
EndSelect

l=0
ForEach myfile()

;// !!! Debug Download to Memory Buffer
If myfile()\Destbuffer
  Debug "Memorycontent:"
  Debug "Memorybuffersize: "+Str(MemorySize(myfile()\Destbuffer))+" bytes"
  Debug "Received Data   : "+Str(myfile()\Totalbytes)+" bytes"
  Debug PeekS(myfile()\Destbuffer)
EndIf
l+1
CreateFile(1, "mem"+Str(l)+".txt")
WriteData(1, myfile()\Destbuffer, myfile()\totalbytes)
CloseFile(1)
Next

Posted: Fri Dec 26, 2008 8:22 am
by Rings
i put a working version here (replaced some
japanesed caracters (not oryaaaaa's fault ) and
add a InitNetwork() ) :

Code: Select all

; PureHTTP Include Parallels - Version: 0.44b + customize 0.1
; OS: Linux / Windows / AmigaOS / MacOSX
; Author: Marius Eckardt (Thalius), oryaaaaa
; a lil lib for HTTP ( for now just Downloading ;)
; Last Changes: 06.08.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.l) - Splits an URL to Host/Path/Filename
; - Extended Example a little
; 0.41 - 0.44b:
; - small Optimizations
; - Added Redirect Support
; - Download to Memory ( Weee ! ;)
; - Added fixes by "moogle"
; 0.44b + Customize oryaaaaa
; - Parallels Downlads
;
; ToDo:
;  - Bugfixes ?
;  - Extend HTTP Header Structure to support more of HTTP/1.0
;  - HTTP Resume Support
;  - GUI with Callback Example
;  - HTTP POST Functionality
;  - Manual

;- Konstants
; Network
#PureHTTP_Name                  = "PureHTTP" ; UserAgent Name
#PureHTTP_Defaultfile           = "index.html" ; Default for index Files ( used to parse URLs )
#PureHTTP_Buffersize            = 4092   ; 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.l          ; HTTP Return Code -> 200 = OK -> 404 = File Not Found
  ContentLength.l       ; 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.l                  ; FileIDThread ( in case we download multiple files at once )
  *Callback             ; Callback Function
  ConID.l               ; 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.l              ; Download Status
  ; HTTP Header Meta Info
  Header._PureHTTP_HEADER
  ; Network
  *Buffer               ; Pointer to our Paketbuffer
  Totalbytes.l          ; Holds actual Total bytes received from this File
  StartTimer.l          ; Start Timer in ms
  Timer.l               ; Current Our Timer in ms
  Totaltime.l           ; Total DownloadTime
  limitspeed.l          ; Limit Downloadspeed in Kb/s
  kbps.f                ; KB/s
EndStructure

;- Procs

; -- Semi Internal Functions

; Builds GET HTTP Header, kinda interna therefor in CAPS
; Returns HTTP HeaderString
Procedure.s PureHTTP_BUILDHEADER_HTTP_GET(*this._PureHTTP_GET_FILE)
  Protected extras.s
 
  If Len(*this\Path) <= 1
    *this\Path = "/"
  EndIf
 
  ; Add more Checks & stuff here...
  extras.s = Chr(13) + Chr(10) + "User-Agent: " + #PureHTTP_Name
 
  ProcedureReturn "GET " + *this\Path + " " + #HTTP_Protocol10 + Chr(13) + Chr(10) + "host: "+ *this\Host + Chr(13) + Chr(10) +"Connection: Close" + extras.s + Chr(13) + Chr(10) + Chr(13) + Chr(10)
EndProcedure


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

; -- User Functions

; 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.l = #PureHTTP_URL_TO_HOST)
  Protected i.l, a.l
 
  Result.s = ""
 
  ;// Do we have a http:// ?
  a.l = FindString(URL.s,#PureHTTP_URL_Protocol,0)
  If a.l
    URL.s = Right(URL.s,Len(URL.s) - Len(#PureHTTP_URL_Protocol))
    If type.l >= #PureHTTP_URL_TO_HOST And type.l <= #PureHTTP_URL_TO_FILE
      ;// Host   
      Result.s = StringField(URL.s,0,"/")
     
      If type.l = #PureHTTP_URL_TO_FILE
        ;// Filename
        ;// Find File
        num_slash=CountString(URL.s, "/")
        Result.s=StringField(URL.s, num_slash+1, "/")
        ;// Sure we got a File ?
        If FindString(Result.s,".",0) = 0 Or Result.s = StringField(URL.s,0,"/")
          ;// No ? Assuming its an index HTML
          Result.s = #PureHTTP_Defaultfile
        EndIf
      EndIf
     
      ;// Path   
      If type.l = #PureHTTP_URL_TO_PATH
        Result.s = Right(URL.s,Len(URL.s)-Len(Result.s))
      EndIf
     
    EndIf
  EndIf
 
  ProcedureReturn Result.s
EndProcedure

; Func: PureHTTP_Get_File(@myfile)
; Returns: Statuscode See: #PureHTTP_STATUS_*
; Desc: Downloads File
Procedure PureHTTP_Get_File(List this._PureHTTP_GET_FILE())

  Debug ListSize(this())
 
  Structure HttpPacket
    offset.l
    eoffset.l
    cloffset.l
    ctoffset.l
    solocoffset.l
    eolocoffset.l
    Bytes.l
    PaketCounter.l
    SEvent.l
    outfile.l
    m_mul.l
    redirection.l
    dest_buffersize.l
    tmp_redir_url.s
    retry.b
  EndStructure
 
  Protected NewList packet.HttpPacket()
 
  ForEach this._PureHTTP_GET_FILE()
    ;// Set Status
    PureHTTP_SET_STATUS(this(), #PureHTTP_STATUS_CONNECTING)
   
    this()\ConID = OpenNetworkConnection(this()\Host , #HTTP_Port )
    AddElement( packet() )
    Debug this()\ConID
    If this()\ConID
      ;// 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
      SendNetworkString(this()\ConID,PureHTTP_BUILDHEADER_HTTP_GET(this()))
      Debug "* Sending Request"
      ;// Wait for incoming Data ...
      Debug "* Waiting for Reply"
    Else
      PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_TIMEOUT)
    EndIf
  Next
  Repeat
    FirstElement(packet())
    ForEach this()
      If This()\ConID
        packet()\SEvent = NetworkClientEvent(this()\ConID)
       
        Select packet()\SEvent
            ;// We received Data!
          Case #PB_NetworkEvent_Data
            Debug "* Receiving..."
            ;// Now go Fetch!
            Repeat
              packet()\Bytes.l = ReceiveNetworkData(this()\ConID, this()\Buffer, #PureHTTP_Buffersize)
              ;// Is this the first Paket containing the Header ?
              If packet()\PaketCounter.l = 0
                ; PrintN(PeekS(*this\Buffer,#PureHTTP_Buffersize)) ;<- lil Debug For the header
                ;// Basic Process Header - Get DataOffsets
                packet()\eoffset  = FindString(PeekS(this()\Buffer, 200), #HTTP_Protocol10, 0) + Len(#HTTP_Protocol10)
                If packet()\eoffset = Len(#HTTP_Protocol10) ;// We got a HTTP1.1 response, find new offset.
                  packet()\eoffset  = FindString(PeekS(this()\Buffer, 200), #HTTP_Protocol11, 0) + Len(#HTTP_Protocol11)
                EndIf
                ;// We sure in for a right Response now ?
                If packet()\eoffset.l = Len(#HTTP_Protocol10) ; no .. still no offset
                  PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_HTTPERROR)
                Else ; Yeah baby!
                  packet()\cloffset.l = FindString(PeekS(this()\Buffer, #PureHTTP_Buffersize), #HTTP_ContentLength, packet()\eoffset.l) + Len(#HTTP_ContentLength)
                  packet()\ctoffset.l = FindString(PeekS(this()\Buffer, #PureHTTP_Buffersize), #HTTP_ContentType, packet()\eoffset.l) + Len(#HTTP_ContentType)
                  packet()\offset.l   = FindString(PeekS(this()\Buffer, #PureHTTP_Buffersize),Chr(13) + Chr(10) + Chr(13) + Chr(10),packet()\eoffset.l) + 3
                  ;// Do we have a Content-Length Info? if so, set Size
                  If packet()\cloffset.l <> Len(#HTTP_ContentLength)
                    this()\Header\ContentLength = Val(LTrim(RTrim(PeekS(this()\Buffer+packet()\cloffset.l,FindString(PeekS(this()\Buffer+packet()\cloffset.l,#PureHTTP_Buffersize-packet()\cloffset.l),Chr(13) + Chr(10),0)))))
                  EndIf
                  ;// Set Content-Type
                  If packet()\ctoffset.l <> Len(#HTTP_ContentType)
                    this()\Header\ContentType = LTrim(RTrim(PeekS(this()\Buffer+packet()\ctoffset.l,FindString(PeekS(this()\Buffer+packet()\ctoffset.l,#PureHTTP_Buffersize-packet()\ctoffset.l),Chr(13) + Chr(10),0))))
                  EndIf
                  ;// Select Header Response
                  this()\Header\Returncode = Val(PeekS(this()\Buffer+packet()\eoffset.l, 3))
                  Select this()\Header\Returncode
                    Case #HTTP_CODE_OK
                      ;// Create File
                      If Len(this()\outputfile) > 0
                        packet()\outfile = CreateFile(#PB_Any,this()\outputfile+".part")
                      EndIf
                      ;//Set status
                      PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_GOTHEADER)
                      ;// Write first bytes to File
                      If packet()\outfile
                        Debug "Writing HeaderData to File..."
                        this()\Totalbytes = packet()\Bytes.l - packet()\offset.l
                        WriteData(packet()\outfile, this()\Buffer + packet()\offset.l, packet()\Bytes.l - packet()\offset.l)
                      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
                        packet()\dest_buffersize.l = MemorySize(this()\Destbuffer)
                        ;// Check if Buffer is Big enough for first data...
                        If #PureHTTP_Buffersize > packet()\dest_buffersize.l
                          ;// Reallocate Memory to Rec-Buffersize
                          this()\Destbuffer = ReAllocateMemory(this()\Destbuffer,#PureHTTP_Buffersize)
                        EndIf
                        ;// Download first Data to Memory Buffer
                        CopyMemory(this()\Buffer + packet()\offset.l,this()\Destbuffer,packet()\Bytes.l - packet()\offset.l)
                        this()\Totalbytes + ( packet()\Bytes.l - packet()\offset.l)
                      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
                      packet()\solocoffset.l   = FindString(PeekS(this()\Buffer),"Location:",packet()\eoffset.l) + 10
                      packet()\eolocoffset.l   = FindString(PeekS(this()\Buffer),Chr(13) + Chr(10),packet()\solocoffset.l)
                      packet()\tmp_redir_url.s = Mid(PeekS(this()\Buffer), packet()\solocoffset, packet()\eolocoffset - packet()\solocoffset)
                      ;// Got Location ? Rewrite URL !
                      If packet()\solocoffset.l
                        this()\Host = PureHTTP_SplitURL(packet()\tmp_redir_url.s,#PureHTTP_URL_TO_HOST)
                        this()\Path = PureHTTP_SplitURL(packet()\tmp_redir_url.s,#PureHTTP_URL_TO_PATH)
                        ;// Set status
                        PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_REDIRECT)
                        ;Delay(100)
                       
                        If this()\Buffer
                          FreeMemory(this()\Buffer)
                        EndIf
                        this()\Totaltime = ElapsedMilliseconds() - this()\StartTimer
                        If this()\ConID
                          CloseNetworkConnection(this()\ConID)
                        EndIf
                       
                        PureHTTP_SET_STATUS(this(), #PureHTTP_STATUS_CONNECTING)
                       
                        this()\ConID = OpenNetworkConnection( this()\Host , #HTTP_Port )
                        AddElement( packet() )
                       
                        If this()\ConID
                          ;// 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
                          SendNetworkString(this()\ConID,PureHTTP_BUILDHEADER_HTTP_GET(this()))
                          Debug "* Sending Request"
                          ;// Wait for incoming Data ...
                          Debug "* Waiting for Reply"
                        Else
                          PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_TIMEOUT)
                        EndIf
                      EndIf                     
                    Default ; Unknown Error Code
                      ;// Set Status
                      PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_HTTPERROR)
                      this()\Header\HTTPReturnString = PeekS(this()\Buffer+packet()\eoffset.l,FindString(PeekS(this()\Buffer+packet()\eoffset.l,200),Chr(13) + Chr(10),0))
                  EndSelect
                EndIf
               
              Else  ;// Download Finished ?
                If packet()\Bytes.l = 0
                  PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_FINISHED)
                  Debug "** FINISHED **"
                Else ;// No? ok then write some ...
                  this()\Totalbytes + packet()\Bytes.l
                  ;// Set Status
                  PureHTTP_SET_STATUS(this(), #PureHTTP_STATUS_RECEIVE)
                  ;// write Data To File
                  If packet()\outfile
                    WriteData(packet()\outfile,this()\Buffer,packet()\Bytes.l)
                  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
                    packet()\dest_buffersize.l = MemorySize(this()\Destbuffer)
                    ;// Check if Buffer is Big enough for coming data...
                    If this()\Totalbytes > packet()\dest_buffersize.l
                      ;// Reallocate Memory to Fit
                      packet()\m_mul.l = Round(this()\Totalbytes / #PureHTTP_Buffersize,1) + 1
                      this()\Destbuffer = ReAllocateMemory(this()\Destbuffer,(#PureHTTP_Buffersize * packet()\m_mul.l))
                    EndIf
                    ;// Download first Data to Memory Buffer
                    CopyMemory(this()\Buffer,(this()\Destbuffer + this()\Totalbytes - packet()\Bytes.l),packet()\Bytes.l)
                  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
              packet()\PaketCounter.l + 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 packet()\outfile
              CloseFile(packet()\outfile)
              CopyFile(this()\outputfile+".part",this()\outputfile)
              DeleteFile(this()\outputfile+".part")
            EndIf
          Default
            ;// Set Status
            PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_IDLE)
            Debug "- IDLE -"+Str(ListIndex(this()))
        EndSelect
        ;// Check Timeout
        If ElapsedMilliseconds() - this()\Timer > #PureHTTP_Timeout
          PureHTTP_SET_STATUS(this(),#PureHTTP_STATUS_TIMEOUT)
        EndIf
       
        ;// Don't burn CPU while waiting...
      EndIf
      NextElement(packet())       
    Next
    Delay(10)
    ForEach this()
     If this()\Status >= #PureHTTP_STATUS_FINISHED
       m+1
       If ListSize(this())=<m
        Break 2
       EndIf
     EndIf
     Next
  ForEver 
  ;// Free Memory
  ForEach this()
    If this()\Buffer
      FreeMemory(this()\Buffer)
    EndIf
    this()\Totaltime = ElapsedMilliseconds() - this()\StartTimer
    If this()\ConID
      CloseNetworkConnection(this()\ConID)
    EndIf
   
    ;     If redirection.l = 1
    ;       PureHTTP_Get_File(*this())
    ;     EndIf
  Next
  ProcedureReturn this()\Status
EndProcedure

; **** END OF INCLUDE **** 
InitNetwork()

NewList myfile._PureHTTP_GET_FILE()
myurl.s = "http://www.watch.impress.co.jp/headline/rss/headline.rdf"

AddElement(myfile())
myfile()\Host = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_HOST)
myfile()\Path = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_PATH)
myfile()\Destbuffer = AllocateMemory(#PureHTTP_Buffersize)
myfile()\limitspeed = 0

AddElement(myfile())
myfile()\Host = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_HOST)
myfile()\Path = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_PATH)
myfile()\Destbuffer = AllocateMemory(#PureHTTP_Buffersize)
myfile()\limitspeed = 0

AddElement(myfile())
myfile()\Host = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_HOST)
myfile()\Path = PureHTTP_SplitURL(myurl.s,#PureHTTP_URL_TO_PATH)
myfile()\Destbuffer = AllocateMemory(#PureHTTP_Buffersize)
myfile()\limitspeed = 0

;// Start Download
Status.l = PureHTTP_Get_File(myfile())

;// Select Status after we are done.
Select Status.l
  Case #PureHTTP_STATUS_CONNECTING   ; Connecting
  Case #PureHTTP_STATUS_CONNECTED    ; Connected
  Case #PureHTTP_STATUS_RECEIVE      ; Receiving...
  Case #PureHTTP_STATUS_IDLE         ; Idle, Waiting for Data...
  Case #PureHTTP_STATUS_FINISHED     ; Download Finished
      Debug "Finish"
  Case #PureHTTP_STATUS_TIMEOUT      ; Timeout
   Debug "Timeout"
;    PrintN("* Connection Timeout!")
  Case #PureHTTP_STATUS_HTTPERROR    ; HTTP Error / Return
;    PrintN("HTTP ERROR "+myfile\Header\HTTPReturnString)
     Debug "HTTP ERROR "+myfile()\Header\HTTPReturnString
  Case #PureHTTP_STATUS_REDIRECT
;    PrintN("HTTP REDIRECT 302")
     Debug "302"
  Case #PureHTTP_STATUS_FILEERROR    ; Cant create file
;    PrintN("Unable to Write File: "+myfile\outputfile)
     Debug "FILE ERROR"
  Case #PureHTTP_STATUS_ABORT        ; Download Aborted
     Debug "ABORT"
EndSelect

;// !!! Debug Download to Memory Buffer
If myfile()\Destbuffer
  Debug "Memorycontent:"
  Debug "Memorybuffersize: "+Str(MemorySize(myfile()\Destbuffer))+" bytes"
  Debug "Received Data   : "+Str(myfile()\Totalbytes)+" bytes"
  Debug PeekS(myfile()\Destbuffer)
EndIf

;PrintN("Press Enter to exit ...")
;Input()
l=0
ForEach myfile()
l+1
CreateFile(1, "mem"+Str(l)+".txt")
WriteData(1, myfile()\Destbuffer, myfile()\totalbytes)
CloseFile(1)
Next 

Posted: Fri Dec 26, 2008 8:37 am
by rsts
Very nice.

Thanks to you both :)

Posted: Fri Dec 26, 2008 10:44 am
by oryaaaaa
Rings, Rsts. Thank you.

I fixed.... and Unicord Support
Need in MacOSX
IDE save sample.pb. XCODE open sample.pb
Copy & Paste. no problem.

Re: [Crossplatform] HTTP GET / Parallels Download

Posted: Sat Jan 23, 2010 4:36 am
by oryaaaaa
News

MS10-002, This code down network performance. Maybe MS10-002 IE patch is
Parallels Network attacks disable patch... :shock:

Microsoft Security Bulletin Summary for January 2010
http://www.microsoft.com/technet/securi ... 0-jan.mspx