 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
DeathByNukes
Joined: 25 Mar 2007 Posts: 14 Location: Mabase
|
Posted: Tue May 20, 2008 9:25 pm Post subject: libcurl Wrapper (WIP) |
|
|
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 |
|
 |
n-l-i-d Guest
|
Posted: Tue May 20, 2008 10:17 pm Post subject: |
|
|
Impressive!
Your error sounds like you forgot to zero terminate something. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Tue May 20, 2008 10:20 pm Post subject: |
|
|
Thx for this ! _________________
 |
|
| Back to top |
|
 |
k3ph
Joined: 21 Jul 2006 Posts: 123
|
Posted: Tue May 20, 2008 10:32 pm Post subject: |
|
|
huzzah! thanks for this, im going to test it asap
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 |
|
 |
nonov Guest
|
Posted: Wed May 21, 2008 5:29 am Post subject: |
|
|
| THANK YOU SO MUCH THIS WILL BE POPULAR ! |
|
| Back to top |
|
 |
DeathByNukes
Joined: 25 Mar 2007 Posts: 14 Location: Mabase
|
Posted: Wed May 21, 2008 5:55 am Post subject: |
|
|
| 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 |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Wed May 21, 2008 9:59 am Post subject: |
|
|
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 |
|
 |
k3ph
Joined: 21 Jul 2006 Posts: 123
|
Posted: Wed May 21, 2008 6:23 pm Post subject: |
|
|
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 |
|
 |
heresy
Joined: 11 Mar 2008 Posts: 291
|
Posted: Sun May 25, 2008 5:07 am Post subject: |
|
|
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 |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|