Skip to content

Releases: Qriist/LibQurl

LibQurl v1.2.0

09 Nov 06:00

Choose a tag to compare

This update features a slew of enhancements and fixes primarily aimed at smoothing API interactions.

  • Added DecodeJwt() to return an unobfuscated Map of the input JWT token.
  • DecodeBase64() accepts a third parameter to mark the input as Base64URL, which will do a couple extra pre-transformations before decoding as Base64.
  • Timestamp() now accepts a parameter to return multiple common internet standard formats.
    • Acceptable paramaters: Readable, SQL, ODBC, RFC 3339, Unix, asctime, RFC 1123, RFC 2822, FILETIME, EXIF, and RFC 850. See that method for output examples.
  • SetPost() now returns the input's mimetype. This is useful for persnickety servers demanding an exact Content-Type to be reported in the headers.
    • Due to a behavioral quirk in libmagic, json data examined in memory is reported as text/plain. However, since passing an Object/Map/Array always results in a dumped json being staged, there is a specific override for that group which returns application/json.
  • SetPost() now explicitly sets CUSTOMREQUEST to POST. This fixed a bug where POSTs would fail after GETs were sent after POSTs were sent.
    • ...yeah that was as dumb as you might imagine to track down.
  • Fixed SetPost() unintentionally assigning POST data to the default handle
  • ClearPost() now also zeros libcurl's UPLOAD flag.
  • ClearPost() now explicitly sets CUSTOMREQUEST to GET for more intuitive behavior in mixed-request usage.

LibQurl v1.1.1

24 Oct 03:08

Choose a tag to compare

Fixed a dependency typo that affected fresh installs (but not upgrades) of the library.

LibQurl v1.1.0

06 Oct 18:35

Choose a tag to compare

Just a small update today. This version includes one new wrapped function introduced in the latest libcurl as well as enhanced error handling.

  • Added GetMultiInfo() for gathering basic job stats on a given multi_handle.
  • Added error handling to all dll calls to around ~30 core functions. Many already had this handling but now they all do!
    • As a reminder, an info snapshot of any discovered errors are pushed into the curl.caughtErrors array.
  • Fixed an improperly set callback variable for file uploads in SetPost().
  • Fixed an incorrect easy_handle lookup in AttachMimeAsPart().

The error handling in particular should be useful in a production project as there's an enormous amount of program state information captured whenever libcurl flags an issue.

LibQurl v1.0.0

05 Aug 23:24

Choose a tag to compare

This version sees a whole slew of enhancements that include better MIME tracking, websocket interactions, and the option to enable libcurl's debug data. In fact, nearly the entirety of libcurl has now been wrapped! More on that after the patch notes.

  • Added GetMimeType() for identifying the mime type of any arbitrary input. This is the same text string that would be auto-sent as part of a mime upload, exposed as a one-shot operation.
  • Added tracking for nested mime_handles.
  • Added better tracking for mime_parts, including when that part is a nested mime_handle.
  • Using MimeCleanup() on a nested mime_handle will return now harmlessly.
  • Added GetOpt(), MultiGetOpt(), and ShareOpt() to return whatever LibQurl is tracking for the given option on a given handle.
    • Options that haven't yet been set will return a Null type instead of unset. This is to simplify Type() checks and error handling when querying tracked data.
  • Added ExportSSLs() and ImportSSLs()
  • Added EnableDebug() to enable verbose logging on the given easy_handle.
  • Use PollDebug() to get a formated report of debug data.
    • Body and ssl data is currently filtered from the report. I'll enhance the handling if somebody has a need for it.
  • Added ConfigureDebug() to set the verbosity level of the debug report. This can be called either before or after EnableDebug(), but must be called before any transfers have been intiated.
  • Added Timestamp() to get a pre-formatted, sortable UTC timestamp.
    • Example: 2025-07-27 15:36:07.746
  • Added WebSocketConvert() to convert a given easy_handle to a websocket connection.
  • Added WebSocketSend() and WebSocketRecieve() for handling websocket data. As usual, pretty much all of AHK's normal data types are acceptable inputs.
    • These are both explicitly synchronous operations. Their underlying operations are a little different because they do not use the write callback provided to curl_easy_perform.
    • Additionally, the websocket functions were particularly fickle to wrap. Please be sure to provide feedback if something breaks as I do not have a good use case to test against.
  • Added SetWebSocketFrameSize() to have the library automatically split large outgoing frames of data into as many partial frames as required to send the entire input. The threshold is set per easy_handle and defaults to 14kb.
    • Note that the full un-split size is reported in the first partial frame, and some servers will still use that to reject uploads above a given size threshold. It is on the user to understand the constraints of the system they are connecting to.
  • Added the initMemMap optional parameter. If set, this map will be used to pass advanced usage callback pointers to curl's loading routine.
    • I recommend not setting initMemMap unless you know what you're doing.
  • Removed SetOpts() as there's just way too many options (300+) to try to account for, each with different types of returns and varied processing exceptions. I'd be fighting the design of everything else I've written to try to make it work.
  • While not used by LibQurl itself, curl.exe is now included alongside the rest of the generated binaries as it will make errors related to a specific version easier to track down.
  • Fixed an incorrect parameter name in the GetInfo signature.

As I said above, almost all of libcurl has now been tended to; there's only two more sections of code worth wrapping. Both of those may or may not happen for similar reasons.

The first is the pair of pushheader functions. While parsing the function data would be easy enough, these require a public (read: accessible) persistent remote server connection that also sends push requests on command. Without that, I can't write sensible logic. Put simply, I don't have a test case to build against.

The second set of functions is the multi_socket system. Implementing the self-driving timer mechanisms shouldn't be overly difficult and I plan to eventually upgrade LibQurl's current multi interface to use it. (Or, at least, offer that mode alongside what's now available.) However, as with the pushheader dilemma, the more advanced functionality of merging and driving user-provided sockets with those generated by libcurl is off the table until I have a test case to build a sensible implementation against. Some local testing of the current Async() implementation has revealed that it scales to at least 250 concurrent transfers without a significant drop in performance - plenty performant for virtually everything except the most demanding servers.

With those caveats in mind, I don't anticipate any major LibQurl interface changes from here on out, so I feel comfortable bumping to a full production-worthy version.

Lastly, a couple additional notes about what's coming up next.

There's already error handling on the most important parts of the library, but I intended to enhance the coverage so that LibQurl gives a full proper trace where ever something gets invoked. I also want to put a little effort into eliminating unneccesarry pointer chasing during the various callback routines since I know for sure there's a bit of optimization to be gained there after some slight refactoring.

As both of these are sweeping under-the-hood enhancements with no immediately discernable effect on the library's operations, I felt it reasonable enough to get this release out first.

LibQurl v0.94.0

25 Apr 18:33

Choose a tag to compare

There are two main features in this update, both of which deal directly with the handling of transfer data.

  • Enabled proper chunked uploads with SetPost(), meaning large file transfers don't need to reside entirely in memory for the duration of the upload.
    • MIME uploads already did this natively but libcurl required building a custom callback function for basic POSTs for some reason.
  • Added WriteToMagic() for file downloads. This is a hybrid mode that starts out identical to WriteToMem() but will automagically flush to disk and act as WriteToFile() when a defined size threshold is reached.
    • The default flush threshold is 50mb. The method's first parameter adjusts to whatever size is provided.
    • Any flushed files get saved to A_Temp "\LibQurl\" with a name based on timestamp and file handle. All temp files are deleted when the class goes through its exit routine, though its (hopefully) designed so that multiple running scripts won't interfere with each other's temp files.
    • For plain text, GetLastBody() handles this new method without any implementation modifications. If you need to work with binary data from this method, use Type(curl.GetLastBody("Object")) to determine if you should use Buffer or File calls.
    • My personal intended use case of the Magic mode is with REST APIs that don't paginate bulk requests. This provides the speed benefits of Memory mode while protecting the script (and system) against unpredictable payload size spikes.
  • Several major improvements to the build script, including integrating it into the release generation script.

LibQurl v0.93.0

18 Apr 06:01

Choose a tag to compare

This release mainly sees quality of life enhancements to dealing with transfer data.

  • Added EncodeBase64()/DecodeBase64() methods
    • EncodeBase64() will accept all the usual inputs to output a Base64 string
    • DecodeBase64() returns a decoded string by default, or an optional raw buffer
  • Added GetLastStatus() to quickly check an easy_handle's last HTTP status code
  • Added real time progress checking methods
    • GetProgress() returns a Map with the raw byte values for further processing
    • The convenice methods DownloadPercent and UploadPercent will return the given easy_handle's completion% rounded to 2 decimals
  • Fixed 3 default assignments that were missed in the last release's mass change

LibQurl v0.92.0

07 Apr 08:17

Choose a tag to compare

Major breaking functionality change in this release: athough default handles are still created for ease of use, additional handles are no longer switched to automatically.

The reason for this is I discovered that there was a sort of scoping problem where AHK would treat different instances of the class as having the same pool of dll data, presumably because Windows only loads the dll once. Fortunately, curl and LibQurl are both well equipped to handle this behavior by defining different handle pools; the class just required a change to keep from stepping on itself.

Other enhancements and fixes include:

  • Wrapped libmagic for use in POST and MIME operations, eliminating the clunky commandline wrap
  • Added ClearPost() to properly yeet POST data from an easy_handle
  • Memory buffers now auto-expand as data comes in, instead of spawning with a fixed size
  • Allowed memory buffers to truncate to final download size (there were sometimes trailing binary zeroes)
  • Added StrCompare() to allow usage of libcurl's portable string comparison functions
  • removed a redundant string->buffer operation
  • removed a deprecated variable in EasyInit()

LibQurl v0.91.0

28 Jan 16:10

Choose a tag to compare

LibQurl v0.91.0 Pre-release
Pre-release

Small bugfix release.

  • Fixed two instances of an incorrect global declaration.
  • Yet another attempt at fixing autoload from common install patterns.

LibQurl v0.90.0

27 Dec 21:12

Choose a tag to compare

Added most of the rest of the MIME functions. These mostly focus on server-specified formatting requirements.

What's new in this release:

  • Added MimeTreatPartAsFile(). This tells the server that it should consider that mime_part as a file with the given file name.
  • Added AttachMimeAsPart(). This allows you to embed an entire other mime_handle as a single mime_part. Because there's no way to undo this action, LibQurl will stop tracking the embedded mime_handle and any subsequent calls to that mime_handle will throw an error. Also, using this function after using the embedded mime_handle in a transfer will fail; you have to rebuild the entire structure from scratch in order to embed.
  • Added MimePartEncoder()/SetMimePartHeaders(). These are difficult to get feedback on without a server specifically designed to echo these low-level aspects. While libcurl reports no error, I currently have no proper test case to verify against.
  • Allowed SetHeaders()/SetMimePartHeaders() and custom header inputs to also accept Objects (in addition to Arrays and Maps).

LibQurl v0.89.0

25 Dec 23:42

Choose a tag to compare

LibQurl v0.89.0 Pre-release
Pre-release

This update wraps the most important parts of curl's MIME api. Which is to say, those functions that are immediately required to push data. Read the patch notes carefully to understand how it works.

What's new in this release:

  • Added MimeInit(), which accepts (or defaults to) an easy_handle, and returns a mime_handle.
    • While EasyInit() creates some initial mime-related variables when called, MimeInit() is never called automatically due to how its mere inclusion modifies outgoing data. Thus, unlike with other handles, it is on the user to explicitly call MimeInit() to generate a default mime_handle.
    • Per curl's design, mime_handles are attached to that specific easy_handle for its lifetime. As such, a given mime_handle will only ever modify the easy_handle it was created with.
  • Added AttachMimePart() to add content to a mime_handle . This will create the mime_part, set its name, pass the partContent data to libcurl, auto-set the mimetype using magic numbers, and return the mime_part for further processing. The underlying methods are publicly available but their explicit use is discouraged to ensure consistency.
    • As with similar methods, you can pass almost anything for partContent: String, Integer, Object, Map, Array, Buffer, and FileObjects are all uploaded appropriately.
  • Added MimeCleanup(). This will safely close out the given mime_handle and all associated mime_parts.
  • Fixed finding the libcurl dll from an Aris installation.

NOTE: Incidentally, the magic numbers which determine mimetype come from a Windows build of Unix's file command. While this works flawlessly, it is somewhat inefficient because of the need to temporarily dump variables to disk (though FileObjects are unaffected). My intention is to come back at a later date and incorporate file's underlying library, libmagic. It's just low priority due to having a technically working solution.