sm-plugins/includes/webcon.inc
2017-02-26 00:16:12 +01:00

315 lines
12 KiB
SourcePawn

#if defined _webcon_included
#endinput
#endif
#define _webcon_included
#define WEB_CLIENT_ADDRESS_LENGTH 46
//const char WebMethod_Connect[] = "CONNECT";
//const char WebMethod_Delete[] = "DELETE";
//const char WebMethod_Get[] = "GET";
//const char WebMethod_Head[] = "HEAD";
//const char WebMethod_Options[] = "OPTIONS";
//const char WebMethod_Post[] = "POST";
//const char WebMethod_Put[] = "PUT";
//const char WebMethod_Patch[] = "PATCH";
//const char WebMethod_Trace[] = "TRACE";
#define WebMethod_Connect "CONNECT"
#define WebMethod_Delete "DELETE"
#define WebMethod_Get "GET"
#define WebMethod_Head "HEAD"
#define WebMethod_Options "OPTIONS"
#define WebMethod_Post "POST"
#define WebMethod_Put "PUT"
#define WebMethod_Patch "PATCH"
#define WebMethod_Trace "TRACE"
enum WebStatus
{
WebStatus_Continue = 100,
WebStatus_SwitchingProtocols = 101,
WebStatus_Processing = 102,
WebStatus_OK = 200,
WebStatus_Created = 201,
WebStatus_Accepted = 202,
WebStatus_NonAuthoritativeInformation = 203,
WebStatus_NoContent = 204,
WebStatus_ResetContent = 205,
WebStatus_PartialContent = 206,
WebStatus_MultiStatus = 207,
WebStatus_MultipleChoices = 300,
WebStatus_MovedPermanently = 301,
WebStatus_Found = 302,
WebStatus_SeeOther = 303,
WebStatus_NotModified = 304,
WebStatus_UseProxy = 305,
WebStatus_SwitchProxy = 306,
WebStatus_TemporaryRedirect = 307,
WebStatus_BadRequest = 400,
WebStatus_Unauthorized = 401,
WebStatus_PaymentRequired = 402,
WebStatus_Forbidden = 403,
WebStatus_NotFound = 404,
WebStatus_MethodNotAllowed = 405,
WebStatus_NotAcceptable = 406,
WebStatus_ProxyAuthenticationRequired = 407,
WebStatus_RequestTimeout = 408,
WebStatus_Conflict = 409,
WebStatus_Gone = 410,
WebStatus_LengthRequired = 411,
WebStatus_PreconditionFailed = 412,
WebStatus_RequestEntityTooLarge = 413,
WebStatus_RequestUriTooLong = 414,
WebStatus_UnsupportedMediaType = 415,
WebStatus_RequestedRangeNotSatisfiable = 416,
WebStatus_ExpectationFailed = 417,
WebStatus_UnprocessableEntity = 422,
WebStatus_Locked = 423,
WebStatus_FailedDependency = 424,
WebStatus_UnorderedCollection = 425,
WebStatus_UpgradeRequired = 426,
WebStatus_NoResponse = 444,
WebStatus_RetryWith = 449,
WebStatus_BlockedByWindowsParentalControls = 450,
WebStatus_UnavailableForLegalReasons = 451,
WebStatus_InternalServerError = 500,
WebStatus_NotImplemented = 501,
WebStatus_BadGateway = 502,
WebStatus_ServiceUnavailable = 503,
WebStatus_GatewayTimeout = 504,
WebStatus_HttpVersionNotSupported = 505,
WebStatus_VariantAlsoNegotiates = 506,
WebStatus_InsufficientStorage = 507,
WebStatus_BandwidthLimitExceeded = 509,
WebStatus_NotExtended = 510,
}
#define WebHeader_Accept "Accept"
#define WebHeader_AcceptCharset "Accept-Charset"
#define WebHeader_AcceptEncoding "Accept-Encoding"
#define WebHeader_AcceptLanguage "Accept-Language"
#define WebHeader_AcceptRanges "Accept-Ranges"
#define WebHeader_Age "Age"
#define WebHeader_Allow "Allow"
#define WebHeader_Authorization "Authorization"
#define WebHeader_CacheControl "Cache-Control"
#define WebHeader_Connection "Connection"
#define WebHeader_ContentEncoding "Content-Encoding"
#define WebHeader_ContentLanguage "Content-Language"
#define WebHeader_ContentLength "Content-Length"
#define WebHeader_ContentLocation "Content-Location"
#define WebHeader_ContentMD5 "Content-MD5"
#define WebHeader_ContentRange "Content-Range"
#define WebHeader_ContentType "Content-Type"
#define WebHeader_Cookie "Cookie"
#define WebHeader_Date "Date"
#define WebHeader_ETag "ETag"
#define WebHeader_Expect "Expect"
#define WebHeader_Expires "Expires"
#define WebHeader_From "From"
#define WebHeader_Host "Host"
#define WebHeader_IfMatch "If-Match"
#define WebHeader_IfModifiedSince "If-Modified-Since"
#define WebHeader_IfNoneMatch "If-None-Match"
#define WebHeader_IfRange "If-Range"
#define WebHeader_IfUnmodifiedSince "If-Unmodified-Since"
#define WebHeader_LastModified "Last-Modified"
#define WebHeader_Location "Location"
#define WebHeader_MaxForwards "Max-Forwards"
#define WebHeader_Pragma "Pragma"
#define WebHeader_ProxyAuthenticate "Proxy-Authenticate"
#define WebHeader_ProxyAuthorization "Proxy-Authorization"
#define WebHeader_Range "Range"
#define WebHeader_Referer "Referer"
#define WebHeader_RetryAfter "Retry-After"
#define WebHeader_Server "Server"
#define WebHeader_SetCookie "Set-Cookie"
#define WebHeader_SetCookie2 "Set-Cookie2"
#define WebHeader_TE "TE"
#define WebHeader_Trailer "Trailer"
#define WebHeader_TransferEncoding "Transfer-Encoding"
#define WebHeader_Upgrade "Upgrade"
#define WebHeader_UserAgent "User-Agent"
#define WebHeader_Vary "Vary"
#define WebHeader_Via "Via"
#define WebHeader_Warning "Warning"
#define WebHeader_WWWAuthenticate "WWW-Authenticate"
#define WebHeader_AccessControlAllowOrigin "Access-Control-Allow-Origin"
enum WebRequestDataType
{
WebRequestDataType_Get,
WebRequestDataType_Post,
WebRequestDataType_Cookie,
WebRequestDataType_Header,
}
methodmap WebResponse < Handle
{
/// Add a HTTP header to a response.
///
/// Multiple instances of the same header can be added to a response with different values.
/// This is only valid if the header is specified as a list, but the restriction is not enforced.
///
/// @param header Name of HTTP header to add. `WebHeader_*` constants exist for standard headers.
/// @param content Value to send in response for this header.
/// @return `true` if the header was sucessfully added, `false` otherwise.
public native bool AddHeader(const char[] header, const char[] content);
/// Remove an added HTTP header from a response.
///
/// @param header Name of HTTP header to remove. `WebHeader_*` constants exist for standard headers.
/// @param content If specified, only remove a header matching this value.
/// @return `true` if any headers were removed, `false` otherwise.
public native bool RemoveHeader(const char[] header, const char[] content = NULL_STRING);
};
methodmap WebStringResponse < WebResponse
{
/// Create a WebResponse from a character string.
///
/// The response length is determined automatically and thus is not binary-safe.
/// Use `WebBinaryResponse` for binary data.
///
/// @param content Content to use for response.
/// @return A new WebResponse instance with the specified content as the body.
public native WebStringResponse(const char[] content);
};
methodmap WebBinaryResponse < WebResponse
{
/// Create a WebResponse from binary data.
///
/// @param content Content to use for response.
/// @param length Length of content.
/// @return A new WebResponse instance with the specified content as the body.
public native WebBinaryResponse(const char[] content, int length);
};
methodmap WebFileResponse < WebResponse
{
/// Create a WebResponse from a file path.
///
/// This uses efficient kernel data transfer mechanisms where available, and avoids
/// reading the entire file into memory at once (or when not being sent to a client).
///
/// @param path Path to response file. Should be constructed using `BuildPath`.
/// @return A new WebResponse instance with the specified file content as the body.
/// @error Unable to open file path for reading.
public native WebFileResponse(const char[] path);
};
typeset WebBodyDataReceived
{
/// Callback for request body.
///
/// @param connection WebConnection handle for the request. Must not be deleted.
/// @param data Raw request body data OR "" if `data_in_cb` = false.
/// @param length Size of `data`.
/// @param data1 Optional user data 1.
/// @param data2 Optional user data 2.
/// @return `true` if the request was handled, `false` will terminate the connection.
function bool(WebConnection connection, char[] data, int length);
function bool(WebConnection connection, char[] data, int length, any data1);
function bool(WebConnection connection, char[] data, int length, any data1, any data2);
};
methodmap WebConnection < Handle
{
/// Get the remote client IP address.
///
/// @param buffer Buffer to store the address in. Should be `WEB_CLIENT_ADDRESS_LENGTH` bytes in size.
/// @param length Size of `buffer`.
/// @return `true` if the client address was stored in `buffer`, `false` otherwise.
public native bool GetClientAddress(char[] buffer, int length);
/// Get the length of the string that would be returned by GetRequestData().
///
/// @param key Paramater (GET or POST), Cookie, or Header to get data from.
/// @return int the size in bytes.
/// @error ParseRequestBody was not called for POST data.
public native int GetRequestDataLength(WebRequestDataType type, const char[] key);
/// Get data sent by the client in the request.
/// Retrieving data from the body (aka. POST) will only work after ParseRequestBody() has been run.
///
/// @param type Source of data. See `WebRequestDataType` for details.
/// @param key Paramater (GET or POST), Cookie, or Header to get data from.
/// @param buffer Buffer to store the data value in.
/// @param length Size of `buffer`.
/// @return `true` if the data exists in the request and was stored in `buffer`, `false` otherwise.
/// @error ParseRequestBody was not called for POST data.
public native bool GetRequestData(WebRequestDataType type, const char[] key, char[] buffer, int length);
/// Load full request body into memory and call `callback` when done.
///
/// @param callback WebBodyDataReceived callback that will be called when request body has been loaded.
/// @param data1 Optional user data 1.
/// @param data2 Optional user data 2.
/// @param data_in_cb Pass body through callback if true.
/// @return `true` on success
/// @error Function called more than once.
public native bool ReadRequestBody(WebBodyDataReceived callback, any data1 = 0, any data2 = 0, bool data_in_cb = true);
/// Get request body, or part of, into buffer.
///
/// @param start Start index in request body.
/// @param buffer Target buffer.
/// @param length Target buffer size.
/// @return `true` on success
/// @error Start exceeds data size.
public native bool GetRequestBody(int start, char[] buffer, int length);
/// Detect endcoding of request body and parse into hashtable for use with GetRequestData.
/// Supports: "application/x-www-form-urlencoded", "multipart/form-data"
///
/// @return `true` on success
/// @error ReadRequestBody() not called first. Function called twice.
public native bool ParseRequestBody();
/// Queue a response to send to the client.
///
/// @param status HTTP status code to use for response. See `WebStatus`.
/// @param response WebResonse to queue. You are responsible for deleting the response.
/// @return `true` if the response was successfully queued, `false` otherwise.
/// @error Invalid response handle.
public native bool QueueResponse(WebStatus status, WebResponse response);
};
/// Callback for incoming requests.
///
/// @param connection WebConnection handle for the request. Must not be deleted.
/// @param method HTTP method used for request. `WebMethod_*` constants exist for standard methods.
/// @param url URL requested by client.
/// @return `true` if the request was handled, `false` will terminate the connection.
typedef WebRequestHandler = function bool (WebConnection connection, const char[] method, const char[] url);
/// Register a request handler.
///
/// @param id Unique identifier for request handler. Used for virtual hosting.
/// @param handler WebRequestHandler callback for incoming requests.
/// @param name Optional name for handler on index page.
/// @param description Optional description for handler on index page.
/// @return `true` if the handler was sucessfully registered, `false` otherwise.
native bool Web_RegisterRequestHandler(const char[] id, WebRequestHandler handler, const char[] name = "", const char[] description = "");
public Extension __ext_Webcon =
{
name = "Webcon",
file = "webcon.ext",
#if defined AUTOLOAD_EXTENSIONS
autoload = 1,
#else
autoload = 0,
#endif
#if defined REQUIRE_EXTENSIONS
required = 1,
#else
required = 0,
#endif
}