Skip to content

Instantly share code, notes, and snippets.

@CaptainPRICE
Last active May 22, 2019 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CaptainPRICE/e1cea02f2ab2a4ae24b700f9b238f4b8 to your computer and use it in GitHub Desktop.
Save CaptainPRICE/e1cea02f2ab2a4ae24b700f9b238f4b8 to your computer and use it in GitHub Desktop.

API draft (rev. 2)

See proposal here.
tldr: This document is unofficial until finally revised by Garry's Mod development team!

Status: See response from @robotboy655.

This is a preview API draft of new functionality for HTTP requests in Garry's Mod Lua.
Everything presented in this document is a subject to change without any notice.
There is a possibility of being unaccepted and/or altered by devs. For example:

  • Only partial functions may be implemented.
  • Function/Class name may be different in the final revision.

Some parts in this document are marked using tags to help distinguish between old/new stuff. Legend:

  • [N]: New functionality.
  • [U]: Functionality that could be user-implemented in the current game version.
  • [X]: Won't add (confirmed).
  • [Q]: User questions.
  • [T]: User hints/tips.

HTTP_ (enum) [N]

Enumeration to be used via HttpFile.GetMethod and HttpFile.SetMethod functions.
Representing HTTP request methods.

HTTP_GET

Value: "GET"
The HTTP GET method requests a representation of the specified resource. Requests using GET should only retrieve data.

HTTP_POST

Value: "POST"
The HTTP POST method sends data to the server. The type of the body of the request is indicated by the Content-Type header.

HTTP_HEAD

Value: "HEAD"
The HTTP HEAD method requests the headers that are returned if the specified resource would be requested with an HTTP GET method. Such a request can be done before deciding to download a large resource to save bandwidth, for example.

HTTP_PUT

Value: "PUT"
The HTTP PUT request method creates a new resource or replaces a representation of the target resource with the request payload.

HTTP_DELETE

Value: "DELETE"
The HTTP DELETE request method deletes the specified resource.

HTTP_PATCH

Value: "PATCH"
The HTTP PATCH request method applies partial modifications to a resource.

HTTP_OPTIONS

Value: "OPTIONS"
The HTTP OPTIONS method is used to describe the communication options for the target resource. The client can specify a URL for the OPTIONS method, or an asterisk (*) to refer to the entire server.

HttpFile (class) [N]

An object to represent and also perform HTTP requests.

HttpFile(HTTPRequest request=nil) (constructor)

Creates a HttpFile object. Optionally allows to initialize an object with HTTPRequest values.

string GetMethod()

Gets the request method. See also HTTP_ (enum).
[T] It would be better to use an enum instead of plain string in your code.

void SetMethod(string method)

Sets the request method.

  1. method: Specify the HTTP request method, the string is case-insensitive. For possible values refer to the HTTP_ (enum).

[T] It would be better to use an enum instead of plain string in your code.

string GetURL()

Gets the target URL.

void SetURL(string url)

Sets the target URL.

table GetParameters()

Gets the request parameters (key-value).

void SetParameters(table parameters)

Sets the request parameters (key-value). This is only applicable to the following request methods:

table GetHeaders()

Gets the request headers (key-value).

void SetHeaders(table headers)

Sets the request headers (key-value).

string GetBody()

Gets the request body string for POST data.

[Q] Is this function really necessary, can't it be retrieved using request headers? (If not, why does it exist? Convenience function?)

void SetBody(string body, string type="text/plain; charset=utf-8")

Sets the request body string for POST data. If set, will override request parameters.
You can obtain a value of charset by calling the GetHeaders function.

  1. body: Body string for POST data.
  2. type: Content type for body.

[Q] Is this function really necessary, can't these be done using request headers (SetHeaders)? (If not, why does it exist? Convenience function?)

table GetCompletionCallbacks() [U]

Returns a table of all completion callbacks (sequence of functions to be called once a request is completed).
A direct reference to the internal table, so you are allowed to reorder callbacks too, by using table.sort function.

void AddCompletionCallback(function callback, string identifier=nil) [U]

Adds the completion callback (a function to be called once this request is completed, ragardless of fail/success).

  1. callback has the following function signature:
  1. HTTPResponse: The response object.
  1. identifier: Optional. If specified, it can be used to remove the callback with RemoveCompletionCallback function; otherwise, the callback is linked and unremovable.

boolean RemoveCompletionCallback(string identifier) [U]

Removes the completion callback. See also AddCompletionCallback function.

Returns true to indicate a success.

  1. identifier: String identifier of the completion callback to be removed.

table GetProgressCallbacks() [N]

Returns a table of all progress-report callbacks (sequence of functions to be called whenever a network change occurs in this request).
A direct reference to the internal table, so you are allowed to reorder callbacks too, by using table.sort function.

void AddProgressCallback(function callback, string identifier=nil) [N]

Adds the progress-report callback (a function to be called each time there is a network change in this request).

  1. callback has the following function signature:
  1. number: Transfer rate (download/upload speed in bytes-per-second).
  2. number: Downloaded/Uploaded file-size so far (in bytes).
  3. number: Total file-size (in bytes). May be nil if size can not be determined (i.e. when request is returning chunked-data).
  4. number: Estimated time left (remaining time to completion in seconds). May be nil if total size can not be determined (i.e. when request is returning chunked-data).
  1. identifier: Optional. If specified, it can be used to remove the callback with RemoveProgressCallback function; otherwise, the callback is linked and unremovable.

boolean RemoveProgressCallback(string identifier) [N]

Removes the progress-report callback. See also AddProgressCallback function.

  1. identifier: String identifier of the progress-report callback to be removed.

boolean IsCompleted() [U]

Returns true to indicate if this HTTP request has been completed.

boolean IsStarted() [U]

Returns true to indicate if this HTTP request is in-progress. (Note: This is not the same as not HttpFile:IsPaused()!)

boolean IsPaused() [X]

Returns true to indicate if this HTTP request is currently paused.

boolean CanResume() [X]

Returns true to indicate resume capability, if this HTTP request can be resumed successfully.

boolean Start()

Starts this HTTP request.
Returns true to indicate success, this HTTP request has started; otherwise, false.

boolean Pause() [X]

Pauses this HTTP request.
Returns true to indicate success, this HTTP request has been paused; otherwise, false.

boolean Stop() [N]

Stops this HTTP request.
Returns true to indicate success, this HTTP request has been stopped completely (loses all made progress); otherwise, false.

boolean Restart() [N]

Restarts this HTTP request. (Convenience function.)
Returns true to indicate success, this HTTP request has been restarted (stops and starts again); otherwise, false.

boolean Defer() [N]

Defers this HTTP request (only when in-progress), by moving it at the back of the queue.
Returns true if this request has been successfully deferred; otherwise, false.

boolean Prioritize() [N]

Prioritizes this HTTP request (only when in-progress), by moving it at the front of the queue.
Returns true if this request has been successfully prioritized; otherwise, false.

HTTPResponse (struct) [N]

The structure returned via completion callback at HttpFile.AddCompletionCallback.

HttpFile Request

Returns the HTTP request object.
This is unnecessary. If needed, it can be retrieved by using an upvalue of the request object.

boolean Success

Returns true if HTTP request were completed successfully; otherwise, false.

number StatusCode

Returns the HTTP response status code, indicating whether the HTTP request has been successfully completed.

[Q] It might be wise to implement enum for this?

string Body

Returns the HTTP response body string for a successful HTTP request; otherwise, a reason of failure.

table Headers

Returns the HTTP response headers (key-value) for a successful HTTP request; otherwise, nil.

Example Usage

Simple queue

Demonstrates how to queue HTTP requests using HttpFile, and also print out their progress.

local function printf( ... ) MsgN( string.format( ... ) ) end

-- Feed this table with HTTPRequest tables. See https://wiki.garrysmod.com/page/Structures/HTTPRequest
-- Note: 'failed' and 'success' functions (if used) would be combined into an appropriate completion callback (internally).
local queue = {
    {
        method  = HTTP_GET;
        url     = 'https://facepunch.com/';
        success =
            function( code, body, headers )
                printf( '[HTTP GET request to https://facepunch.com/] Legacy completion callback (success). Status code: #%d. Body length: %d. Headers:', code, #body )
                PrintTable( headers, 1 )
            end;
        failed =
            function( reason )
                printf( '[HTTP GET request to https://facepunch.com/] Legacy completion callback (failed). Reason: %q', reason )
            end;
    };
    {
        method = HTTP_GET;
        url    = 'https://wiki.garrysmod.com/page/Main_Page';
    };
}

-- Generic/Shared completion callback for queued HTTP requests.
local function CCB( request, response )
    if response.Success then
        printf( '[HTTP %s request to %q] Completion callback (success). Status code: #%d. Body length: %d. Headers:', request:GetMethod( ), request:GetURL( ), response.StatusCode, #response.Body )
        PrintTable( response.Headers, 1 )
    else
        printf( '[HTTP %s request to %q] Completion callback (failed). Status code: #%d. Reason: %q', request:GetMethod( ), request:GetURL( ), response.StatusCode, response.Body )
    end
end

-- Generic/Shared progress-report callback for queued HTTP requests.
local function PRCB( request, transferRate, currentSize, totalSize, eta )
    printf( '[HTTP %s request to %q] Speed: %.2f B/s, Size: %.2f B, Total size: %.2f B, ETA: %d second(s)', request:GetMethod( ), request:GetURL( ), transferRate, currentSize, totalSize or 'N/A', eta or 'N/A' )
end

-- A helper function to rewrite function 'f' to provide 'arg' upon call.
-- Used to rewrite generic functions above, to provide the request (HttpFile) object as the first argument.
local function Re( arg, f )
    return function( ... ) return f( arg, ... ) end
end

-- Process queue.
for i, request in ipairs( queue ) do
    local req = HttpFile( request )             -- Create a new HttpFile object, and initialize it using the given HTTPRequest table values.
    req:AddCompletionCallback( Re( req, CCB ) ) -- Add a completion callback, to be notified upon completion of request.
    req:AddProgressCallback( Re( req, PRCB ) )  -- Add a progress-report callback, to be notified of new network change.
    if req:Start( ) then                        -- Attempt to initiate HTTP request.
        printf( '[#%d] HTTP %s request has been started, URL: %q', i, req:GetMethod( ), req:GetURL( ) )
    end
    queue[ i ] = req
end
@CaptainPRICE
Copy link
Author

CaptainPRICE commented May 19, 2019

Reserved.

I have fixed Markdown issues and updated 'Simple queue' example usage code.


Changelog

API rev. 2:

HttpFile

  • Removed 'Pause' functionality as it can not be added.
  • Added Defer() and Prioritize() functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment