/** * ----------------------------------------------------- * File request.inc * Authors David Ordnung * License GPLv3 * Web http://dordnung.de * ----------------------------------------------------- * * Copyright (C) 2013-2020 David Ordnung * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see */ #if defined _system2_request_included #endinput #endif #define _system2_request_included /** * * API for making HTTP and FTP requests. * */ /** * A list of possible HTTP request methods. */ enum HTTPRequestMethod { METHOD_GET, METHOD_POST, METHOD_PUT, METHOD_PATCH, METHOD_DELETE, METHOD_HEAD } /** * A list of possible HTTP versions. */ enum HTTPVersion { VERSION_NONE, VERSION_1_0, VERSION_1_1, VERSION_2_0 } /** * Called when a HTTP request was finished. * * The response will only be valid in the callback and will be destroyed afterwards. * The request is a copy of the original request and will be destroyed afterwards. * The request can be modified and made again. * * @param success Whether the request could made. * This not means that the request itself was successful, check the StatusCode of the response for that! * @param error If success is false this will contain the error message. * @param request A copy of the made HTTP request. * Can't be deleted, as it will be destroyed after the callback! * @param response HTTP response of the request. Is null if success is false. * Can't be deleted, as it will be destroyed after the callback! * @param method The HTTP request method that was made. * * @noreturn */ typeset System2HTTPResponseCallback { function void (bool success, const char[] error, System2HTTPRequest request, System2HTTPResponse response, HTTPRequestMethod method); }; /** * Called when a FTP request was finished. * * The response will only be valid in the callback and will be destroyed afterwards. * The request is a copy of the original request and will be destroyed afterwards. * The request can be modified and made again. * * @param success Whether the request could made. * This not means that the request itself was successful, check the StatusCode of the response for that! * @param error If success is false this will contain the error message. * @param request A copy of the made FTP request. * Can't be deleted, as it will be destroyed after the callback! * @param response FTP response of the request. Is null if success is false. * Can't be deleted, as it will be destroyed after the callback! * * @noreturn */ typeset System2FTPResponseCallback { function void (bool success, const char[] error, System2FTPRequest request, System2FTPResponse response); }; /** * Called on a frequent interval while data of a HTTP request is being transferred. * The request is a copy of the original request and will be destroyed afterwards. * * @param request A copy of the made HTTP request. * Can't be deleted, as it will be destroyed after the callback! * @param dlTotal Total expected download size in bytes. * @param dlNow Downloaded bytes so far. * @param ulTotal Total expected upload size in bytes. * @param ulNow Uploaded bytes so far. * * @noreturn */ typeset System2HTTPProgressCallback { function void (System2HTTPRequest request, int dlTotal, int dlNow, int ulTotal, int ulNow); }; /** * Called on a frequent interval while data of a FTP request is being transferred. * The request is a copy of the original request and will be destroyed afterwards. * * @param request A copy of the made FTP request. * Can't be deleted, as it will be destroyed after the callback! * @param dlTotal Total expected download size in bytes. * @param dlNow Downloaded bytes so far. * @param ulTotal Total expected upload size in bytes. * @param ulNow Uploaded bytes so far. * * @noreturn */ typeset System2FTPProgressCallback { function void (System2FTPRequest request, int dlTotal, int dlNow, int ulTotal, int ulNow); }; /** * Basic methodmap for a request. * Use System2HTTPRequest or System2FTPRequest to actually create a request. */ methodmap System2Request < Handle { /** * Sets the URL of the request. * Query parameters have to be given directly in the URL. * * Must be URL-encoded (use System2_URLEncode) in the following format: * scheme://host:port/path * * Host is a hostname or dotted numerical IP address. A numerical IPv6 address must be written within [brackets]. * * If the given URL is missing a scheme name (such as "http://" or "ftp://" etc) * then system2 will make a guess based on the host. * * @param url URL to use for the request. * @param ... URL format arguments. * * @noreturn * @error Invalid request. */ public native void SetURL(const char[] url, any ...); /** * Retrieves the URL of the request. * * @param url Buffer to store URL in. * @param maxlength Maxlength of the buffer. * * @noreturn * @error Invalid request. */ public native void GetURL(char[] url, int maxlength); /** * Sets the remote port number to connect to, * instead of the one specified in the URL or the default port for the used protocol * * @param port Port to use for the request. * * @noreturn * @error Invalid request. * @error Invalid port number. */ public native void SetPort(int port); /** * Returns the port of the request. * * @return The port of the request or 0 if none set. * @error Invalid request. */ public native int GetPort(); /** * Sets the path to the file to which the output of the request will be written to. * Use this to download the output of a response to a file. * * @param file File to write the output to. * @param ... File format arguments. * * @noreturn * @error Invalid request. */ public native void SetOutputFile(const char[] file, any ...); /** * Retrieves the path to the file to which the output of the request will be written to. * * @param file Buffer to store file in. * @param maxlength Maxlength of the buffer. * * @noreturn * @error Invalid request. */ public native void GetOutputFile(char[] file, int maxlength); /** * Sets whether to verify authenticity of the peer's certificate and server cert is for the server it is known as. * Only disable this, when you know what you do! * * @param verify True to verify SSL certificates, otherwise false. * * @noreturn * @error Invalid request. */ public native void SetVerifySSL(bool verify); /** * Returns whether SSL certificates will be verified. * * @return True if SSL certificates will be verified, otherwise false. * @error Invalid request. */ public native bool GetVerifySSL(); /** * Sets proxy for the request. * * @param proxy Hostname or dotted numerical IP address. A numerical IPv6 address must be written within [brackets]. * To specify port number in this string, append :[port] to the end of the host name (default: 1080). * The proxy string may be prefixed with [scheme]:// to specify which kind of proxy is used. * http:// * HTTP Proxy. Default when no scheme is specified. * https:// * HTTPS Proxy. * socks4:// * SOCKS4 Proxy. * socks4a:// * SOCKS4a Proxy. Proxy resolves URL hostname. * socks5:// * SOCKS5 Proxy. * socks5h:// * SOCKS5 Proxy. Proxy resolves URL hostname. * @param useHttpTunnel Tunnel all operations through the HTTP proxy (use http or https)- * Tunneling means that an HTTP CONNECT request is sent to the proxy, asking it to connect to a remote host * on a specific port number and then the traffic is just passed through the proxy. Proxies tend to white-list * specific port numbers it allows CONNECT requests to and often only port 80 and 443 are allowed. * * @noreturn * @error Invalid request. */ public native void SetProxy(const char[] proxy, bool useHttpTunnel = false); /** * Sets the username and password to be used in protocol authentication with the proxy. * * @param username Username to use for proxy authentication. * @param password Password to use for proxy authentication. * * @noreturn * @error Invalid request. */ public native void SetProxyAuthentication(const char[] username, const char[] password); property int Timeout { /** * Returns the timeout for the request. * By default, there is no timeout. * * @return The timeout of the request in seconds or -1 if none set. * @error Invalid request. */ public native get(); /** * Sets the timeout for the request in seconds. * By default, there is no timeout. * * @param seconds The timeout for the request in seconds. 0 to disable. * * @noreturn * @error Invalid request. * @error Invalid timeout. */ public native set(int seconds); } property any Any { /** * Returns the any data that was bound to this request. * * @return The any data that was bound or 0 if none set. * @error Invalid request. */ public native get(); /** * Sets any data to bind to the request (which you can then use in callbacks). * * @param Any The any data to bind. * * @noreturn * @error Invalid request. */ public native set(any Any); } } /** * Methodmap to create a HTTP request. */ methodmap System2HTTPRequest < System2Request { /** * Creates a new HTTP Request. * * @param callback Response callback to call when the request is finished. * @param url URL to use for the request. * Query parameters have to be given directly in the URL. * * Must be URL-encoded (use System2_URLEncode) in the following format: * scheme://host:port/path * * Host is a hostname or dotted numerical IP address. A numerical IPv6 address must be written within [brackets]. * If no scheme is given, HTTP will be used. * @param ... URL format arguments. * * @noreturn * @error Couldn't create request. */ public native System2HTTPRequest(System2HTTPResponseCallback callback, const char[] url, any ...); /** * Sets the progress callback for the transfer of the request. * This will be called frequently while data is being transferred. * This is useful when downloading or uploading stuff. * * @param callback Progress callback to call for the transfer. * * @noreturn * @error Invalid request. */ public native void SetProgressCallback(System2HTTPProgressCallback callback); /** * Sets the body data to send with the request. * You must make sure that the data is formatted the way you want the server to receive it. * Use System2_URLEncode to encode the data. * * For example: parameter=value¶meter2=value2 * Or with JSON: {"parameter": "value", "parameter2": "value2"} * * @param data Body data to send with the request. * @param ... Data format arguments. * * @noreturn * @error Invalid request. */ public native void SetData(const char[] data, any ...); /** * Retrieves the body data of the request. * * @param url Buffer to store data in. * @param maxlength Maxlength of the buffer. * * @noreturn * @error Invalid request. */ public native void GetData(char[] data, int maxlength); /** * Sets a HTTP request header. * Use System2_URLEncode to encode the header. * * @param name Name of the header. * @param value Value to set the header to. * @param ... Value format arguments. * * @noreturn * @error Invalid request. */ public native void SetHeader(const char[] header, const char[] value, any ...); /** * Retrieves a HTTP request header. * * @param name Name of the header to retrieve. * @param value Buffer to store value in. * @param maxlength Maxlength of the buffer. * * @return True if header was set, otherwise false. * @error Invalid request. */ public native bool GetHeader(const char[] header, char[] value, int maxlength); /** * Retrieves the name of a header at a given index. * Use Headers property to retrieve the maximum index. * * @param index Index of the header name. * @param name Buffer to store name in. * @param maxlength Maxlength of the buffer. * * @return True if header was found, otherwise false. * @error Invalid request. */ public native bool GetHeaderName(int index, char[] name, int maxlength); property int Headers { /** * Returns the number of set headers. * * @return The number of set headers. * @error Invalid response. */ public native get(); } /** * Returns all set header names of the request as ArrayList. * Attention: ArrayList has to be deleted after use! * @param maxlength Maxlength of a header. * * @return ArrayList with all set request header names. Must be deleted afterwards! * @error Invalid request. */ public ArrayList GetHeaders(int maxlength = 256) { ArrayList headers = new ArrayList(maxlength); char[] headerName = new char[maxlength]; for (int i=0; i < this.Headers; i++) { this.GetHeaderName(i, headerName, maxlength); headers.PushString(headerName); } return headers; } /** * Sets the user agent for the request. * This will set the User-Agent header to the given value. * * @param userAgent User agent to use. * @param ... User agent format arguments. * * @noreturn * @error Invalid request. */ public native void SetUserAgent(const char[] userAgent, any ...); /** * Sets basic authentication username and passowrd for the request. * This will set the Authorization header to the given values. * * @param username Username to use for basic authentication. * @param password Password to use for basic authentication. * * @noreturn * @error Invalid request. */ public native void SetBasicAuthentication(const char[] username, const char[] password); /** * Sends the request with the HTTP GET method. * * @noreturn * @error Invalid request. */ public native void GET(); /** * Sends the request with the HTTP POST method. * * @noreturn * @error Invalid request. */ public native void POST(); /** * Sends the request with the HTTP PUT method. * * @noreturn * @error Invalid request. */ public native void PUT(); /** * Sends the request with the HTTP PATCH method. * * @noreturn * @error Invalid request. */ public native void PATCH(); /** * Sends the request with the HTTP DELETE method. * * @noreturn * @error Invalid request. */ public native void DELETE(); /** * Sends the request with the HTTP HEAD method. * * @noreturn * @error Invalid request. */ public native void HEAD(); property bool FollowRedirects { /** * Returns whether the request follow redirects or not. * By default, redirects will be followed. * * @return True if it follow redirects, otherwise false. * @error Invalid request. */ public native get(); /** * Sets to follow any Location: header that the server sends as part of an HTTP header in a 3xx response. * For 301, 302 and 303 responses system2 will switch method to GET. All other 3xx codes will make system2 send the same method again. * By default, redirects will be followed. * * @param follow True to follow redirects, otherwise false. * * @noreturn * @error Invalid request. */ public native set(bool follow); } } /** * Methodmap to create a FTP request. */ methodmap System2FTPRequest < System2Request { /** * Creates a new FTP Request. * * @param callback Response callback to call when the request is finished. * @param url URL to use for the request. * * Must be URL-encoded (use System2_URLEncode) in the following format: * scheme://host:port/path * * Host is a hostname or dotted numerical IP address. A numerical IPv6 address must be written within [brackets]. * If no scheme is given, FTP will be used. * @param ... URL format arguments. * * @noreturn * @error Couldn't create request. */ public native System2FTPRequest(System2FTPResponseCallback callback, const char[] url, any ...); /** * Sets the progress callback for the transfer of the request. * This will be called frequently while data is being transferred. * * @param callback Progress callback to call for the transfer. * * @noreturn * @error Invalid request. */ public native void SetProgressCallback(System2FTPProgressCallback callback); /** * Sets authentication needed to access the FTP server. * * @param username Username to use for authentication. * @param password Password to use for authentication. * * @noreturn * @error Invalid request. */ public native void SetAuthentication(const char[] username, const char[] password); /** * Sets the path to the file which should be uploaded. * If this is set, an upload approach will be used. * * @param file File to upload. * @param ... File format arguments. * * @noreturn * @error Invalid request. */ public native void SetInputFile(const char[] file, any ...); /** * Retrieves the path to the file which should be uploaded. * * @param file Buffer to store file in. * @param maxlength Maxlength of the buffer. * * @noreturn * @error Invalid request. */ public native void GetInputFile(char[] file, int maxlength); /** * Starts the request. * * If a input file is set the request will upload this file. * Otherwise it may result in a directory listing or a file download. * * @noreturn * @error Invalid request. */ public native void StartRequest(); property bool AppendToFile { /** * Returns whether the request appends to the FTP file or replaces it when uploading a file. * By default, the file will be replaced. * * @return True if it appends to the file, false if the file will be replaced. * @error Invalid request. */ public native get(); /** * Sets whether to append to the FTP file or to replace it when uploading a file. * By default, the file will be replaced. * * @param append True to append to file, false to replace it. * * @noreturn * @error Invalid request. */ public native set(bool append); } property bool CreateMissingDirs { /** * Returns whether the request creates missing dirs when uploading a file. * By default, missing dirs will be created. * * @return True if it creates missing dirs, otherwise false. * @error Invalid request. */ public native get(); /** * Sets whether to create any remote directory that it fails to "move" into. * By default, missing dirs will be created. * * @param create True to create missing dirs, otherwise false. * * @noreturn * @error Invalid request. */ public native set(bool create); } property bool ListFilenamesOnly { /** * Returns whether only file names should be fetched for directory listing. * By default, all information will be fetched. * * @return True if only file names should be fetched, false for full directory listing. * @error Invalid request. */ public native get(); /** * Sets whether to list the names of files in a directory, * rather than performing a full directory listing that would normally include file sizes, dates etc. * By default, all information will be fetched. * * @param append True if only file names should be fetched, false for full directory listing. * * @noreturn * @error Invalid request. */ public native set(bool append); } } /** * Basic methodmap for a response of a request. */ methodmap System2Response < Handle { /** * Retrieves the last used effective URL. * This may differ from the request URL, if a redirect was followed. * * @param url Buffer to store last URL in. * @param maxlength Maxlength of the URL buffer. * * @noreturn * @error Invalid response. */ public native void GetLastURL(char[] url, int maxlength); /** * Retrieves the content of the response. * This shouldn't be used when retrieved binary stuff. * * @param content Buffer to store the content in. * @param maxlength Maxlength of the content buffer. * @param start Start byte to start reading from. * You can use this to retrieve the content step by step. * @param delimiter Delimiter until which the content should be retrieved. * @param include Whether the delimiter should be included or not. * * @return Number of read bytes. * @error Invalid response. */ public native int GetContent(char[] content, int maxlength, int start = 0, const char[] delimiter = "", bool include = true); property int ContentLength { /** * Returns the length of the complete response content. * * @return Length of the content. * @error Invalid response. */ public native get(); } property int StatusCode { /** * Returns the status code of the response. * * @return The status code. * @error Invalid response. */ public native get(); } property float TotalTime { /** * Returns the total time from the request until the response in seconds. * Includs name resolving, TCP connect etc. * * @return Total time from the request until the response in seconds. * @error Invalid response. */ public native get(); } property int DownloadSize { /** * Returns the total amount of bytes that were downloaded. * This counts actual payload data, what's also commonly called body. * All meta and header data are excluded and will not be counted in this number. * * @return Total amount of bytes that were downloaded. * @error Invalid response. */ public native get(); } property int UploadSize { /** * Returns the total amount of bytes that were uploaded. * * @return Total amount of bytes that were uploaded. * @error Invalid response. */ public native get(); } property int DownloadSpeed { /** * Returns the average download speed measured for the complete download in bytes per second. * * @return Average download speed in bytes per second. * @error Invalid response. */ public native get(); } property int UploadSpeed { /** * Returns the average upload speed measured for the complete upload in bytes per second. * * @return Average upload speed in bytes per second. * @error Invalid response. */ public native get(); } } /** * Methodmap for a response of a HTTP request. */ methodmap System2HTTPResponse < System2Response { /** * Retrieves the content type of the response. * This is the value read from the Content-Type header. * * @param type Buffer to store content type in. * @param maxlength Maxlength of the buffer. * * @noreturn * @error Invalid response. */ public native void GetContentType(const char[] type, int maxlength); /** * Retrieves a HTTP response header * * @param name Name of the header to retrieve. * @param value Buffer to store value in. * @param maxlength Maxlength of the buffer. * * @return True if header was set, otherwise false. * @error Invalid response. */ public native bool GetHeader(const char[] name, char[] value, int maxlength); /** * Retrieves the name of a header at a given index. * Use Headers property to retrieve the maximum index. * * @param index Index of the header name. * @param name Buffer to store name in. * @param maxlength Maxlength of the buffer. * * @return True if header was found, otherwise false. * @error Invalid response. */ public native bool GetHeaderName(int index, char[] name, int maxlength); property int Headers { /** * Returns the number of set headers in the response. * * @return The number of set headers. * @error Invalid response. */ public native get(); } /** * Returns all header set names of the response as ArrayList. * Attention: ArrayList has to be deleted after use! * @param maxlength Maxlength of a header. * * @return ArrayList with all set response header names. Must be deleted! * @error Invalid request. */ public ArrayList GetHeaders(int maxlength = 256) { ArrayList headers = new ArrayList(maxlength); char[] headerName = new char[maxlength]; for (int i=0; i < this.Headers; i++) { this.GetHeaderName(i, headerName, maxlength); headers.PushString(headerName); } return headers; } property HTTPVersion HTTPVersion { /** * Returns the HTTP version of the response. * * @return The HTTP version. * @error Invalid response. */ public native get(); } } /** * Methodmap for a response of a FTP request. * Currently there are no special methods for that. */ methodmap System2FTPResponse < System2Response { } /** * Converts a plain string to an URL encoded string. * All input characters that are not a-z, A-Z, 0-9, '-', '.', '_' or '~' * are converted to their "URL escaped" version (%NN where NN is a two-digit hexadecimal number). * * Be aware that the output string may be larger then the input string. * * @param output Buffer to store encoded string in. May point to the input string (will replace the input string). * @param maxlength Maxlength of the output buffer. * @param input String to encode. * @param ... Input string format arguments * * @return True on success, false otherwise. */ native bool System2_URLEncode(char[] output, int maxlength, const char[] input, any ...); /** * Converts an URL encoded string to a plain string. * All input characters that are URL encoded (%XX where XX is a two-digit hexadecimal number) are converted to their binary versions. * * @param output Buffer to store decoded string in. May point to the input string (will replace the input string). * @param maxlength Maxlength of the output buffer. * @param input String to decode. * @param ... Input string format arguments * * @return True on success, false otherwise. */ native bool System2_URLDecode(char[] output, int maxlength, const char[] input, any ...);