comparison Core/Lua/LuaContext.cpp @ 1055:6f923d52a46c

call Web services from Lua
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 24 Jul 2014 11:37:02 +0200
parents cc4ff680e2a0
children 6e7e5ed91c2d
comparison
equal deleted inserted replaced
1054:1701dcb6f554 1055:6f923d52a46c
92 92
93 return 0; 93 return 0;
94 } 94 }
95 95
96 96
97 bool LuaContext::DoHttpQuery(lua_State* state, 97 int LuaContext::SetHttpCredentials(lua_State *state)
98 bool isJson) 98 {
99 LuaContext& that = GetLuaContext(state);
100
101 // Check the types of the arguments
102 int nArgs = lua_gettop(state);
103 if (nArgs != 2 ||
104 !lua_isstring(state, 1) || // Username
105 !lua_isstring(state, 2)) // Password
106 {
107 LOG(ERROR) << "Lua: Bad parameters to SetHttpCredentials()";
108 }
109 else
110 {
111 // Configure the HTTP client
112 const char* username = lua_tostring(state, 1);
113 const char* password = lua_tostring(state, 2);
114 that.httpClient_.SetCredentials(username, password);
115 }
116
117 return 0;
118 }
119
120
121 bool LuaContext::AnswerHttpQuery(lua_State* state)
99 { 122 {
100 std::string str; 123 std::string str;
101 Json::Value json;
102 124
103 try 125 try
104 { 126 {
105 if (isJson) 127 httpClient_.Apply(str);
106 {
107 httpClient_.Apply(json);
108 }
109 else
110 {
111 httpClient_.Apply(str);
112 }
113 } 128 }
114 catch (OrthancException& e) 129 catch (OrthancException& e)
115 { 130 {
116 return false; 131 return false;
117 } 132 }
118 133
119 // Return the result of the HTTP request 134 // Return the result of the HTTP request
120 if (isJson) 135 lua_pushstring(state, str.c_str());
121 {
122 PushJson(json);
123 }
124 else
125 {
126 lua_pushstring(state, str.c_str());
127 }
128 136
129 return true; 137 return true;
130 } 138 }
131 139
132 140
133 int LuaContext::CallHttpGet(lua_State *state) 141 int LuaContext::CallHttpGet(lua_State *state)
142 {
143 LuaContext& that = GetLuaContext(state);
144
145 // Check the types of the arguments
146 int nArgs = lua_gettop(state);
147 if (nArgs != 1 || !lua_isstring(state, 1)) // URL
148 {
149 LOG(ERROR) << "Lua: Bad parameters to HttpGet()";
150 lua_pushstring(state, "ERROR");
151 return 1;
152 }
153
154 // Configure the HTTP client class
155 const char* url = lua_tostring(state, 1);
156 that.httpClient_.SetMethod(HttpMethod_Get);
157 that.httpClient_.SetUrl(url);
158
159 // Do the HTTP GET request
160 if (!that.AnswerHttpQuery(state))
161 {
162 LOG(ERROR) << "Lua: Error in HttpGet() for URL " << url;
163 lua_pushstring(state, "ERROR");
164 }
165
166 return 1;
167 }
168
169
170 int LuaContext::CallHttpPostOrPut(lua_State *state,
171 HttpMethod method)
134 { 172 {
135 LuaContext& that = GetLuaContext(state); 173 LuaContext& that = GetLuaContext(state);
136 174
137 // Check the types of the arguments 175 // Check the types of the arguments
138 int nArgs = lua_gettop(state); 176 int nArgs = lua_gettop(state);
139 if ((nArgs != 1 && nArgs != 2) || 177 if ((nArgs != 1 && nArgs != 2) ||
140 !lua_isstring(state, 1) || // URL 178 !lua_isstring(state, 1) || // URL
141 (nArgs >= 2 && !lua_isboolean(state, 2))) // Interpret result as JSON 179 (nArgs >= 2 && !lua_isstring(state, 2))) // Body data
142 { 180 {
143 LOG(ERROR) << "Lua: Bad parameters to HttpGet()"; 181 LOG(ERROR) << "Lua: Bad parameters to HttpPost() or HttpPut()";
144 lua_pushstring(state, "ERROR"); 182 lua_pushstring(state, "ERROR");
145 return 1; 183 return 1;
146 } 184 }
147 185
148 // Configure the HTTP client class 186 // Configure the HTTP client class
149 const char* url = lua_tostring(state, 1); 187 const char* url = lua_tostring(state, 1);
150 bool isJson = (nArgs >= 2 && lua_toboolean(state, 2));
151 that.httpClient_.SetMethod(HttpMethod_Get);
152 that.httpClient_.SetUrl(url);
153
154 // Do the HTTP GET request
155 if (!that.DoHttpQuery(state, isJson))
156 {
157 LOG(ERROR) << "Lua: Error in HttpGet() for URL " << url;
158 lua_pushstring(state, "ERROR");
159 }
160
161 return 1;
162 }
163
164
165 int LuaContext::CallHttpPostOrPut(lua_State *state,
166 HttpMethod method)
167 {
168 LuaContext& that = GetLuaContext(state);
169
170 // Check the types of the arguments
171 int nArgs = lua_gettop(state);
172 if ((nArgs != 1 && nArgs != 2 && nArgs != 3) ||
173 !lua_isstring(state, 1) || // URL
174 (nArgs >= 2 && !lua_isstring(state, 2)) || // Body data
175 (nArgs >= 3 && !lua_isboolean(state, 3))) // Interpret result as JSON
176 {
177 LOG(ERROR) << "Lua: Bad parameters to HttpPost() or HttpPut()";
178 lua_pushstring(state, "ERROR");
179 return 1;
180 }
181
182 // Configure the HTTP client class
183 const char* url = lua_tostring(state, 1);
184 bool isJson = (nArgs >= 3 && lua_toboolean(state, 3));
185 that.httpClient_.SetMethod(method); 188 that.httpClient_.SetMethod(method);
186 that.httpClient_.SetUrl(url); 189 that.httpClient_.SetUrl(url);
187 190
188 if (nArgs >= 2) 191 if (nArgs >= 2)
189 { 192 {
193 { 196 {
194 that.httpClient_.AccessPostData().clear(); 197 that.httpClient_.AccessPostData().clear();
195 } 198 }
196 199
197 // Do the HTTP POST/PUT request 200 // Do the HTTP POST/PUT request
198 if (!that.DoHttpQuery(state, isJson)) 201 if (!that.AnswerHttpQuery(state))
199 { 202 {
200 LOG(ERROR) << "Lua: Error in HttpPost() or HttpPut() for URL " << url; 203 LOG(ERROR) << "Lua: Error in HttpPost() or HttpPut() for URL " << url;
201 lua_pushstring(state, "ERROR"); 204 lua_pushstring(state, "ERROR");
202 } 205 }
203 206
237 240
238 // Do the HTTP DELETE request 241 // Do the HTTP DELETE request
239 std::string s; 242 std::string s;
240 if (!that.httpClient_.Apply(s)) 243 if (!that.httpClient_.Apply(s))
241 { 244 {
242 LOG(ERROR) << "Lua: Error in HttpPost() for URL " << url; 245 LOG(ERROR) << "Lua: Error in HttpDelete() for URL " << url;
243 lua_pushstring(state, "ERROR"); 246 lua_pushstring(state, "ERROR");
244 } 247 }
245 else 248 else
246 { 249 {
247 lua_pushstring(state, "SUCCESS"); 250 lua_pushstring(state, "SUCCESS");
332 lua_register(lua_, "print", PrintToLog); 335 lua_register(lua_, "print", PrintToLog);
333 lua_register(lua_, "HttpGet", CallHttpGet); 336 lua_register(lua_, "HttpGet", CallHttpGet);
334 lua_register(lua_, "HttpPost", CallHttpPost); 337 lua_register(lua_, "HttpPost", CallHttpPost);
335 lua_register(lua_, "HttpPut", CallHttpPut); 338 lua_register(lua_, "HttpPut", CallHttpPut);
336 lua_register(lua_, "HttpDelete", CallHttpDelete); 339 lua_register(lua_, "HttpDelete", CallHttpDelete);
340 lua_register(lua_, "SetHttpCredentials", SetHttpCredentials);
337 341
338 lua_pushlightuserdata(lua_, this); 342 lua_pushlightuserdata(lua_, this);
339 lua_setglobal(lua_, "_LuaContext"); 343 lua_setglobal(lua_, "_LuaContext");
340 } 344 }
341 345
344 { 348 {
345 lua_close(lua_); 349 lua_close(lua_);
346 } 350 }
347 351
348 352
349 void LuaContext::Execute(std::string* output, 353 void LuaContext::ExecuteInternal(std::string* output,
350 const std::string& command) 354 const std::string& command)
351 { 355 {
352 log_.clear(); 356 log_.clear();
353 int error = (luaL_loadbuffer(lua_, command.c_str(), command.size(), "line") || 357 int error = (luaL_loadbuffer(lua_, command.c_str(), command.size(), "line") ||
354 lua_pcall(lua_, 0, 0, 0)); 358 lua_pcall(lua_, 0, 0, 0));
355 359
357 { 361 {
358 assert(lua_gettop(lua_) >= 1); 362 assert(lua_gettop(lua_) >= 1);
359 363
360 std::string description(lua_tostring(lua_, -1)); 364 std::string description(lua_tostring(lua_, -1));
361 lua_pop(lua_, 1); /* pop error message from the stack */ 365 lua_pop(lua_, 1); /* pop error message from the stack */
366 LOG(ERROR) << "Error while executing Lua script: " << description;
362 throw LuaException(description); 367 throw LuaException(description);
363 } 368 }
364 369
365 if (output != NULL) 370 if (output != NULL)
366 { 371 {
371 376
372 void LuaContext::Execute(EmbeddedResources::FileResourceId resource) 377 void LuaContext::Execute(EmbeddedResources::FileResourceId resource)
373 { 378 {
374 std::string command; 379 std::string command;
375 EmbeddedResources::GetFileResource(command, resource); 380 EmbeddedResources::GetFileResource(command, resource);
376 Execute(command); 381 ExecuteInternal(NULL, command);
377 } 382 }
378 383
379 384
380 bool LuaContext::IsExistingFunction(const char* name) 385 bool LuaContext::IsExistingFunction(const char* name)
381 { 386 {
382 lua_settop(lua_, 0); 387 lua_settop(lua_, 0);
383 lua_getglobal(lua_, name); 388 lua_getglobal(lua_, name);
384 return lua_type(lua_, -1) == LUA_TFUNCTION; 389 return lua_type(lua_, -1) == LUA_TFUNCTION;
385 } 390 }
391
392
393 void LuaContext::Execute(Json::Value& output,
394 const std::string& command)
395 {
396 std::string s;
397 ExecuteInternal(&s, command);
398
399 Json::Reader reader;
400 if (!reader.parse(s, output))
401 {
402 throw OrthancException(ErrorCode_BadFileFormat);
403 }
404 }
405
386 } 406 }