mod_duktape.inl 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /* This file is part of the CivetWeb web server.
  2. * See https://github.com/civetweb/civetweb/
  3. * (C) 2015 by the CivetWeb authors, MIT license.
  4. */
  5. #include "duktape.h"
  6. /* TODO: Malloc function should use mg_malloc/mg_free */
  7. /* TODO: the mg context should be added to duktape as well */
  8. /* Alternative: redefine a new, clean API from scratch (instead of using mg),
  9. * or at least do not add problematic functions. */
  10. /* For evaluation purposes, currently only "send" is supported.
  11. * All other ~50 functions will be added later. */
  12. /* Note: This is only experimental support, so any API may still change. */
  13. static const char *civetweb_conn_id = "civetweb_conn";
  14. static duk_ret_t duk_itf_send(duk_context *ctx)
  15. {
  16. struct mg_connection *conn;
  17. duk_double_t ret;
  18. duk_size_t len = 0;
  19. const char *val = duk_require_lstring(ctx, -1, &len);
  20. duk_push_global_stash(ctx);
  21. duk_get_prop_string(ctx, -1, civetweb_conn_id);
  22. conn = (struct mg_connection *)duk_to_pointer(ctx, -1);
  23. if (!conn) {
  24. duk_error(ctx,
  25. DUK_ERR_INTERNAL_ERROR,
  26. "function not available without connection object");
  27. /* probably never reached, but satisfies static code analysis */
  28. return DUK_RET_INTERNAL_ERROR;
  29. }
  30. ret = mg_write(conn, val, len);
  31. duk_push_number(ctx, ret);
  32. return 1;
  33. }
  34. static void mg_exec_duktape_script(struct mg_connection *conn, const char *path)
  35. {
  36. duk_context *ctx = NULL;
  37. conn->must_close = 1;
  38. ctx = duk_create_heap_default();
  39. if (!ctx) {
  40. mg_cry(conn, "Failed to create a Duktape heap.");
  41. goto exec_duktape_finished;
  42. }
  43. duk_push_global_object(ctx);
  44. duk_push_c_function(ctx, duk_itf_send, 1 /*nargs*/);
  45. duk_put_prop_string(ctx, -2, "send");
  46. duk_push_global_stash(ctx);
  47. duk_push_pointer(ctx, (void *)conn);
  48. duk_put_prop_string(ctx, -2, civetweb_conn_id);
  49. if (duk_peval_file(ctx, path) != 0) {
  50. mg_cry(conn, "%s", duk_safe_to_string(ctx, -1));
  51. goto exec_duktape_finished;
  52. }
  53. duk_pop(ctx); /* ignore result */
  54. exec_duktape_finished:
  55. duk_destroy_heap(ctx);
  56. }