Difference between revisions of "Manual:Networking Functions"
m (→sendGMCP) |
m (correcting function name) |
||
(56 intermediate revisions by 10 users not shown) | |||
Line 1: | Line 1: | ||
{{TOC right}} | {{TOC right}} | ||
+ | {{#description2:Mudlet API documentation for functions for managing networking.}} | ||
= Networking Functions = | = Networking Functions = | ||
A collection of functions for managing networking. | A collection of functions for managing networking. | ||
Line 37: | Line 38: | ||
==downloadFile== | ==downloadFile== | ||
;downloadFile(saveto, url) | ;downloadFile(saveto, url) | ||
− | : Downloads the resource at the given url into the saveto location on disk. This does not pause the script until the file is downloaded - instead, it lets it continue right away and downloads in the background. When a download is finished, the [[Manual: | + | : Downloads the resource at the given url into the saveto location on disk. This does not pause the script until the file is downloaded - instead, it lets it continue right away and downloads in the background. When a download is finished, the [[Manual:Event_Engine#sysDownloadDone|sysDownloadDone]] event is raised (with the saveto location as the argument), or when a download fails, the [[Manual:Event_Engine#sysDownloadError|sysDownloadError]] event is raised with the reason for failure. You may call downloadFile multiple times and have multiple downloads going on at once - but they aren’t guaranteed to be downloaded in the same order that you started them in. |
+ | |||
+ | :See also: [[#getHTTP|getHTTP()]], [[#postHTTP|postHTTP()]], [[#putHTTP|putHTTP()]], [[#deleteHTTP|deleteHTTP()]] | ||
+ | |||
+ | [[File:Downloadfile privacy logging.png|frame|For privacy transparency, URLs accessed are logged in the Central Debug Console]] | ||
{{note}} Since Mudlet 3.0, https downloads are supported and the actual url that was used for the download is returned - useful in case of redirects. | {{note}} Since Mudlet 3.0, https downloads are supported and the actual url that was used for the download is returned - useful in case of redirects. | ||
Line 80: | Line 85: | ||
Result should look like this: | Result should look like this: | ||
− | [[File:DownloadFile_demo.png]]. | + | [[File:DownloadFile_demo.png|alt=|1000x1000px]]. |
+ | |||
+ | ==getConnectionInfo== | ||
+ | ;getConnectionInfo() | ||
+ | :Returns the server address and port that you're currently connected to, and (in Mudlet 4.12+) <code>true</code> or <code>false</code> indicating if you're currently connected to a game. | ||
+ | :See also: [[Manual:Networking_Functions#connectToServer|connectToServer()]] | ||
+ | |||
+ | {{MudletVersion|4.2}} | ||
+ | |||
+ | ;Example | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | local host, port, connected = getConnectionInfo() | ||
+ | cecho(string.format("<light_grey>Playing on <forest_green>%s:%s<light_grey>, currently connected? <forest_green>%s\n", host, port, tostring(connected))) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- echo the new connection parameters whenever we connect to a different host with connectToServer() | ||
+ | function echoInfo() | ||
+ | local host, port = getConnectionInfo() | ||
+ | cecho(string.format("<light_grey>Now connected to <forest_green>%s:%s\n", host, port)) | ||
+ | end | ||
+ | |||
+ | registerAnonymousEventHandler("sysConnectionEvent", "echoInfo") | ||
+ | </syntaxhighlight> | ||
==getIrcChannels== | ==getIrcChannels== | ||
Line 87: | Line 115: | ||
:See also: [[Manual:Networking_Functions#setIrcChannels|setIrcChannels()]] | :See also: [[Manual:Networking_Functions#setIrcChannels|setIrcChannels()]] | ||
− | {{ | + | {{MudletVersion|3.3}} |
;Example | ;Example | ||
Line 114: | Line 142: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | {{ | + | {{MudletVersion|3.3}} |
==getIrcNick== | ==getIrcNick== | ||
Line 121: | Line 149: | ||
:See also: [[Manual:Networking_Functions#setIrcNick|setIrcNick()]] | :See also: [[Manual:Networking_Functions#setIrcNick|setIrcNick()]] | ||
− | {{ | + | {{MudletVersion|3.3}} |
;Example | ;Example | ||
Line 135: | Line 163: | ||
:See also: [[Manual:Networking_Functions#setIrcServer|setIrcServer()]] | :See also: [[Manual:Networking_Functions#setIrcServer|setIrcServer()]] | ||
− | {{ | + | {{MudletVersion|3.3}} |
;Example | ;Example | ||
Line 150: | Line 178: | ||
;Example | ;Example | ||
− | + | <syntaxhighlight lang="lua"> | |
+ | if getNetworkLatency() > 3 then | ||
+ | send("say This game is soooo laggy!") | ||
+ | end | ||
+ | </syntaxhighlight> | ||
==openUrl== | ==openUrl== | ||
Line 176: | Line 208: | ||
:Restarts the IRC client connection, reloading configurations from disk before reconnecting the IRC client. | :Restarts the IRC client connection, reloading configurations from disk before reconnecting the IRC client. | ||
− | {{ | + | {{MudletVersion|3.3}} |
==sendAll== | ==sendAll== | ||
Line 212: | Line 244: | ||
: Note that this function is rarely used in practice. For most GMCP modules, the messages are automatically sent by the server when a relevant event happens in the game. For example, LOOKing in your room prompts the server to send the room description and contents, as well as the GMCP message gmcp.Room. A call to sendGMCP would not be required in this case. | : Note that this function is rarely used in practice. For most GMCP modules, the messages are automatically sent by the server when a relevant event happens in the game. For example, LOOKing in your room prompts the server to send the room description and contents, as well as the GMCP message gmcp.Room. A call to sendGMCP would not be required in this case. | ||
− | : See also: [[Manual:Scripting#GMCP|GMCP Scripting]] | + | : When playing an IRE game, a call to <code>send(" ")</code> afterwards is necessary due to a bug in the game with compression (MCCP) is enabled. |
+ | |||
+ | : See also: [[Manual:Scripting#GMCP|GMCP Scripting for Discord status]] | ||
;Example | ;Example | ||
Line 231: | Line 265: | ||
sendGMCP("Char.Skills.Get " .. yajl.to_string{group="MWP", name="block"}) | sendGMCP("Char.Skills.Get " .. yajl.to_string{group="MWP", name="block"}) | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 260: | Line 270: | ||
;sendIrc(target, message) | ;sendIrc(target, message) | ||
: Sends a message to an IRC channel or person. Returns ''true''+''status'' if message could be sent or was successfully processed by the client, or ''nil''+''error'' if the client is not ready for sending, and ''false''+''status'' if the client filtered the message or failed to send it for some reason. If the IRC client hasn't started yet, this function will initiate the IRC client and begin a connection. | : Sends a message to an IRC channel or person. Returns ''true''+''status'' if message could be sent or was successfully processed by the client, or ''nil''+''error'' if the client is not ready for sending, and ''false''+''status'' if the client filtered the message or failed to send it for some reason. If the IRC client hasn't started yet, this function will initiate the IRC client and begin a connection. | ||
+ | |||
+ | To receive an IRC message, check out the [[Manual:Event_Engine#sysIrcMessage|sysIrcMessage event]]. | ||
{{note}} Since Mudlet 3.3, auto-opens the IRC window and returns the success status. | {{note}} Since Mudlet 3.3, auto-opens the IRC window and returns the success status. | ||
Line 317: | Line 329: | ||
{{note}} The following IRC commands are available since Mudlet 3.15: | {{note}} The following IRC commands are available since Mudlet 3.15: | ||
* /MSGLIMIT <limit> (<buffer>) -- Sets the limit for messages to keep in the IRC client message buffers and saves this setting. If a specific buffer/channel name is given the limit is not saved and applies to the given buffer until the application is closed or the limit is changed again. For this reason, global settings should be applied first, before settings for specific channels/PM buffers. | * /MSGLIMIT <limit> (<buffer>) -- Sets the limit for messages to keep in the IRC client message buffers and saves this setting. If a specific buffer/channel name is given the limit is not saved and applies to the given buffer until the application is closed or the limit is changed again. For this reason, global settings should be applied first, before settings for specific channels/PM buffers. | ||
+ | |||
+ | ==sendMSDP== | ||
+ | ;sendMSDP(variable[, value][, value...]) | ||
+ | : Sends a MSDP message to the server. | ||
+ | |||
+ | ;Parameters: | ||
+ | * ''variable:'' | ||
+ | : The variable, in MSDP terms, that you want to request from the server. | ||
+ | * ''value:'' | ||
+ | : The variables value that you want to request. You can request more than one value at a time. | ||
+ | |||
+ | : See Also: [[Manual:Supported_Protocols#MSDP|MSDP support in Mudlet]], [http://tintin.sourceforge.net/msdp/ Mud Server Data Protocol specification] | ||
+ | |||
+ | ;Example | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- ask for a list of commands, lists, and reportable variables that the server supports | ||
+ | sendMSDP("LIST", "COMMANDS", "LISTS", "REPORTABLE_VARIABLES") | ||
+ | |||
+ | -- ask the server to start keeping you up to date on your health | ||
+ | sendMSDP("REPORT", "HEALTH") | ||
+ | |||
+ | -- or on your health and location | ||
+ | sendMSDP("REPORT", "HEALTH", "ROOM_VNUM", "ROOM_NAME") | ||
+ | </syntaxhighlight> | ||
==sendTelnetChannel102== | ==sendTelnetChannel102== | ||
; sendTelnetChannel102(msg) | ; sendTelnetChannel102(msg) | ||
− | : Sends a message via the 102 subchannel back to the | + | : Sends a message via the 102 subchannel back to the game (that's used in Aardwolf). The msg is in a two byte format; see the link below to the Aardwolf Wiki for how that works. |
;Example | ;Example | ||
Line 334: | Line 370: | ||
==setIrcChannels== | ==setIrcChannels== | ||
− | ;setIrcChannels( channels ) | + | ;setIrcChannels(channels) |
:Saves the given channels to disk as the new IRC client channel auto-join configuration. This value is not applied to the current active IRC client until it is restarted with [[Manual:Networking_Functions#restartIrc|restartIrc()]] | :Saves the given channels to disk as the new IRC client channel auto-join configuration. This value is not applied to the current active IRC client until it is restarted with [[Manual:Networking_Functions#restartIrc|restartIrc()]] | ||
:See also: [[Manual:Networking_Functions#getIrcChannels|getIrcChannels()]], [[Manual:Networking_Functions#restartIrc|restartIrc()]] | :See also: [[Manual:Networking_Functions#getIrcChannels|getIrcChannels()]], [[Manual:Networking_Functions#restartIrc|restartIrc()]] | ||
Line 342: | Line 378: | ||
: A table containing strings which are valid channel names. Any channels in the list which aren't valid are removed from the list. | : A table containing strings which are valid channel names. Any channels in the list which aren't valid are removed from the list. | ||
− | {{ | + | {{MudletVersion|3.3}} |
;Example | ;Example | ||
Line 351: | Line 387: | ||
==setIrcNick== | ==setIrcNick== | ||
− | ;setIrcNick( nickname ) | + | ;setIrcNick(nickname) |
:Saves the given nickname to disk as the new IRC client configuration. This value is not applied to the current active IRC client until it is restarted with restartIrc() | :Saves the given nickname to disk as the new IRC client configuration. This value is not applied to the current active IRC client until it is restarted with restartIrc() | ||
:See also: [[Manual:Networking_Functions#getIrcNick|getIrcNick()]], [[Manual:Networking_Functions#restartIrc|restartIrc()]] | :See also: [[Manual:Networking_Functions#getIrcNick|getIrcNick()]], [[Manual:Networking_Functions#restartIrc|restartIrc()]] | ||
Line 359: | Line 395: | ||
: A string with your new desired name in IRC. | : A string with your new desired name in IRC. | ||
− | {{ | + | {{MudletVersion|3.3}} |
;Example | ;Example | ||
Line 367: | Line 403: | ||
==setIrcServer== | ==setIrcServer== | ||
− | ;setIrcServer( hostname, port ) | + | ;setIrcServer(hostname, port[, secure]) |
:Saves the given server's address to disk as the new IRC client connection configuration. These values are not applied to the current active IRC client until it is restarted with restartIrc() | :Saves the given server's address to disk as the new IRC client connection configuration. These values are not applied to the current active IRC client until it is restarted with restartIrc() | ||
:See also: [[Manual:Networking_Functions#getIrcServer|getIrcServer()]], [[Manual:Networking_Functions#restartIrc|restartIrc()]] | :See also: [[Manual:Networking_Functions#getIrcServer|getIrcServer()]], [[Manual:Networking_Functions#restartIrc|restartIrc()]] | ||
Line 376: | Line 412: | ||
* ''port:'' | * ''port:'' | ||
: (optional) A number indicating the port of the IRC server. Defaults to 6667, if not provided. | : (optional) A number indicating the port of the IRC server. Defaults to 6667, if not provided. | ||
+ | * ''secure:'' | ||
+ | : (optional) Boolean, true if server uses Transport Layer Security. Defaults to false. | ||
+ | |||
+ | {{MudletVersion|3.3}} | ||
+ | |||
+ | ;Example | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | setIrcServer("irc.libera.chat", 6667) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==getHTTP== | ||
+ | ;getHTTP(url, headersTable) | ||
+ | : Sends an [https://en.wikipedia.org/wiki/GET_(HTTP) HTTP GET] request to the given URL. Raises [[Manual:Event_Engine#sysGetHttpDone|sysGetHttpDone]] on success or [[Manual:Event_Engine#sysGetHttpError|sysGetHttpError]] on failure. | ||
+ | :See also: [[#downloadFile|downloadFile()]]. | ||
+ | |||
+ | [[File:Posthttp privacy logging.png.png|frame|For privacy transparency, URLs accessed are logged in the Central Debug Console]] | ||
+ | |||
+ | ;Parameters: | ||
+ | * ''url:'' | ||
+ | : Location to send the request to. | ||
+ | * ''headersTable:'' | ||
+ | : (optional) table of headers to send with your request. | ||
+ | |||
+ | {{MudletVersion|4.10}} | ||
+ | |||
+ | ;Examples | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | function onHttpGetDone(_, url, body) | ||
+ | cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body)) | ||
+ | end | ||
+ | |||
+ | registerAnonymousEventHandler("sysGetHttpDone", onHttpGetDone) | ||
+ | |||
+ | getHTTP("https://httpbin.org/info") | ||
+ | getHTTP("https://httpbin.org/are_you_awesome", {["X-am-I-awesome"] = "yep I am"}) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- Status requests typically use GET requests | ||
+ | local url = "http://postman-echo.com/status" | ||
+ | local header = {["Content-Type"] = "application/json"} | ||
+ | |||
+ | -- first we create something to handle the success, and tell us what we got | ||
+ | registerAnonymousEventHandler('sysGetHttpDone', function(event, rurl, response) | ||
+ | if rurl == url then display(r) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler | ||
+ | end, true) -- this sets it to delete itself after it fires | ||
+ | -- then we create something to handle the error message, and tell us what went wrong | ||
+ | registerAnonymousEventHandler('sysGetHttpError', function(event, response, rurl) | ||
+ | if rurl == url then display(r) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler | ||
+ | end, true) -- this sets it to delete itself after it fires | ||
+ | |||
+ | -- Lastly, we make the request: | ||
+ | getHTTP(url, header) | ||
+ | |||
+ | -- Pop this into an alias and try it yourself! | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==postHTTP== | ||
+ | ;postHTTP(dataToSend, url, headersTable, file) | ||
+ | : Sends an [https://en.wikipedia.org/wiki/POST_(HTTP) HTTP POST] request to the given URL, either as text or with a specific file you'd like to upload. Raises [[Manual:Event_Engine#sysPostHttpDone|sysPostHttpDone]] on success or [[Manual:Event_Engine#sysPostHttpError|sysPostHttpError]] on failure. | ||
+ | :See also: [[#downloadFile|downloadFile()]], [[#getHTTP|getHTTP()]], [[#putHTTP|putHTTP()]], [[#deleteHTTP|deleteHTTP()]]. | ||
+ | |||
+ | [[File:Posthttp privacy logging.png.png|frame|For privacy transparency, URLs accessed are logged in the Central Debug Console]] | ||
+ | |||
+ | ;Parameters: | ||
+ | * ''dataToSend:'' | ||
+ | : Text to send in the request (unless you provide a file to upload). | ||
+ | * ''url:'' | ||
+ | : Location to send the request to. | ||
+ | * ''headersTable:'' | ||
+ | : (optional) table of headers to send with your request. | ||
+ | * ''file:'' | ||
+ | : (optional) file to upload as part of the POST request. If provided, this will replace 'dataToSend'. | ||
+ | : If you use a scripting language (ex. PHP) to handle this post, remember that the file is sent as raw data. Expecially no field name is provided, dispite it works in common html post. | ||
+ | |||
+ | {{MudletVersion|4.1}} | ||
+ | |||
+ | ;Examples | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | function onHttpPostDone(_, url, body) | ||
+ | cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body)) | ||
+ | end | ||
+ | |||
+ | registerAnonymousEventHandler("sysPostHttpDone", onHttpPostDone) | ||
+ | |||
+ | postHTTP("why hello there!", "https://httpbin.org/post") | ||
+ | postHTTP("this us a request with custom headers", "https://httpbin.org/post", {["X-am-I-awesome"] = "yep I am"}) | ||
+ | postHTTP(nil, "https://httpbin.org/post", {}, "<fill in file location to upload here, maybe get from invokeFileDialog>") | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- This will create a JSON message body. Many modern REST APIs expect a JSON body. | ||
+ | local url = "http://postman-echo.com/post" | ||
+ | local data = {message = "I am the banana", user = "admin"} | ||
+ | local header = {["Content-Type"] = "application/json"} | ||
+ | |||
+ | -- first we create something to handle the success, and tell us what we got | ||
+ | registerAnonymousEventHandler('sysPostHttpDone', function(event, rurl, response) | ||
+ | if rurl == url then display(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler | ||
+ | end, true) -- this sets it to delete itself after it fires | ||
+ | |||
+ | -- then we create something to handle the error message, and tell us what went wrong | ||
+ | registerAnonymousEventHandler('sysPostHttpError', function(event, response, rurl) | ||
+ | if rurl == url then display(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler | ||
+ | end, true) -- this sets it to delete itself after it fires | ||
+ | |||
+ | -- Lastly, we make the request: | ||
+ | postHTTP(yajl.to_string(data), url, header) -- yajl.to_string converts our Lua table into a JSON-like string so the server can understand it | ||
+ | |||
+ | -- Pop this into an alias and try it yourself! | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;HTTP Basic Authentication Example: | ||
+ | If your HTTP endpoint requires authentication to post data, HTTP Basic Authentication is a common method for doing so. There are two ways to do so. | ||
+ | |||
+ | OPTION 1: URL encoding: | ||
+ | Many HTTP servers allow you to enter a HTTP Basic Authentication username and password at the beginning of the URL itself, in format: | ||
+ | https://username:[email protected]/path/to/endpoint | ||
+ | |||
+ | OPTION 2: Authorization Header: | ||
+ | Some HTTP servers may require you to put your Basic Authentication into the 'Authorization' HTTP header value. | ||
+ | |||
+ | This requires encoding the username:password into base64. | ||
+ | For example, if your username is 'user' and your password is '12345', you'd need to run the string "user:12345" through a base64 encoder, which would result in the string: | ||
+ | dXNlcjoxMjM0NQ== | ||
+ | |||
+ | Then, you'd need to set the HTTP header 'Authorization' field value to indicate it is using Basic auth and inserting the base64 string as: | ||
+ | ['Authorization'] = "Basic dXNlcjoxMjM0NQ==" | ||
+ | |||
+ | As you're encoding your username and password, you probably want to do this encoding locally for security reasons. You also probably want to only use https:// and not http:// when sending usernames and passwords over the internet. | ||
+ | |||
+ | In the HTTP Basic Authentication example below, there is an inline base64Encode() function included: | ||
+ | |||
+ | <syntaxhighlight lang="lua"> | ||
+ | function base64Encode(data) | ||
+ | -- Lua 5.1+ base64 v3.0 (c) 2009 by Alex Kloss <[email protected]> | ||
+ | -- licensed under the terms of the LGPL2 | ||
+ | local b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' | ||
+ | return ((data:gsub('.', function(x) | ||
+ | local r,b='',x:byte() | ||
+ | for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end | ||
+ | return r; | ||
+ | end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x) | ||
+ | if (#x < 6) then return '' end | ||
+ | local c=0 | ||
+ | for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end | ||
+ | return b:sub(c+1,c+1) | ||
+ | end)..({ '', '==', '=' })[#data%3+1]) | ||
+ | end | ||
+ | -- Example: base64Encode("user:12345") -> dXNlcjoxMjM0NQ== | ||
+ | |||
+ | function postJSON(url,dataTable,headerTable) | ||
+ | -- This will create a JSON message body. Many modern REST APIs expect a JSON body. | ||
+ | local data = dataTable or {text = "hello world"} | ||
+ | local header = headerTable or {["Content-Type"] = "application/json"} | ||
+ | -- first we create something to handle the success, and tell us what we got | ||
+ | registerAnonymousEventHandler('sysPostHttpDone', function(event, rurl, response) | ||
+ | if rurl == url then sL("HTTP response success"); echo(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler | ||
+ | end, true) -- this sets it to delete itself after it fires | ||
+ | -- then we create something to handle the error message, and tell us what went wrong | ||
+ | registerAnonymousEventHandler('sysPostHttpError', function(event, response, rurl) | ||
+ | if rurl == url then sL("HTTP response error",3); echo(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler | ||
+ | end, true) -- this sets it to delete itself after it fires | ||
+ | -- Lastly, we make the request: | ||
+ | postHTTP(yajl.to_string(data), url, header) -- yajl.to_string converts our Lua table into a JSON-like string so the server can understand it | ||
+ | end | ||
+ | |||
+ | data = { | ||
+ | message = "I am the banana", | ||
+ | user = "admin" | ||
+ | } | ||
+ | header = { | ||
+ | ["Content-Type"] = "application/json", | ||
+ | ["Authorization"] = "Basic " .. base64Encode("user:12345") | ||
+ | } | ||
+ | postJSON("http://postman-echo.com/post",data,header) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;URL Encoding vs JSON encoding | ||
+ | Some HTTP endpoints may not support JSON encoding, and instead may require URL encoding. Here's an example function to convert your lua data table into a URL encoded string:: | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- Example: URLEncodeTable({message="hello",person="world"}) -> "message=hello&person=world" | ||
+ | |||
+ | function URLEncodeTable(Args) | ||
+ | -- From: https://help.interfaceware.com/code/details/urlcode-lua | ||
+ | ---------------------------------------------------------------------------- | ||
+ | -- URL-encode the elements of a table creating a string to be used in a | ||
+ | -- URL for passing data/parameters to another script | ||
+ | -- @param args Table where to extract the pairs (name=value). | ||
+ | -- @return String with the resulting encoding. | ||
+ | ---------------------------------------------------------------------------- | ||
+ | -- | ||
+ | local ipairs, next, pairs, tonumber, type = ipairs, next, pairs, tonumber, type | ||
+ | local string = string | ||
+ | local table = table | ||
+ | |||
+ | --helper functions: | ||
+ | ---------------------------------------------------------------------------- | ||
+ | -- Decode an URL-encoded string (see RFC 2396) | ||
+ | ---------------------------------------------------------------------------- | ||
+ | local unescape = function (str) | ||
+ | str = string.gsub (str, "+", " ") | ||
+ | str = string.gsub (str, "%%(%x%x)", function(h) return string.char(tonumber(h,16)) end) | ||
+ | return str | ||
+ | end | ||
+ | |||
+ | ---------------------------------------------------------------------------- | ||
+ | -- URL-encode a string (see RFC 2396) | ||
+ | ---------------------------------------------------------------------------- | ||
+ | local escape = function (str) | ||
+ | str = string.gsub (str, "([^0-9a-zA-Z !'()*._~-])", -- locale independent | ||
+ | function (c) return string.format ("%%%02X", string.byte(c)) end) | ||
+ | str = string.gsub (str, " ", "+") | ||
+ | return str | ||
+ | end | ||
+ | |||
+ | ---------------------------------------------------------------------------- | ||
+ | -- Insert a (name=value) pair into table [[args]] | ||
+ | -- @param args Table to receive the result. | ||
+ | -- @param name Key for the table. | ||
+ | -- @param value Value for the key. | ||
+ | -- Multi-valued names will be represented as tables with numerical indexes | ||
+ | -- (in the order they came). | ||
+ | ---------------------------------------------------------------------------- | ||
+ | local insertfield = function (args, name, value) | ||
+ | if not args[name] then | ||
+ | args[name] = value | ||
+ | else | ||
+ | local t = type (args[name]) | ||
+ | if t == "string" then | ||
+ | args[name] = {args[name],value,} | ||
+ | elseif t == "table" then | ||
+ | table.insert (args[name], value) | ||
+ | else | ||
+ | error ("CGILua fatal error (invalid args table)!") | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | -- end helper functions | ||
+ | |||
+ | if Args == nil or next(Args) == nil then -- no args or empty args? | ||
+ | return "" | ||
+ | end | ||
+ | local strp = "" | ||
+ | for key, vals in pairs(Args) do | ||
+ | if type(vals) ~= "table" then | ||
+ | vals = {vals} | ||
+ | end | ||
+ | for i,val in ipairs(vals) do | ||
+ | strp = strp.."&"..key.."="..escape(val) | ||
+ | end | ||
+ | end | ||
+ | -- remove first & | ||
+ | return string.sub(strp,2) | ||
+ | end | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==putHTTP== | ||
+ | ;putHTTP(dataToSend, url, [headersTable], [file]) | ||
+ | : Sends an [https://en.wikipedia.org/wiki/PUT_(HTTP) HTTP PUT] request to the given URL, either as text or with a specific file you'd like to upload. Raises [[Manual:Event_Engine#sysPutHttpDone|sysPutHttpDone]] on success or [[Manual:Event_Engine#sysPutHttpError|sysPutHttpError]] on failure. | ||
+ | :See also: [[#downloadFile|downloadFile()]], [[#getHTTP|getHTTP()]], [[#postHTTP|postHTTP()]], [[#deleteHTTP|deleteHTTP()]]. | ||
+ | |||
+ | [[File:PutHTTP privacy logging.png|frame|For privacy transparency, URLs accessed are logged in the Central Debug Console]] | ||
+ | |||
+ | ;Parameters: | ||
+ | * ''dataToSend:'' | ||
+ | : Text to send in the request (unless you provide a file to upload). | ||
+ | * ''url:'' | ||
+ | : Location to send the request to. | ||
+ | * ''headersTable:'' | ||
+ | : (optional) table of headers to send with your request. | ||
+ | * ''file:'' | ||
+ | : (optional) file to upload as part of the PUT request. If provided, this will replace 'dataToSend'. | ||
+ | |||
+ | {{MudletVersion|4.1}} | ||
+ | |||
+ | ;Example | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | function onHttpPutDone(_, url, body) | ||
+ | cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body)) | ||
+ | end | ||
+ | |||
+ | registerAnonymousEventHandler("sysPutHttpDone", onHttpPutDone) | ||
+ | putHTTP("this us a request with custom headers", "https://httpbin.org/put", {["X-am-I-awesome"] = "yep I am"}) | ||
+ | putHTTP("https://httpbin.org/put", "<fill in file location to upload here>") | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==deleteHTTP== | ||
+ | ;deleteHTTP(url, headersTable) | ||
+ | : Sends an [https://en.wikipedia.org/wiki/DELETE_(HTTP) HTTP DELETE] request to the given URL. Raises [[Manual:Event_Engine#sysDeleteHttpDone|sysDeleteHttpDone]] on success or [[Manual:Event_Engine#sysDeleteHttpError|sysDeleteHttpError]] on failure. | ||
+ | :See also: [[#downloadFile|downloadFile()]], [[#getHTTP|getHTTP()]], [[#postHTTP|postHTTP()]], [[#putHTTP|putHTTP()]]. | ||
+ | |||
+ | [[File:PutHTTP privacy logging.png|frame|For privacy transparency, URLs accessed are logged in the Central Debug Console]] | ||
+ | |||
+ | ;Parameters: | ||
+ | * ''url:'' | ||
+ | : Location to send the request to. | ||
+ | * ''headersTable:'' | ||
+ | : (optional) table of headers to send with your request. | ||
− | {{ | + | {{MudletVersion|4.1}} |
;Example | ;Example | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
− | + | function onHttpDeleteDone(_, url, body) | |
+ | cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body)) | ||
+ | end | ||
+ | |||
+ | registerAnonymousEventHandler("sysDeleteHttpDone", onHttpDeleteDone) | ||
+ | |||
+ | deleteHTTP("https://httpbin.org/delete") | ||
+ | deleteHTTP("https://httpbin.org/delete", {["X-am-I-awesome"] = "yep I am"}) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | ==customHTTP== | ||
+ | ;customHTTP(method, url, headersTable) | ||
+ | : Sends an custom method request to the given URL. Raises [[Manual:Event_Engine#sysCustomHttpDone|sysCustomHttpDone]] on success or [[Manual:Event_Engine#sysCustomHttpError|sysCustomHttpError]] on failure. | ||
+ | :See also: [[#downloadFile|downloadFile()]], [[#getHTTP|getHTTP()]], [[#postHTTP|postHTTP()]], [[#putHTTP|putHTTP()]], [[#deleteHTTP|deleteHTTP()]]. | ||
+ | ;Parameters: | ||
+ | * ''method:'' | ||
+ | : Http method to use (eg. PATCH, HEAD etc.) | ||
+ | * ''dataToSend:'' | ||
+ | : Text to send in the request (unless you provide a file to upload). | ||
+ | * ''url:'' | ||
+ | : Location to send the request to. | ||
+ | * ''headersTable:'' | ||
+ | : (optional) table of headers to send with your request. | ||
+ | * ''file:'' | ||
+ | : (optional) file to upload as part of the PUT request. If provided, this will replace 'dataToSend'. | ||
+ | |||
+ | {{MudletVersion|4.11}} | ||
+ | |||
+ | ;Example | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | function onCustomHttpDone(_, url, body, method) | ||
+ | cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s<white>, method: <dark_green>%s", url, body, method)) | ||
+ | end | ||
+ | |||
+ | registerAnonymousEventHandler("sysCustomHttpDone", sysCustomHttpDone) | ||
+ | |||
+ | customHTTP("PATCH", "this us a request with custom headers", "https://httpbin.org/put", {["X-am-I-awesome"] = "yep I am"}) | ||
+ | customHTTP("PATCH", "https://httpbin.org/put", "<fill in file location to upload here>") | ||
+ | </syntaxhighlight> | ||
[[Category:Mudlet API]] | [[Category:Mudlet API]] | ||
[[Category:Mudlet Manual]] | [[Category:Mudlet Manual]] |
Latest revision as of 02:11, 22 October 2024
Networking Functions
A collection of functions for managing networking.
connectToServer
- connectToServer(host, port, [save])
- Connects to a given game.
- Parameters
- host:
- Server domain or IP address.
- port:
- Servers port.
- save:
- (optional, boolean) if provided, saves the new connection parameters in the profile so they'll be used next time you open it.
Note: save is available in Mudlet 3.2+.
- Example
connectToServer("midnightsun2.org", 3000)
-- save to disk so these parameters are used next time when opening the profile
connectToServer("midnightsun2.org", 3000, true)
disconnect
- disconnect()
- Disconnects you from the game right away. Note that this will not properly log you out of the game - use an ingame command for that. Such commands vary, but typically QUIT will work.
- See also: reconnect()
- Example
disconnect()
downloadFile
- downloadFile(saveto, url)
- Downloads the resource at the given url into the saveto location on disk. This does not pause the script until the file is downloaded - instead, it lets it continue right away and downloads in the background. When a download is finished, the sysDownloadDone event is raised (with the saveto location as the argument), or when a download fails, the sysDownloadError event is raised with the reason for failure. You may call downloadFile multiple times and have multiple downloads going on at once - but they aren’t guaranteed to be downloaded in the same order that you started them in.
- See also: getHTTP(), postHTTP(), putHTTP(), deleteHTTP()
Note: Since Mudlet 3.0, https downloads are supported and the actual url that was used for the download is returned - useful in case of redirects.
- Example
-- just download a file and save it in our profile folder
local saveto = getMudletHomeDir().."/dark-theme-mudlet.zip"
local url = "http://www.mudlet.org/wp-content/files/dark-theme-mudlet.zip"
downloadFile(saveto, url)
cecho("<white>Downloading <green>"..url.."<white> to <green>"..saveto.."\n")
A more advanced example that downloads a webpage, reads it, and prints a result from it:
-- create a function to parse the downloaded webpage and display a result
function downloaded_file(_, filename)
-- is the file that downloaded ours?
if not filename:find("achaea-who-count.html", 1, true) then return end
-- read the contents of the webpage in
local f, s, webpage = io.open(filename)
if f then webpage = f:read("*a"); io.close(f) end
-- delete the file on disk, don't clutter
os.remove(filename)
-- parse our downloaded file for the player count
local pc = webpage:match([[Total: (%d+) players online]])
display("Achaea has "..tostring(pc).." players on right now.")
end
-- register our function to run on the event that something was downloaded
registerAnonymousEventHandler("sysDownloadDone", "downloaded_file")
-- download a list of fake users for a demo
downloadFile(getMudletHomeDir().."/achaea-who-count.html", "https://www.achaea.com/game/who")
Result should look like this:
getConnectionInfo
- getConnectionInfo()
- Returns the server address and port that you're currently connected to, and (in Mudlet 4.12+)
true
orfalse
indicating if you're currently connected to a game. - See also: connectToServer()
- Example
local host, port, connected = getConnectionInfo()
cecho(string.format("<light_grey>Playing on <forest_green>%s:%s<light_grey>, currently connected? <forest_green>%s\n", host, port, tostring(connected)))
-- echo the new connection parameters whenever we connect to a different host with connectToServer()
function echoInfo()
local host, port = getConnectionInfo()
cecho(string.format("<light_grey>Now connected to <forest_green>%s:%s\n", host, port))
end
registerAnonymousEventHandler("sysConnectionEvent", "echoInfo")
getIrcChannels
- getIrcChannels()
- Returns a list of channels the IRC client is joined to as a lua table. If the client is not yet started the value returned is loaded from disk and represents channels the client will auto-join when started.
- See also: setIrcChannels()
- Example
display(getIrcChannels())
-- Prints: {"#mudlet", "#lua"}
getIrcConnectedHost
- getIrcConnectedHost()
- Returns true+host where host is a string containing the host name of the IRC server, as given to the client by the server while starting the IRC connection. If the client has not yet started or finished connecting this will return false and an empty string.
- This function can be particularly useful for testing if the IRC client has connected to a server prior to sending data, and it will not auto-start the IRC client.
- The hostname value this function returns can be used to test if sysIrcMessage events are sent from the server or a user on the network.
- Example
local status, hostname = getIrcConnectedHost()
if status == true then
-- do something with connected IRC, send IRC commands, store 'hostname' elsewhere.
-- if sysIrcMessage sender = hostname from above, message is likely a status, command response, or an error from the Server.
else
-- print a status, change connection settings, or just continue waiting to send IRC data.
end
getIrcNick
- getIrcNick()
- Returns a string containing the IRC client nickname. If the client is not yet started, your default nickname is loaded from IRC client configuration.
- See also: setIrcNick()
- Example
local nick = getIrcNick()
echo(nick)
-- Prints: "Sheldor"
getIrcServer
- getIrcServer()
- Returns the IRC client server name and port as a string and a number respectively. If the client is not yet started your default server is loaded from IRC client configuration.
- See also: setIrcServer()
- Example
local server, port = getIrcServer()
echo("server: "..server..", port: "..port.."\n")
getNetworkLatency
- getNetworkLatency()
- Returns the last measured response time between the sent command and the server reply in seconds - e.g. 0.058 (=58 milliseconds lag) or 0.309 (=309 milliseconds). This is the N: number you see bottom-right of Mudlet.
Also known as server lag.
- Example
if getNetworkLatency() > 3 then
send("say This game is soooo laggy!")
end
openUrl
- openUrl (url)
- Opens the default OS browser for the given URL.
- Example
openUrl("http://google.com")
openUrl("www.mudlet.org")
reconnect
- reconnect()
- Force-reconnects (so if you're connected, it'll disconnect) you to the game.
- Example
-- you could trigger this on a log out message to reconnect, if you'd like
reconnect()
restartIrc
- restartIrc()
- Restarts the IRC client connection, reloading configurations from disk before reconnecting the IRC client.
sendAll
- sendAll(list of things to send, [echo back or not])
- sends multiple things to the game. If you'd like the commands not to be shown, include false at the end.
- See also: send()
- Example
-- instead of using many send() calls, you can use one sendAll
sendAll("outr paint", "outr canvas", "paint canvas")
-- can also have the commands not be echoed
sendAll("hi", "bye", false)
sendATCP
- sendATCP(message, what)
- Need description
- See also: ATCP Protocol, ATCP Extensions, Achaea Telnet Client Protocol specification, Description by forum user KaVir (2013), Description by forum user Iocun (2009)
- Parameters
- message:
- The message that you want to send.
- what:
- Need description
- Example
Need example
sendGMCP
- sendGMCP(command)
- Sends a GMCP message to the server. The IRE document on GMCP has information about what can be sent, and what tables it will use, etcetera.
- Note that this function is rarely used in practice. For most GMCP modules, the messages are automatically sent by the server when a relevant event happens in the game. For example, LOOKing in your room prompts the server to send the room description and contents, as well as the GMCP message gmcp.Room. A call to sendGMCP would not be required in this case.
- When playing an IRE game, a call to
send(" ")
afterwards is necessary due to a bug in the game with compression (MCCP) is enabled.
- See also: GMCP Scripting for Discord status
- Example
--This would send "Core.KeepAlive" to the server, which resets the timeout
sendGMCP("Core.KeepAlive")
--This would send a request for the server to send an update to the gmcp.Char.Skills.Groups table.
sendGMCP("Char.Skills.Get {}")
--This would send a request for the server to send a list of the skills in the
--vision group to the gmcp.Char.Skills.List table.
sendGMCP("Char.Skills.Get " .. yajl.to_string{group = "vision"})
--And finally, this would send a request for the server to send the info for
--hide in the woodlore group to the gmcp.Char.Skills.Info table
sendGMCP("Char.Skills.Get " .. yajl.to_string{group="MWP", name="block"})
sendIrc
- sendIrc(target, message)
- Sends a message to an IRC channel or person. Returns true+status if message could be sent or was successfully processed by the client, or nil+error if the client is not ready for sending, and false+status if the client filtered the message or failed to send it for some reason. If the IRC client hasn't started yet, this function will initiate the IRC client and begin a connection.
To receive an IRC message, check out the sysIrcMessage event.
Note: Since Mudlet 3.3, auto-opens the IRC window and returns the success status.
- Parameters
- target:
- nick or channel name and if omitted will default to the first available channel in the list of joined channels.
- message:
- The message to send, may contain IRC client commands which start with
/
and can use all commands which are available through the client window.
- Example
-- this would send "hello from Mudlet!" to the channel #mudlet on freenode.net
sendIrc("#mudlet", "hello from Mudlet!")
-- this would send "identify password" in a private message to Nickserv on freenode.net
sendIrc("Nickserv", "identify password")
-- use an in-built IRC command
sendIrc("#mudlet", "/topic")
Note: The following IRC commands are available since Mudlet 3.3:
- /ACTION <target> <message...>
- /ADMIN (<server>)
- /AWAY (<reason...>)
- /CLEAR (<buffer>) -- Clears the text log for the given buffer name. Uses the current active buffer if none are given.
- /CLOSE (<buffer>) -- Closes the buffer and removes it from the Buffer list. Uses the current active buffer if none are given.
- /HELP (<command>) -- Displays some help information about a given command or lists all available commands.
- /INFO (<server>)
- /INVITE <user> (<#channel>)
- /JOIN <#channel> (<key>)
- /KICK (<#channel>) <user> (<reason...>)
- /KNOCK <#channel> (<message...>)
- /LIST (<channels>) (<server>)
- /ME [target] <message...>
- /MODE (<channel/user>) (<mode>) (<arg>)
- /MOTD (<server>)
- /MSG <target> <message...> -- Sends a message to target, can be used to send Private messages.
- /NAMES (<#channel>)
- /NICK <nick>
- /NOTICE <#channel/user> <message...>
- /PART (<#channel>) (<message...>)
- /PING (<user>)
- /RECONNECT -- Issues a Quit command to the IRC Server and closes the IRC connection then reconnects to the IRC server. The same as calling ircRestart() in Lua.
- /QUIT (<message...>)
- /QUOTE <command> (<parameters...>)
- /STATS <query> (<server>)
- /TIME (<user>)
- /TOPIC (<#channel>) (<topic...>)
- /TRACE (<target>)
- /USERS (<server>)
- /VERSION (<user>)
- /WHO <mask>
- /WHOIS <user>
- /WHOWAS <user>
Note: The following IRC commands are available since Mudlet 3.15:
- /MSGLIMIT <limit> (<buffer>) -- Sets the limit for messages to keep in the IRC client message buffers and saves this setting. If a specific buffer/channel name is given the limit is not saved and applies to the given buffer until the application is closed or the limit is changed again. For this reason, global settings should be applied first, before settings for specific channels/PM buffers.
sendMSDP
- sendMSDP(variable[, value][, value...])
- Sends a MSDP message to the server.
- Parameters
- variable:
- The variable, in MSDP terms, that you want to request from the server.
- value:
- The variables value that you want to request. You can request more than one value at a time.
- Example
-- ask for a list of commands, lists, and reportable variables that the server supports
sendMSDP("LIST", "COMMANDS", "LISTS", "REPORTABLE_VARIABLES")
-- ask the server to start keeping you up to date on your health
sendMSDP("REPORT", "HEALTH")
-- or on your health and location
sendMSDP("REPORT", "HEALTH", "ROOM_VNUM", "ROOM_NAME")
sendTelnetChannel102
- sendTelnetChannel102(msg)
- Sends a message via the 102 subchannel back to the game (that's used in Aardwolf). The msg is in a two byte format; see the link below to the Aardwolf Wiki for how that works.
- Example
-- turn prompt flags on:
sendTelnetChannel102("\52\1")
-- turn prompt flags off:
sendTelnetChannel102("\52\2")
To see the list of options that Aardwolf supports go to: Using Telnet negotiation to control MUD client interaction.
setIrcChannels
- setIrcChannels(channels)
- Saves the given channels to disk as the new IRC client channel auto-join configuration. This value is not applied to the current active IRC client until it is restarted with restartIrc()
- See also: getIrcChannels(), restartIrc()
- Parameters
- channels:
- A table containing strings which are valid channel names. Any channels in the list which aren't valid are removed from the list.
- Example
setIrcChannels( {"#mudlet", "#lua", "irc"} )
-- Only the first two will be accepted, as "irc" is not a valid channel name.
setIrcNick
- setIrcNick(nickname)
- Saves the given nickname to disk as the new IRC client configuration. This value is not applied to the current active IRC client until it is restarted with restartIrc()
- See also: getIrcNick(), restartIrc()
- Parameters
- nickname:
- A string with your new desired name in IRC.
- Example
setIrcNick( "Sheldor" )
setIrcServer
- setIrcServer(hostname, port[, secure])
- Saves the given server's address to disk as the new IRC client connection configuration. These values are not applied to the current active IRC client until it is restarted with restartIrc()
- See also: getIrcServer(), restartIrc()
- Parameters
- hostname:
- A string containing the hostname of the IRC server.
- port:
- (optional) A number indicating the port of the IRC server. Defaults to 6667, if not provided.
- secure:
- (optional) Boolean, true if server uses Transport Layer Security. Defaults to false.
- Example
setIrcServer("irc.libera.chat", 6667)
getHTTP
- getHTTP(url, headersTable)
- Sends an HTTP GET request to the given URL. Raises sysGetHttpDone on success or sysGetHttpError on failure.
- See also: downloadFile().
- Parameters
- url:
- Location to send the request to.
- headersTable:
- (optional) table of headers to send with your request.
- Examples
function onHttpGetDone(_, url, body)
cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body))
end
registerAnonymousEventHandler("sysGetHttpDone", onHttpGetDone)
getHTTP("https://httpbin.org/info")
getHTTP("https://httpbin.org/are_you_awesome", {["X-am-I-awesome"] = "yep I am"})
-- Status requests typically use GET requests
local url = "http://postman-echo.com/status"
local header = {["Content-Type"] = "application/json"}
-- first we create something to handle the success, and tell us what we got
registerAnonymousEventHandler('sysGetHttpDone', function(event, rurl, response)
if rurl == url then display(r) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
end, true) -- this sets it to delete itself after it fires
-- then we create something to handle the error message, and tell us what went wrong
registerAnonymousEventHandler('sysGetHttpError', function(event, response, rurl)
if rurl == url then display(r) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
end, true) -- this sets it to delete itself after it fires
-- Lastly, we make the request:
getHTTP(url, header)
-- Pop this into an alias and try it yourself!
postHTTP
- postHTTP(dataToSend, url, headersTable, file)
- Sends an HTTP POST request to the given URL, either as text or with a specific file you'd like to upload. Raises sysPostHttpDone on success or sysPostHttpError on failure.
- See also: downloadFile(), getHTTP(), putHTTP(), deleteHTTP().
- Parameters
- dataToSend:
- Text to send in the request (unless you provide a file to upload).
- url:
- Location to send the request to.
- headersTable:
- (optional) table of headers to send with your request.
- file:
- (optional) file to upload as part of the POST request. If provided, this will replace 'dataToSend'.
- If you use a scripting language (ex. PHP) to handle this post, remember that the file is sent as raw data. Expecially no field name is provided, dispite it works in common html post.
- Examples
function onHttpPostDone(_, url, body)
cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body))
end
registerAnonymousEventHandler("sysPostHttpDone", onHttpPostDone)
postHTTP("why hello there!", "https://httpbin.org/post")
postHTTP("this us a request with custom headers", "https://httpbin.org/post", {["X-am-I-awesome"] = "yep I am"})
postHTTP(nil, "https://httpbin.org/post", {}, "<fill in file location to upload here, maybe get from invokeFileDialog>")
-- This will create a JSON message body. Many modern REST APIs expect a JSON body.
local url = "http://postman-echo.com/post"
local data = {message = "I am the banana", user = "admin"}
local header = {["Content-Type"] = "application/json"}
-- first we create something to handle the success, and tell us what we got
registerAnonymousEventHandler('sysPostHttpDone', function(event, rurl, response)
if rurl == url then display(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
end, true) -- this sets it to delete itself after it fires
-- then we create something to handle the error message, and tell us what went wrong
registerAnonymousEventHandler('sysPostHttpError', function(event, response, rurl)
if rurl == url then display(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
end, true) -- this sets it to delete itself after it fires
-- Lastly, we make the request:
postHTTP(yajl.to_string(data), url, header) -- yajl.to_string converts our Lua table into a JSON-like string so the server can understand it
-- Pop this into an alias and try it yourself!
- HTTP Basic Authentication Example
If your HTTP endpoint requires authentication to post data, HTTP Basic Authentication is a common method for doing so. There are two ways to do so.
OPTION 1: URL encoding: Many HTTP servers allow you to enter a HTTP Basic Authentication username and password at the beginning of the URL itself, in format: https://username:[email protected]/path/to/endpoint
OPTION 2: Authorization Header: Some HTTP servers may require you to put your Basic Authentication into the 'Authorization' HTTP header value.
This requires encoding the username:password into base64. For example, if your username is 'user' and your password is '12345', you'd need to run the string "user:12345" through a base64 encoder, which would result in the string: dXNlcjoxMjM0NQ==
Then, you'd need to set the HTTP header 'Authorization' field value to indicate it is using Basic auth and inserting the base64 string as: ['Authorization'] = "Basic dXNlcjoxMjM0NQ=="
As you're encoding your username and password, you probably want to do this encoding locally for security reasons. You also probably want to only use https:// and not http:// when sending usernames and passwords over the internet.
In the HTTP Basic Authentication example below, there is an inline base64Encode() function included:
function base64Encode(data)
-- Lua 5.1+ base64 v3.0 (c) 2009 by Alex Kloss <[email protected]>
-- licensed under the terms of the LGPL2
local b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
return ((data:gsub('.', function(x)
local r,b='',x:byte()
for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
return r;
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if (#x < 6) then return '' end
local c=0
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
return b:sub(c+1,c+1)
end)..({ '', '==', '=' })[#data%3+1])
end
-- Example: base64Encode("user:12345") -> dXNlcjoxMjM0NQ==
function postJSON(url,dataTable,headerTable)
-- This will create a JSON message body. Many modern REST APIs expect a JSON body.
local data = dataTable or {text = "hello world"}
local header = headerTable or {["Content-Type"] = "application/json"}
-- first we create something to handle the success, and tell us what we got
registerAnonymousEventHandler('sysPostHttpDone', function(event, rurl, response)
if rurl == url then sL("HTTP response success"); echo(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
end, true) -- this sets it to delete itself after it fires
-- then we create something to handle the error message, and tell us what went wrong
registerAnonymousEventHandler('sysPostHttpError', function(event, response, rurl)
if rurl == url then sL("HTTP response error",3); echo(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
end, true) -- this sets it to delete itself after it fires
-- Lastly, we make the request:
postHTTP(yajl.to_string(data), url, header) -- yajl.to_string converts our Lua table into a JSON-like string so the server can understand it
end
data = {
message = "I am the banana",
user = "admin"
}
header = {
["Content-Type"] = "application/json",
["Authorization"] = "Basic " .. base64Encode("user:12345")
}
postJSON("http://postman-echo.com/post",data,header)
- URL Encoding vs JSON encoding
Some HTTP endpoints may not support JSON encoding, and instead may require URL encoding. Here's an example function to convert your lua data table into a URL encoded string::
-- Example: URLEncodeTable({message="hello",person="world"}) -> "message=hello&person=world"
function URLEncodeTable(Args)
-- From: https://help.interfaceware.com/code/details/urlcode-lua
----------------------------------------------------------------------------
-- URL-encode the elements of a table creating a string to be used in a
-- URL for passing data/parameters to another script
-- @param args Table where to extract the pairs (name=value).
-- @return String with the resulting encoding.
----------------------------------------------------------------------------
--
local ipairs, next, pairs, tonumber, type = ipairs, next, pairs, tonumber, type
local string = string
local table = table
--helper functions:
----------------------------------------------------------------------------
-- Decode an URL-encoded string (see RFC 2396)
----------------------------------------------------------------------------
local unescape = function (str)
str = string.gsub (str, "+", " ")
str = string.gsub (str, "%%(%x%x)", function(h) return string.char(tonumber(h,16)) end)
return str
end
----------------------------------------------------------------------------
-- URL-encode a string (see RFC 2396)
----------------------------------------------------------------------------
local escape = function (str)
str = string.gsub (str, "([^0-9a-zA-Z !'()*._~-])", -- locale independent
function (c) return string.format ("%%%02X", string.byte(c)) end)
str = string.gsub (str, " ", "+")
return str
end
----------------------------------------------------------------------------
-- Insert a (name=value) pair into table [[args]]
-- @param args Table to receive the result.
-- @param name Key for the table.
-- @param value Value for the key.
-- Multi-valued names will be represented as tables with numerical indexes
-- (in the order they came).
----------------------------------------------------------------------------
local insertfield = function (args, name, value)
if not args[name] then
args[name] = value
else
local t = type (args[name])
if t == "string" then
args[name] = {args[name],value,}
elseif t == "table" then
table.insert (args[name], value)
else
error ("CGILua fatal error (invalid args table)!")
end
end
end
-- end helper functions
if Args == nil or next(Args) == nil then -- no args or empty args?
return ""
end
local strp = ""
for key, vals in pairs(Args) do
if type(vals) ~= "table" then
vals = {vals}
end
for i,val in ipairs(vals) do
strp = strp.."&"..key.."="..escape(val)
end
end
-- remove first &
return string.sub(strp,2)
end
putHTTP
- putHTTP(dataToSend, url, [headersTable], [file])
- Sends an HTTP PUT request to the given URL, either as text or with a specific file you'd like to upload. Raises sysPutHttpDone on success or sysPutHttpError on failure.
- See also: downloadFile(), getHTTP(), postHTTP(), deleteHTTP().
- Parameters
- dataToSend:
- Text to send in the request (unless you provide a file to upload).
- url:
- Location to send the request to.
- headersTable:
- (optional) table of headers to send with your request.
- file:
- (optional) file to upload as part of the PUT request. If provided, this will replace 'dataToSend'.
- Example
function onHttpPutDone(_, url, body)
cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body))
end
registerAnonymousEventHandler("sysPutHttpDone", onHttpPutDone)
putHTTP("this us a request with custom headers", "https://httpbin.org/put", {["X-am-I-awesome"] = "yep I am"})
putHTTP("https://httpbin.org/put", "<fill in file location to upload here>")
deleteHTTP
- deleteHTTP(url, headersTable)
- Sends an HTTP DELETE request to the given URL. Raises sysDeleteHttpDone on success or sysDeleteHttpError on failure.
- See also: downloadFile(), getHTTP(), postHTTP(), putHTTP().
- Parameters
- url:
- Location to send the request to.
- headersTable:
- (optional) table of headers to send with your request.
- Example
function onHttpDeleteDone(_, url, body)
cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body))
end
registerAnonymousEventHandler("sysDeleteHttpDone", onHttpDeleteDone)
deleteHTTP("https://httpbin.org/delete")
deleteHTTP("https://httpbin.org/delete", {["X-am-I-awesome"] = "yep I am"})
customHTTP
- customHTTP(method, url, headersTable)
- Sends an custom method request to the given URL. Raises sysCustomHttpDone on success or sysCustomHttpError on failure.
- See also: downloadFile(), getHTTP(), postHTTP(), putHTTP(), deleteHTTP().
- Parameters
- method:
- Http method to use (eg. PATCH, HEAD etc.)
- dataToSend:
- Text to send in the request (unless you provide a file to upload).
- url:
- Location to send the request to.
- headersTable:
- (optional) table of headers to send with your request.
- file:
- (optional) file to upload as part of the PUT request. If provided, this will replace 'dataToSend'.
- Example
function onCustomHttpDone(_, url, body, method)
cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s<white>, method: <dark_green>%s", url, body, method))
end
registerAnonymousEventHandler("sysCustomHttpDone", sysCustomHttpDone)
customHTTP("PATCH", "this us a request with custom headers", "https://httpbin.org/put", {["X-am-I-awesome"] = "yep I am"})
customHTTP("PATCH", "https://httpbin.org/put", "<fill in file location to upload here>")