comparison Core/Lua/LuaContext.cpp @ 1051:92f4bf2c5d73

HTTP GET in Lua
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 23 Jul 2014 12:59:28 +0200
parents b067017a8a5b
children cc4ff680e2a0
comparison
equal deleted inserted replaced
1050:64f1842aae2e 1051:92f4bf2c5d73
42 #include <lauxlib.h> 42 #include <lauxlib.h>
43 } 43 }
44 44
45 namespace Orthanc 45 namespace Orthanc
46 { 46 {
47 int LuaContext::PrintToLog(lua_State *state) 47 LuaContext& LuaContext::GetLuaContext(lua_State *state)
48 { 48 {
49 // Get the pointer to the "LuaContext" underlying object 49 // Get the pointer to the "LuaContext" underlying object
50 lua_getglobal(state, "_LuaContext"); 50 lua_getglobal(state, "_LuaContext");
51 assert(lua_type(state, -1) == LUA_TLIGHTUSERDATA); 51 assert(lua_type(state, -1) == LUA_TLIGHTUSERDATA);
52 LuaContext* that = const_cast<LuaContext*>(reinterpret_cast<const LuaContext*>(lua_topointer(state, -1))); 52 LuaContext* that = const_cast<LuaContext*>(reinterpret_cast<const LuaContext*>(lua_topointer(state, -1)));
53 assert(that != NULL); 53 assert(that != NULL);
54 lua_pop(state, 1); 54 lua_pop(state, 1);
55 55
56 return *that;
57 }
58
59 int LuaContext::PrintToLog(lua_State *state)
60 {
61 LuaContext& that = GetLuaContext(state);
62
56 // http://medek.wordpress.com/2009/02/03/wrapping-lua-errors-and-print-function/ 63 // http://medek.wordpress.com/2009/02/03/wrapping-lua-errors-and-print-function/
57 int nArgs = lua_gettop(state); 64 int nArgs = lua_gettop(state);
58 lua_getglobal(state, "tostring"); 65 lua_getglobal(state, "tostring");
59 66
60 // Make sure you start at 1 *NOT* 0 for arrays in Lua. 67 // Make sure you start at 1 *NOT* 0 for arrays in Lua.
78 85
79 lua_pop(state, 1); 86 lua_pop(state, 1);
80 } 87 }
81 88
82 LOG(WARNING) << "Lua says: " << result; 89 LOG(WARNING) << "Lua says: " << result;
83 that->log_.append(result); 90 that.log_.append(result);
84 that->log_.append("\n"); 91 that.log_.append("\n");
85 92
86 return 0; 93 return 0;
94 }
95
96
97 int LuaContext::CallHttpGet(lua_State *state)
98 {
99 LuaContext& that = GetLuaContext(state);
100
101 // Check that there is 1 string argument
102 int nArgs = lua_gettop(state);
103 if ((nArgs != 1 && nArgs != 2) ||
104 !lua_isstring(state, 1) ||
105 (nArgs == 2 && !lua_isboolean(state, 2)))
106 {
107 LOG(ERROR) << "Lua: Bad URL in HttpGet";
108
109 lua_pushstring(state, "ERROR");
110 return 1;
111 }
112
113 // Configure the HTTP client class
114 const char* url = lua_tostring(state, 1);
115 bool isJson = (nArgs == 2 && lua_toboolean(state, 2));
116 that.httpClient_.SetMethod(HttpMethod_Get);
117 that.httpClient_.SetUrl(url);
118
119 // Do the HTTP GET request
120 std::string str;
121 Json::Value json;
122
123 try
124 {
125 if (isJson)
126 {
127 that.httpClient_.Apply(json);
128 }
129 else
130 {
131 that.httpClient_.Apply(str);
132 }
133 }
134 catch (OrthancException& e)
135 {
136 LOG(ERROR) << "Lua: Error in HttpGet for URL " << url << ": " << e.What();
137
138 lua_pushstring(state, "ERROR");
139 return 1;
140 }
141
142 // Return the result of the HTTP GET
143 if (isJson)
144 {
145 that.PushJson(json);
146 }
147 else
148 {
149 lua_pushstring(state, str.c_str());
150 }
151
152 return 1;
153 }
154
155
156 void LuaContext::PushJson(const Json::Value& value)
157 {
158 if (value.isString())
159 {
160 lua_pushstring(lua_, value.asCString());
161 }
162 else if (value.isDouble())
163 {
164 lua_pushnumber(lua_, value.asDouble());
165 }
166 else if (value.isInt())
167 {
168 lua_pushinteger(lua_, value.asInt());
169 }
170 else if (value.isUInt())
171 {
172 lua_pushinteger(lua_, value.asUInt());
173 }
174 else if (value.isBool())
175 {
176 lua_pushboolean(lua_, value.asBool());
177 }
178 else if (value.isNull())
179 {
180 lua_pushnil(lua_);
181 }
182 else if (value.isArray())
183 {
184 lua_newtable(lua_);
185
186 // http://lua-users.org/wiki/SimpleLuaApiExample
187 for (Json::Value::ArrayIndex i = 0; i < value.size(); i++)
188 {
189 // Push the table index (note the "+1" because of Lua conventions)
190 lua_pushnumber(lua_, i + 1);
191
192 // Push the value of the cell
193 PushJson(value[i]);
194
195 // Stores the pair in the table
196 lua_rawset(lua_, -3);
197 }
198 }
199 else if (value.isObject())
200 {
201 lua_newtable(lua_);
202
203 Json::Value::Members members = value.getMemberNames();
204
205 for (Json::Value::Members::const_iterator
206 it = members.begin(); it != members.end(); ++it)
207 {
208 // Push the index of the cell
209 lua_pushstring(lua_, it->c_str());
210
211 // Push the value of the cell
212 PushJson(value[*it]);
213
214 // Stores the pair in the table
215 lua_rawset(lua_, -3);
216 }
217 }
218 else
219 {
220 throw LuaException("Unsupported JSON conversion");
221 }
87 } 222 }
88 223
89 224
90 LuaContext::LuaContext() 225 LuaContext::LuaContext()
91 { 226 {
95 throw LuaException("Unable to create the Lua context"); 230 throw LuaException("Unable to create the Lua context");
96 } 231 }
97 232
98 luaL_openlibs(lua_); 233 luaL_openlibs(lua_);
99 lua_register(lua_, "print", PrintToLog); 234 lua_register(lua_, "print", PrintToLog);
235 lua_register(lua_, "HttpGet", CallHttpGet);
100 236
101 lua_pushlightuserdata(lua_, this); 237 lua_pushlightuserdata(lua_, this);
102 lua_setglobal(lua_, "_LuaContext"); 238 lua_setglobal(lua_, "_LuaContext");
103 } 239 }
104 240