main.cpp 2.3 KB

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