AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

libcurl Wrapper (WIP)

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
DeathByNukes



Joined: 25 Mar 2007
Posts: 14
Location: Mabase

PostPosted: Tue May 20, 2008 9:25 pm    Post subject: libcurl Wrapper (WIP) Reply with quote

A while back I started working on a wrapper for the libcurl easy interface. (libcurl is the DLL version of cURL.) I got it pretty much done, except there is an error while doing a form POST that I couldn't nail down. I'm posting it here because it still has a lot of uses even without the ability to POST, and because someone taking a fresh look at it might be able to spot my mistake.
I based it upon olfen's libcurl example.

Here is the libcurl documentation: http://curl.haxx.se/libcurl/c/

Downloads:

libcurl.ahk - The wrapper include file.
libcurl.dll - Win32 libcurl 7.18.1 without SSL. (latest version on 5/20/2008)
libcurl.dll - Win32 libcurl 7.18.1 with SSL. Requires SSL libraries.
libcurl_test.ahk - olfen's test script running through the wrapper.
libcurl_imageshacktest.ahk - A modified test script that posts to imageshack. (erroneous)

The test scripts require FileHelper.ahk.

Functions:
The functions use the global variables CurlDllName and hCurlModule. Be sure not to overwrite them.

CurlGlobalInit( Location = "", flags = 3 )
You must call this first. It loads the DLL and returns curl_global_init( flags ) or -1 if the DLL failed to load. (0 = Success) Location is the path to libcurl and the file name minus ".dll". If Location is omitted, it defaults to "libcurl". It stores the name in a global variable so the other functions will know it.
Code:
;Flags:
;CURL_GLOBAL_SSL = 1
;CURL_GLOBAL_WIN32 = 2
;CURL_GLOBAL_ALL = 3
;CURL_GLOBAL_NOTHING = 0
;CURL_GLOBAL_DEFAULT = 3
CurlGlobalInit( "Common\libcurl" )
CurlGlobalInit( "", 2 ) ; CURL_GLOBAL_WIN32
CurlGlobalInit( "libcurl-4", 0 )

CurlFreeLibrary()
This frees the libcurl DLL. All handles and pointers created by libcurl will be invalidated and libcurl will become unusable until CurlGlobalInit() is called again.

CurlEasyInit()
Returns curl_easy_init().

CurlEasyReset( EasyHandle )
Calls curl_easy_reset( EasyHandle ).

CurlEasyCleanup( EasyHandle )
Calls curl_easy_cleanup( EasyHandle ).

CurlShowErrors( Yes = true )
If set to true, causes some of the wrapper functions to display libcurl string errors in message boxes.

CurlEasySetOption( EasyHandle, Option, Parameter )
If Parameter is an integer it returns curl_easy_setopt( EasyHandle, Option, Parameter ). Otherwise, it returns curl_easy_setopt( EasyHandle, Option, &Parameter ).
You can use CurlEasyDefineOptions() to define the CURLOPT options as variables for easier use of this function.

CurlSlistAppend( ByRef pSlist, String )
Calls curl_slist_append( pSlist, String ) and sets pSlist to the returned value.

CurlSlistFreeAll( ByRef pSlist )
Calls curl_slist_free_all( pSlist ) and sets pSlist to 0.

CurlFormAdd( ByRef pFirstItem, ByRef pLastItem, Option1, Value1, Option2 = 0, Value2 = 0, ........, Option8 = 0, Value8 = 0 )
Returns curl_formadd( &pFirstItem, &pLastItem, Option1, Value1, Option2, Value2, ........, Option8, Value8 ). Non-numeric strings are automatically handled correctly. Numeric strings or user-inputted strings should be passed as an address (& operator). If this is the first call and is supposed to initialize the form, you should set pFirstItem and pLastItem to 0 prior to calling this function.
You can use CurlEasyDefineOptions() to define the CURLFORM options as variables for easier use of this function.
Note: curl_formadd() is not limited to 8 options. Writing more options into this function and increasing the string conversion loop will allow more.

CurlFormFree( pFirstItem )
Calls curl_formfree( pFirstItem ).

CurlEasyPerform( EasyHandle )
Returns curl_easy_perform( EasyHandle ).

CurlEasyGetinfo( EasyHandle, Information )
Returns the output of curl_easy_getinfo( EasyHandle, Information, Ouput ). The function automatically manages the interpretation of the output.

CurlEasyStrError( ErrorCode )
Returns curl_easy_strerror( ErrorCode ).

CurlEasyEscape( EasyHandle, URL )
Returns curl_easy_escape( EasyHandle, URL ) through CurlFreeGet().

CurlEasyUnescape( EasyHandle, URL )
Returns curl_easy_unescape( EasyHandle, URL ) through CurlFreeGet().

CurlVersion()
Returns curl_version().

CurlFreeGet( pString )
Some libcurl functions that return a string say that you should use curl_free() to delete it when you're done with it. This function copies the string at the address specified in pString, calls curl_free( pString ), and returns the copy. It is used internally by other wrapper functions.

MergeDouble( l, h )
Merges the low and high parts of a "Double" together and returns it. Useful for CURLOPT_PROGRESSFUNCTION.

CurlGetInfoType( Information )
Returns the data type of a CURLINFO option. It is used internally by other wrapper functions.

CurlGetInfoDefine( All = true )
Defines variables to match the CURLINFO C constants. If All is false, it will only define the data types.

CurlEasyGetOptionType( Option )
Returns the CURLOPTTYPE of a CURLOPT option.

CurlEasyDefineOptions( All = true )
Defines variables to match the CURLOPTTYPE C constants and CURL_ERROR_SIZE. If All is true, it will also define the CURLFORM and CURLOPT constants.

Error Details:

libcurl gives error #27 "Out of memory" with the message "failed creating formpost data." With some debugging, I was able to trace the failure point in the libcurl code.

In libcurl_imageshacktest.ahk libcurl fails in the internal function Curl_getFormData when it hits this:
Code:
    result = AddFormDataf(&form, &size, "\"");
    if (result)
      break;
(Near line 1150 in formdata.c)
It seems to be passing in a huge value for size, which causes the memory allocation error inside of it. I also recall seeing a string filled with binary.
This apparently indicates that there's a bad pointer somewhere, but I wasn't able to find anything in my code.

Converting from cURL to libcurl

cURL provides the option "--libcurl" which will write out the equivalent libcurl C code.
Quote:
--libcurl <file>
Append this option to any ordinary curl command line, and you will get a libcurl-using source code written to the file that does the equivalent operation of what your command line operation does!

NOTE: this does not properly support -F and the sending of multipart formposts, so in those cases the output program will be missing necessary calls to curl_formadd(3), and possibly more.

If this option is used several times, the last given file name will be used. (Added in 7.16.1)

You can either use the resulting code as a reference for using the AHK wrapper or convert the code and use the program as-is.
_________________


Last edited by DeathByNukes on Wed May 21, 2008 6:11 am; edited 5 times in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address MSN Messenger
n-l-i-d
Guest





PostPosted: Tue May 20, 2008 10:17 pm    Post subject: Reply with quote

Impressive! Smile

Quote:
; YEA, WUT NAO?


Laughing

Your error sounds like you forgot to zero terminate something.
Back to top
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Tue May 20, 2008 10:20 pm    Post subject: Reply with quote

Thx for this !
_________________
Back to top
View user's profile Send private message MSN Messenger
k3ph



Joined: 21 Jul 2006
Posts: 123

PostPosted: Tue May 20, 2008 10:32 pm    Post subject: Reply with quote

huzzah! thanks for this, im going to test it asap Wink

oh yea, can you provide your libeay32.dll? i want to use with the libcurl.dll provided.


Last edited by k3ph on Wed May 21, 2008 6:20 pm; edited 5 times in total
Back to top
View user's profile Send private message
nonov
Guest





PostPosted: Wed May 21, 2008 5:29 am    Post subject: Reply with quote

THANK YOU SO MUCH THIS WILL BE POPULAR !
Back to top
DeathByNukes



Joined: 25 Mar 2007
Posts: 14
Location: Mabase

PostPosted: Wed May 21, 2008 5:55 am    Post subject: Reply with quote

k3ph wrote:
oh yea, can you provide your libeay32.dll? i want to use with the libcurl.dll provided.

question: how can I follow a post data using -Ld parameters?
Code:
curl -Ld "BUTTON_INPUT=Restart%20Cable%20Modem" http://192.168.100.1/configdata.html

reference:
Quote:
; -L/--location Follow Location: hints (H)
; -d/--data <data> HTTP POST data (H)


how can I make it work?

Code:
URL = http://192.168.100.1/configdata.html
POST = BUTTON_INPUT=Restart%20Cable%20Modem

CurlEasySetOption( hCurlEasy, CURLOPT_URL, &URL )
CurlEasySetOption( hCurlEasy, CURLOPT_FOLLOWLOCATION, 0 )
CurlEasySetOption( hCurlEasy, CURLOPT_HTTPPOST, &POST )

CurlEasyCleanup( hCurlEasy )
CurlFreeLibrary()
return


Ah, sorry about that. You can either download SSL here or get the version that doesn't require it. I've edited this into the top post as well.

As for that script, shouldn't CURLOPT_FOLLOWLOCATION be set to 1 to enable it? Also, you need to call CurlEasyPerform( hCurlEasy ) to actually begin the transfer.
I'm not sure if it'll work though because of the current bug in doing a POST.
_________________
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address MSN Messenger
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Wed May 21, 2008 9:59 am    Post subject: Reply with quote

Cool, it is nicer than running cURL on the command line for each operation...
I will keep this library in mind next time I need to do some high level Internet access.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
k3ph



Joined: 21 Jul 2006
Posts: 123

PostPosted: Wed May 21, 2008 6:23 pm    Post subject: Reply with quote

OOOOOOOO thank you so much, with more 3 tries I could run what i've wanted!

CURLOPT_POSTFIELDSIZE_LARGE is mandatory or it will keep waiting for it
Back to top
View user's profile Send private message
heresy



Joined: 11 Mar 2008
Posts: 291

PostPosted: Sun May 25, 2008 5:07 am    Post subject: Reply with quote

thanks for sharing this.
i was having inconvenience on handling curl at all
this will be my another favorite one!
*scraps
_________________
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group