main.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. extern "C"
  2. {
  3. #include <lua.h>
  4. #include <lauxlib.h>
  5. }
  6. #include "../common/HTTPS.h"
  7. #include "../common/config.h"
  8. static std::string w_checkstring(lua_State *L, int idx)
  9. {
  10. size_t len;
  11. const char *str = luaL_checklstring(L, idx, &len);
  12. return std::string(str, len);
  13. }
  14. static void w_pushstring(lua_State *L, const std::string &str)
  15. {
  16. lua_pushlstring(L, str.data(), str.size());
  17. }
  18. static void w_readheaders(lua_State *L, int idx, HTTPSClient::header_map &headers)
  19. {
  20. if (idx < 0)
  21. idx += lua_gettop(L) + 1;
  22. lua_pushnil(L);
  23. while (lua_next(L, idx))
  24. {
  25. auto header = w_checkstring(L, -2);
  26. headers[header] = w_checkstring(L, -1);
  27. lua_pop(L, 1);
  28. }
  29. lua_pop(L, 1);
  30. }
  31. static HTTPSClient::Request::Method w_optmethod(lua_State *L, int idx, HTTPSClient::Request::Method defaultMethod)
  32. {
  33. if (lua_isnoneornil(L, idx))
  34. return defaultMethod;
  35. auto str = w_checkstring(L, idx);
  36. if (str == "get")
  37. return HTTPSClient::Request::GET;
  38. else if (str == "post")
  39. return HTTPSClient::Request::POST;
  40. else
  41. luaL_argerror(L, idx, "expected one of \"get\" or \"set\"");
  42. return defaultMethod;
  43. }
  44. static int w_request(lua_State *L)
  45. {
  46. auto url = w_checkstring(L, 1);
  47. HTTPSClient::Request req(url);
  48. bool advanced = false;
  49. if (lua_istable(L, 2))
  50. {
  51. advanced = true;
  52. HTTPSClient::Request::Method defaultMethod = HTTPSClient::Request::GET;
  53. lua_getfield(L, 2, "data");
  54. if (!lua_isnoneornil(L, -1))
  55. {
  56. req.postdata = w_checkstring(L, -1);
  57. defaultMethod = HTTPSClient::Request::POST;
  58. }
  59. lua_pop(L, 1);
  60. lua_getfield(L, 2, "method");
  61. req.method = w_optmethod(L, -1, defaultMethod);
  62. lua_pop(L, 1);
  63. lua_getfield(L, 2, "headers");
  64. if (!lua_isnoneornil(L, -1))
  65. w_readheaders(L, -1, req.headers);
  66. lua_pop(L, 1);
  67. }
  68. HTTPSClient::Reply reply;
  69. try
  70. {
  71. reply = request(req);
  72. }
  73. catch (const std::exception& e)
  74. {
  75. std::string errorMessage = e.what();
  76. lua_pushnil(L);
  77. lua_pushstring(L, errorMessage.c_str());
  78. return 2;
  79. }
  80. lua_pushinteger(L, reply.responseCode);
  81. w_pushstring(L, reply.body);
  82. if (advanced)
  83. {
  84. lua_newtable(L);
  85. for (const auto &header : reply.headers)
  86. {
  87. w_pushstring(L, header.first);
  88. w_pushstring(L, header.second);
  89. lua_settable(L, -3);
  90. }
  91. }
  92. return advanced ? 3 : 2;
  93. }
  94. extern "C" int HTTPS_DLLEXPORT luaopen_https(lua_State *L)
  95. {
  96. lua_newtable(L);
  97. lua_pushcfunction(L, w_request);
  98. lua_setfield(L, -2, "request");
  99. return 1;
  100. }