I want to present another solution which uses libcurl.dylib and imports the required functions. The libcurl.dylib doesn't need to be installed because it is contained in /usr/lib.
Code: Select all
EnableExplicit
#ServerFile = "http://purebasic.com/documentation/PureBasicSmall.pdf"
#CURL_ERROR_SIZE          =   256
#CURLOPT_ERRORBUFFER      = 10010
#CURLOPT_NOPROGRESS       =    43
#CURLOPT_PROGRESSFUNCTION = 20056
#CURLOPT_URL              = 10002
#CURLOPT_WRITEFUNCTION    = 20011
ImportC "/usr/lib/libcurl.dylib"
  curl_easy_cleanup(*CurlSession)
  curl_easy_init()
  curl_easy_setopt(*CurlSession, Option.I, Parameter.I)
  curl_easy_strerror(ErrorNumber.I)
  curl_easy_perform(*CurlSession) 
EndImport
Define ClientFile.S = GetTemporaryDirectory() + "PureBasicSmall.pdf"
Define i.I
Define ReceivedData.S
Define ServerFile.S
ProcedureC DataReceivedCallback(*Data, Size.I, NMemb.I, *UserData)
  WriteData(0, *Data, Size * NMemb)
  ProcedureReturn Size * NMemb
EndProcedure
ProcedureC ProgressCallback(*ProgressData, DownloadTotal.D, DownloadNow.D,
  UploadTotal.D, UploadNow.D)
  Debug StrD(DownloadNow) + " Bytes from " + StrD(DownloadTotal) +
    " Bytes have been downloaded"
EndProcedure
Procedure SetCurlOption(CurlSession.I, Option.I, Parameter.I)
  CompilerSelect #PB_Compiler_Processor
    CompilerCase #PB_Processor_x86
      curl_easy_setopt(CurlSession, Option, Parameter)
    CompilerCase #PB_Processor_x64
      !EXTERN _curl_easy_setopt
      !MOV    RDI,QWORD [p.v_CurlSession]
      !MOV    RSI,QWORD [p.v_Option]
      !MOV    RDX,QWORD [p.v_Parameter]
      !CALL   _curl_easy_setopt
  CompilerEndSelect
EndProcedure
Procedure DownloadFile(URL.S)
  Shared ReceivedData.S
  
  Protected CurlSession.I
  Protected ErrorCode.I
  Protected ErrorMsg.S = Space(#CURL_ERROR_SIZE)
  Protected *ErrorMsgBuffer = AllocateMemory(#CURL_ERROR_SIZE)
  Protected Result.I = #False
  
  CurlSession = curl_easy_init()
  
  If CurlSession
    SetCurlOption(CurlSession, #CURLOPT_URL, @URL)
    SetCurlOption(CurlSession, #CURLOPT_WRITEFUNCTION, @DataReceivedCallback())
    SetCurlOption(CurlSession, #CURLOPT_ERRORBUFFER, *ErrorMsgBuffer)
    SetCurlOption(CurlSession, #CURLOPT_PROGRESSFUNCTION, @ProgressCallback())
    SetCurlOption(CurlSession, #CURLOPT_NOPROGRESS, #False)
    
    ErrorCode = curl_easy_perform(CurlSession)
    
    If ErrorCode = 0
      Result = #True
    Else
      CompilerIf #PB_Compiler_Unicode
        ErrorMsg = Space(StringByteLength(PeekS(*ErrorMsgBuffer, -1,
          #PB_Ascii), #PB_Unicode))
        PokeS(@ErrorMsg, PeekS(*ErrorMsgBuffer, -1, #PB_Ascii), -1, #PB_Unicode)
      CompilerElse
        ErrorMsg = PeekS(*ErrorMsgBuffer)
      CompilerEndIf
      If Trim(ErrorMsg) = ""
        CompilerIf #PB_Compiler_Unicode
          ErrorMsg = Space(StringByteLength(PeekS(curl_easy_strerror(ErrorCode),
            -1, #PB_Ascii), #PB_Unicode))
          PokeS(@ErrorMsg, PeekS(curl_easy_strerror(ErrorCode), -1, #PB_Ascii), -1,
            #PB_Unicode)
        CompilerElse
          ErrorMsg = PeekS(curl_easy_strerror(ErrorCode))
        CompilerEndIf
      EndIf
      MessageRequester("Error", ErrorMsg)
    EndIf
    
    FreeMemory(*ErrorMsgBuffer)
    curl_easy_cleanup(CurlSession)
  EndIf
  ProcedureReturn Result
EndProcedure
If OpenFile(0, ClientFile)
  If #PB_Compiler_Unicode
    ServerFile = Space(StringByteLength(#ServerFile))
    PokeS(@ServerFile, #ServerFile, -1, #PB_Ascii)
  Else
    ServerFile = #ServerFile
  EndIf
  If DownloadFile(ServerFile)
    MessageRequester("HTTP-Download", "The file" + #CR$ + #CR$ + #ServerFile + #CR$ + #CR$ + "was downloaded successfully and stored as" + #CR$ + #CR$ + ClientFile)
  EndIf
  CloseFile(0)
EndIf
 
Update 1: I have modified the code to work in both ASCII and Unicode mode.
Update 2: I have added the new procedure SetCurlOption() which uses x64 assembly instructions (when compiled on a x64 processor) to correctly move the arguments into the correct registers and call curl_easy_setopt(). I have verified this code to successfully run on MacOS X Snow Leopard and Mavericks in x86 and x64 mode and in both ASCII and Unicode mode.