Page 1 of 1

Openssl or libcurl

Posted: Tue Sep 28, 2010 11:03 am
by Miro
Hello to all,

Does anyone have a working example of HTTPS POST (file upload) by using OpenSSL or libCurl on Windows?

Thanks in advance for your help and eventual constructive comments.

Best regards,
Miro

Re: Openssl or libcurl

Posted: Tue Sep 28, 2010 11:52 am
by Kiffi
Miro wrote:or libCurl on Windows?
use the search, Luke! ;-)

http://code.google.com/p/rwrappers/

Greetings ... Kiffi

Re: Openssl or libcurl

Posted: Tue Sep 28, 2010 12:36 pm
by Miro
Thanks, I have already used the search, downloaded the wrapper,
but couldn't get it to work, and that's the main reason why I posted the message.

In any way, thanks for your reply.

EDIT: Could anyone help me, please!

Best regards,
Miro

Re: Openssl or libcurl

Posted: Thu Oct 07, 2010 12:44 pm
by Miro
Is there anyone who can help me with my problem?

Best regards,
Miro

Re: Openssl or libcurl

Posted: Fri Oct 29, 2010 11:55 am
by scriptmaster
I went through this route and quickly turned to another solution. For Windows, there is a nice code in the codearchive named, Https_SSL_Connect.pb that uses WinAPI - simple and to the point - I was able to upload data perfectly!

I am copying that code here if you are having trouble finding it (By the way, don't ever install any UserLibPack - I did that mistake and crashed my compiler)

I added my version of that code with (HTTP/HTTPS Switch support), with an example usage.

http_post.pbi

Code: Select all


; English forum: http://purebasic.myforums.net/viewtopic.php?t=8302&highlight=
; Author: Karbon
; Date: 12. November 2003

; Note by Andre: I've changed #INTERNET_DEFAULT_HTTP_PORT = 443 to 
;                #INTERNET_DEFAULT_HTTPS_PORT = 443  (be aware of the additional 'S' at '_HTTPS_')
;                because the #INTERNET_DEFAULT_HTTP_PORT constant is already declared in a .res
;                file with another value

; This one does SSL, all you need to do for standard HTTP is change the
; INTERNET_FLAG_SECURE To 0 and the port to 80. 

  ; 
  ; All stuff for the WinInet lib. 
  ; 
  #INTERNET_OPEN_TYPE_DIRECT = 1 
  #HTTP_ADDREQ_FLAG_ADD = $20000000 
  #HTTP_ADDREQ_FLAG_REPLACE = $80000000 
  #INTERNET_FLAG_SECURE = $800000 
  
  ; 
  ; Type of connection (could be FTP Gopher etc). HTTPS is done as HTTP too. 
  ; 
  #INTERNET_SERVICE_HTTP = 3 
  
  ; 
  ; HTTP port is 80, HTTPS (SSL) port is 443. 
  ; 
  #INTERNET_DEFAULT_HTTPS_PORT = 443  

Procedure.s do_post(url.s, post_data.s) 

  ; 
  ; Extract host name: i.e.  www.domain.com  or   ssl.domain.com
  ; 
  host.s = GetURLPart(url, #PB_URL_Site)
  
  ; 
  ; Everything after the hostname of the server 
  ; 
  get_url.s = "/" + GetURLPart(url, #PB_URL_Path)
  
  ; 
  ; Holds the result from the CGI/page 
  ; 
  result.s = "" 
  
  port = 80
  ssl_option = 0

  If GetURLPart(url, #PB_URL_Protocol) = "https"
   ssl_option = #INTERNET_FLAG_SECURE
   port = #INTERNET_DEFAULT_HTTPS_PORT
  EndIf

  ; 
  ; All from the wininet DLL 
  ; 
  ; Be sure your Internet Explorer is up to date! 
  ; 
  open_handle = InternetOpen_("GTFax Uploader",#INTERNET_OPEN_TYPE_DIRECT,"","",0) 
  
  connect_handle = InternetConnect_(open_handle,host,port,"","",#INTERNET_SERVICE_HTTP,0,0) 
  
  request_handle = HttpOpenRequest_(connect_handle,"POST",get_url,"","",0,ssl_option,0) 
  
  headers.s = "Content-Type: application/x-www-form-urlencoded" +Chr(13)+Chr(10)  
  
  HttpAddRequestHeaders_(request_handle,headers,Len(headers), #HTTP_ADDREQ_FLAG_REPLACE | #HTTP_ADDREQ_FLAG_ADD) 
  
  ; post_data.s = "CMD=AUTH&USERNAME=test&PASSWORD=test" 
  
  post_data_len = Len(post_data) 
  
  send_handle = HttpSendRequest_(request_handle,"",0,post_data,post_data_len) 
  
  buffer.s = Space(1024) 
  
  bytes_read.l 
  
  total_read.l 
  
  total_read = 0 
  
  ; 
  ; Read until we can't read anymore.. 
  ; The string "result" will hold what ever the server pushed at us. 
  ; 
  Repeat 
    
    InternetReadFile_(request_handle,@buffer,1024,@bytes_read) 
    
    result + Left(buffer,bytes_read) 
    
    buffer = Space(1024) 
    
  Until bytes_read=0 
  
  ProcedureReturn result
  
EndProcedure 



Example usage:

test_post.pb

Code: Select all

IncludeFile "http_post.pbi"
Debug  do_post( "https://myurl.com", "CMD=AUTH&USER=test&PASS=test" )
Hope this helps

Re: Openssl or libcurl

Posted: Fri Oct 29, 2010 1:31 pm
by Kukulkan
I would prefer using cURL. It is good for your needs. I wrote a cURL implementation using PureBasic, but it was for my company and I cant provide it here. But you may have had problems using the wrapper because you have missed some files (like me before):

To be able to use libcurl.dll you need the following files in the same folder (or system32):

- libcurl.dll (http://curl.haxx.se/libcurl/)
- libeay32.dll (openssl)
- ssleay32.dll (openssl)
- cacert.pem (get a actual one here: http://curl.haxx.se/docs/caextract.html)

This worked great for me!

Kukulkan

Re: Openssl or libcurl

Posted: Wed Nov 03, 2010 11:15 pm
by scriptmaster
Hi Kukulkan,

I had to return to curl because there was a new requirement to send multi-form data. I used the LibCurl using RWrappers from http://purearea.net/pb/download/dll/RWL ... 7.17.1.zip made by Progi1984

Although a simple example works fine (even without any certificate file), sending form data fails :(

Steps I did.

#1) Downloaded that zip file.
#2) Extracted that in a preferred location.
#3) Wrote a quick test program - but it crashed (if I comment one particular line, it doesn't)

Code: Select all


XIncludeFile "RW_LibCurl_Res.pb"
XIncludeFile "RW_LibCurl_Inc.pb"

url.s = "https://myurl.com/"

curl  = curl_easy_init()
If curl

    Debug curl_easy_setopt(curl, #CURLOPT_URL, @url)

    Debug curl_easy_setopt(curl, #CURLOPT_SSL_VERIFYPEER, #False)
    Debug curl_easy_setopt(curl, #CURLOPT_SSL_VERIFYHOST, #False)

    TryFirstMethod = #False
    
    If TryFirstMethod
      Debug curl_easy_setopt(curl, #CURLOPT_POSTFIELDS, @"CMD=AUTH&USERNAME=test&PASSWORD=test") ;; This works but I want to try with forms
    Else
      ;; Trying with forms instead
      Define.Curl_HTTPPost post, last_post;
      
      curl_formadd(@post, @last_post, #CURLFORM_COPYNAME, @"CMD", #CURLFORM_COPYCONTENTS, @"AUTH", #CURLFORM_END);
      curl_formadd(@post,@ last_post, #CURLFORM_COPYNAME, @"USERNAME", #CURLFORM_COPYCONTENTS, @"test", #CURLFORM_END);
      curl_formadd(@post, @last_post, #CURLFORM_COPYNAME, @"PASSWORD", #CURLFORM_COPYCONTENTS, @"test", #CURLFORM_END);

      Debug curl_easy_setopt(curl, #CURLOPT_HTTPPOST, @post); ;; If I comment this line it doesn't crash

    EndIf

    Debug curl_easy_setopt(curl, #CURLOPT_WRITEFUNCTION, @RW_LibCurl_WriteFunction())
    
    res = curl_easy_perform(curl) ; Crashes at this line :(
    Debug res
    
    http_result.s = RW_LibCurl_GetData()
    Debug http_result

    ;always cleanup 
    Debug curl_easy_cleanup(curl)

EndIf

Could you give me a working example for sending in actual form data, like for example a file-upload?

Re: Openssl or libcurl

Posted: Wed Nov 03, 2010 11:24 pm
by scriptmaster
Oops, I found the issue - it was to do with pointers lol. and it worked!! Yay!

Changed code from:

Code: Select all

      ;; Trying with forms instead
      Define.Curl_HTTPPost post, last_post;
     
      curl_formadd(@post, @last_post, #CURLFORM_COPYNAME, @"CMD", #CURLFORM_COPYCONTENTS, @"AUTH", #CURLFORM_END);
      curl_formadd(@post,@ last_post, #CURLFORM_COPYNAME, @"USERNAME", #CURLFORM_COPYCONTENTS, @"test", #CURLFORM_END);
      curl_formadd(@post, @last_post, #CURLFORM_COPYNAME, @"PASSWORD", #CURLFORM_COPYCONTENTS, @"test", #CURLFORM_END);

      Debug curl_easy_setopt(curl, #CURLOPT_HTTPPOST, @post); ;; If I comment this line it doesn't crash
to

Code: Select all

      ;; Trying with forms instead
      Define *formpost.Curl_HTTPPost, *last_post.Curl_HTTPPost;

      curl_formadd(@*formpost, @*last_post, #CURLFORM_COPYNAME, @"CMD", #CURLFORM_COPYCONTENTS, @"AUTH", #CURLFORM_END);
      curl_formadd(@*formpost, @*last_post, #CURLFORM_COPYNAME, @"USERNAME", #CURLFORM_COPYCONTENTS, @"test", #CURLFORM_END);
      curl_formadd(@*formpost, @*last_post, #CURLFORM_COPYNAME, @"PASSWORD", #CURLFORM_COPYCONTENTS, @"test", #CURLFORM_END);

      Debug curl_easy_setopt(curl, #CURLOPT_HTTPPOST, *formpost); ;; If I comment this line it doesn't crash

Re: Openssl or libcurl

Posted: Wed Nov 03, 2010 11:27 pm
by scriptmaster
By the way, this is a nice URL from libcurl - hope this helps someone like me ;)

http://curl.haxx.se/libcurl/c/postit2.html

Re: Openssl or libcurl

Posted: Mon Nov 22, 2010 11:16 pm
by Miro
scriptmaster wrote: ...

Code: Select all

      ;; Trying with forms instead
      Define *formpost.Curl_HTTPPost, *last_post.Curl_HTTPPost;

      curl_formadd(@*formpost, @*last_post, #CURLFORM_COPYNAME, @"CMD", #CURLFORM_COPYCONTENTS, @"AUTH", #CURLFORM_END);
      curl_formadd(@*formpost, @*last_post, #CURLFORM_COPYNAME, @"USERNAME", #CURLFORM_COPYCONTENTS, @"test", #CURLFORM_END);
      curl_formadd(@*formpost, @*last_post, #CURLFORM_COPYNAME, @"PASSWORD", #CURLFORM_COPYCONTENTS, @"test", #CURLFORM_END);

      Debug curl_easy_setopt(curl, #CURLOPT_HTTPPOST, *formpost); ;; If I comment this line it doesn't crash
I get 'curl_formadd()' incorrect number of parameters?!

Re: Openssl or libcurl

Posted: Tue Nov 23, 2010 8:15 am
by Kukulkan
Are you shure you have to set formpost and last-post as reference to pointers? Try to remove the @ from these values (I did no check of this, just an opinion).

Kukulkan

Re: Openssl or libcurl

Posted: Tue Dec 07, 2010 7:36 pm
by Miro
Nope, the main issue is that this function requires 2 parameters (although, original C code supports overload), and I still didn't manage to perform file upload via https... :(

Anyone?