action.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. action.c -- Action handler
  3. This module implements the /action handler. It is a simple binding of URIs to C functions.
  4. This enables a very high performance implementation with easy parsing and decoding of query
  5. strings and posted data.
  6. Copyright (c) All Rights Reserved. See details at the end of the file.
  7. */
  8. /*********************************** Includes *********************************/
  9. #include "goahead.h"
  10. /************************************ Locals **********************************/
  11. static WebsHash actionTable = -1; /* Symbol table for actions */
  12. /************************************* Code ***********************************/
  13. /*
  14. Process an action request. Returns 1 always to indicate it handled the URL
  15. Return true to indicate the request was handled, even for errors.
  16. */
  17. static bool actionHandler(Webs *wp)
  18. {
  19. WebsKey *sp;
  20. char actionBuf[ME_GOAHEAD_LIMIT_URI + 1];
  21. char *cp, *actionName;
  22. WebsAction fn;
  23. assert(websValid(wp));
  24. assert(actionTable >= 0);
  25. /*
  26. Extract the action name
  27. */
  28. scopy(actionBuf, sizeof(actionBuf), wp->path);
  29. if ((actionName = strchr(&actionBuf[1], '/')) == NULL) {
  30. websError(wp, HTTP_CODE_NOT_FOUND, "Missing action name");
  31. return 1;
  32. }
  33. actionName++;
  34. if ((cp = strchr(actionName, '/')) != NULL) {
  35. *cp = '\0';
  36. }
  37. /*
  38. Lookup the C action function first and then try tcl (no javascript support yet).
  39. */
  40. sp = hashLookup(actionTable, actionName);
  41. if (sp == NULL) {
  42. websError(wp, HTTP_CODE_NOT_FOUND, "Action %s is not defined", actionName);
  43. } else {
  44. fn = (WebsAction) sp->content.value.symbol;
  45. assert(fn);
  46. if (fn) {
  47. #if ME_GOAHEAD_LEGACY
  48. (*((WebsProc) fn))((void*) wp, actionName, wp->query);
  49. #else
  50. (*fn)((void*) wp);
  51. #endif
  52. }
  53. }
  54. return 1;
  55. }
  56. /*
  57. Define a function in the "action" map space
  58. */
  59. PUBLIC int websDefineAction(cchar *name, void *fn)
  60. {
  61. assert(name && *name);
  62. assert(fn);
  63. if (fn == NULL) {
  64. return -1;
  65. }
  66. hashEnter(actionTable, (char*) name, valueSymbol(fn), 0);
  67. return 0;
  68. }
  69. static void closeAction()
  70. {
  71. if (actionTable != -1) {
  72. hashFree(actionTable);
  73. actionTable = -1;
  74. }
  75. }
  76. PUBLIC void websActionOpen()
  77. {
  78. actionTable = hashCreate(WEBS_HASH_INIT);
  79. websDefineHandler("action", 0, actionHandler, closeAction, 0);
  80. }
  81. #if ME_GOAHEAD_LEGACY
  82. /*
  83. Don't use these routes. Use websWriteHeaders, websEndHeaders instead.
  84. Write a webs header. This is a convenience routine to write a common header for an action back to the browser.
  85. */
  86. PUBLIC void websHeader(Webs *wp)
  87. {
  88. assert(websValid(wp));
  89. websWriteHeaders(wp, -1, 0);
  90. websWriteEndHeaders(wp);
  91. websWrite(wp, "<html>\n");
  92. }
  93. PUBLIC void websFooter(Webs *wp)
  94. {
  95. assert(websValid(wp));
  96. websWrite(wp, "</html>\n");
  97. }
  98. #endif
  99. /*
  100. Copyright (c) Embedthis Software. All Rights Reserved.
  101. This software is distributed under commercial and open source licenses.
  102. You may use the Embedthis GoAhead open source license or you may acquire
  103. a commercial license from Embedthis Software. You agree to be fully bound
  104. by the terms of either license. Consult the LICENSE.md distributed with
  105. this software for full details and other copyrights.
  106. */