#ifdef _WIN32 #include #define snprintf _snprintf #pragma comment(lib,"ws2_32") #else #include #include #endif #include #include #include #include #include #include #include #include #include "shttpd135.h" #include "api.h" #define HTM_TYPE 'W3' #define HTC_TYPE 'W4' #define MAX_LINE_LEN 1024 #define TAG1 "" class zsRegPrimitive { public: zsRegPrimitive(const char* name, int type, void* func) { api_add_primitive(name, type, func); } }; void input_error(void* caller) { api_runtime_error(caller, "bad arguments"); } void w3_destroy(void* ptr) { shttpd_fini((shttpd_ctx*)ptr); } int script_handler(shttpd_arg_t *arg) { arg->last = 1; arg->nout = 0; const char *ext = shttpd_get_userurl(arg); if (ext[0] != '.' && arg->user_data != 0) { void *p[1]; p[0] = api_create_user(arg->user_data, arg, 0, 0, HTC_TYPE); api_call_func(arg->user_data, 1, p); return arg->nout; } std::string fname("."); fname += shttpd_get_url(arg); FILE *f = fopen(fname.c_str(), "r"); if (!f) { fprintf(stderr, "Failed to open %s\n", fname.c_str()); return 0; } char buf[MAX_LINE_LEN]; std::string script; int loc1 = std::string::npos, loc2 = std::string::npos, count = 0; while (!feof(f)) { if (!fgets(buf, MAX_LINE_LEN-1, f)) continue; std::string tmp(buf); if (loc1 == std::string::npos) loc1 = tmp.find(TAG1, 0); if (loc1 == std::string::npos) { // html context arg->nout += snprintf(arg->buf+arg->nout, arg->buflen-arg->nout, "%s", buf); continue; } count++; if (count == 1) continue; loc2 = tmp.find(TAG2, 0); if (loc2 == std::string::npos) { script += tmp; continue; } void *module = api_parse_string(script.c_str(), buf); if (!module) { fprintf(stderr, "%s\n", buf); continue; } api_set_module_object(module, "HTTP_USER", arg, HTC_TYPE); if (api_exec_module(module, buf) <= 0) fprintf(stderr, "%s\n", buf); api_delete_module(module); script = ""; count = 0; loc1 = loc2 = std::string::npos; } fclose(f); return arg->nout; } void* w3_httpd(void *caller, int nargs, void** args) { if (nargs < 1) input_error(caller); shttpd_ctx *ctx = shttpd_init(NULL, "document_root", api_get_string(caller, args[0]), NULL); if (nargs > 1) shttpd_register_url(ctx, api_get_string(caller, args[1]), script_handler, 0); return api_create_user(caller, ctx, 0, w3_destroy, HTM_TYPE); } static zsRegPrimitive w3a("httpd", 0, w3_httpd); void* w3_version(void *caller, int nargs, void** args) { return api_create_string(caller, shttpd_version()); } static zsRegPrimitive w3b("version", HTM_TYPE, w3_version); void* w3_register(void *caller, int nargs, void** args) { if (nargs < 3) input_error(caller); shttpd_ctx *ctx = (shttpd_ctx*)api_get_user(caller, args[0], HTM_TYPE); for (int i = 2; i < nargs; i += 2) { shttpd_register_url(ctx, api_get_string(caller, args[i-1]), script_handler, api_get_func(caller, api_get_string(caller, args[i]))); } return 0; } static zsRegPrimitive w3c("register", HTM_TYPE, w3_register); void* w3_listen(void *caller, int nargs, void** args) { if (nargs < 1) input_error(caller); shttpd_ctx *ctx = (shttpd_ctx*)api_get_user(caller, args[0], HTM_TYPE); int port = 80; if (nargs > 1) port = api_get_integer(caller, args[1]); int sock = shttpd_open_port(port); shttpd_listen(ctx, sock); for (;;) shttpd_poll(ctx, 1000); return api_create_integer(caller, sock); } static zsRegPrimitive w3f("listen", HTM_TYPE, w3_listen); void* w3_get(void *caller, int nargs, void** args) { if (nargs < 2) input_error(caller); shttpd_arg_t *arg = (shttpd_arg_t*)api_get_user(caller, args[0], HTC_TYPE); return api_create_string(caller, shttpd_get_var(arg, api_get_string(caller, args[1]))); } static zsRegPrimitive w3g("get", HTC_TYPE, w3_get); void* w3_env(void *caller, int nargs, void** args) { if (nargs < 2) input_error(caller); shttpd_arg_t *arg = (shttpd_arg_t*)api_get_user(caller, args[0], HTC_TYPE); return api_create_string(caller, shttpd_get_env(arg, api_get_string(caller, args[1]))); } static zsRegPrimitive w3h("env", HTC_TYPE, w3_env); void* w3_header(void *caller, int nargs, void** args) { if (nargs < 2) input_error(caller); shttpd_arg_t *arg = (shttpd_arg_t*)api_get_user(caller, args[0], HTC_TYPE); return api_create_string(caller, shttpd_get_header(arg, api_get_string(caller, args[1]))); } static zsRegPrimitive w3i("header", HTC_TYPE, w3_header); void* w3_print(void *caller, int nargs, void** args) { if (nargs < 2) input_error(caller); shttpd_arg_t *arg = (shttpd_arg_t*)api_get_user(caller, args[0], HTC_TYPE); for (int i = 1; i < nargs; i++) { arg->nout += snprintf(arg->buf+arg->nout, arg->buflen-arg->nout, "%s", api_get_string(caller, args[i])); } return api_create_integer(caller, arg->nout); } static zsRegPrimitive w3k("print", HTC_TYPE, w3_print);