summaryrefslogtreecommitdiff
path: root/Data/DefaultContent/Libraries/json4lua/json/rpcserver.lua
blob: e01f1f86d2ce374b8d42221c8c30346fef949557 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
-----------------------------------------------------------------------------
-- JSONRPC4Lua: JSON RPC server for exposing Lua objects as JSON RPC callable
-- objects via http.
-- json.rpcserver Module. 
-- Author: Craig Mason-Jones
-- Homepage: http://github.com/craigmj/json4lua/
-- Version: 1.0.0
-- This module is released under the MIT License (MIT).
-- Please see LICENCE.txt for details.
--
-- USAGE:
-- This module exposes one function:
--   server(luaClass, packReturn)
--     Manages incoming JSON RPC request forwarding the method call to the given
--     object. If packReturn is true, multiple return values are packed into an 
--     array on return.
--
-- IMPORTANT NOTES:
--   1. This version ought really not be 0.9.10, since this particular part of the 
--      JSONRPC4Lua package is very first-draft. However, the JSON4Lua package with which
--      it comes is quite solid, so there you have it :-)
--   2. This has only been tested with Xavante webserver, with which it works 
--      if you patch CGILua to accept 'text/plain' content type. See doc\cgilua_patch.html
--      for details.
----------------------------------------------------------------------------

module ('json.rpcserver')

---
-- Implements a JSON RPC Server wrapping for luaClass, exposing each of luaClass's
-- methods as JSON RPC callable methods.
-- @param luaClass The JSON RPC class to expose.
-- @param packReturn If true, the server will automatically wrap any
-- multiple-value returns into an array. Single returns remain single returns. If
-- false, when a function returns multiple values, only the first of these values will
-- be returned.
--
function serve(luaClass, packReturn)
  cgilua.contentheader('text','plain')
  require('cgilua')
  require ('json')
  local postData = ""
  
  if not cgilua.servervariable('CONTENT_LENGTH') then
    cgilua.put("Please access JSON Request using HTTP POST Request")
    return 0
  else
    postData = cgi[1]	-- SAPI.Request.getpostdata()  --[[{ "id":1, "method":"echo","params":["Hi there"]}]]  --
  end
  -- @TODO Catch an error condition on decoding the data
  local jsonRequest = json.decode(postData)
  local jsonResponse = {}
  jsonResponse.id = jsonRequest.id
  local method = luaClass[ jsonRequest.method ]

  if not method then
	jsonResponse.error = 'Method ' .. jsonRequest.method .. ' does not exist at this server.'
  else
    local callResult = { pcall( method, unpack( jsonRequest.params ) ) }
    if callResult[1] then	-- Function call successfull
      table.remove(callResult,1)
      if packReturn and table.getn(callResult)>1 then
        jsonResponse.result = callResult
      else
        jsonResponse.result = unpack(callResult)	-- NB: Does not support multiple argument returns
      end
    else
      jsonResponse.error = callResult[2]
    end
  end 
  
  -- Output the result
  -- TODO: How to be sure that the result and error tags are there even when they are nil in Lua?
  -- Can force them by hand... ?
  cgilua.contentheader('text','plain')
  cgilua.put( json.encode( jsonResponse ) )
end