1
2 /********************************** Description *******************************/
3
4 /*
5 * This module implements the /ajax handler. It emulates CGI processing6 * but performs this in-process and not as an external process. This enables7 * a very high performance implementation with easy parsing and decoding8 * of query strings and posted data.9 */
10
11 /*********************************** Includes *********************************/
12
13 #include "wsIntrn.h"
14
15 /************************************ Locals **********************************/
16
17 static sym_fd_t ajaxSymtab = -1; /*Symbol table for ajax handlers*/
18
19
20 /************************************* Code ***********************************/
21 static intwebsAjaxHandlerDone(webs_t wp);22 static voidwebsAjaxHeader(webs_t wp);23 /************************************* globle ***********************************/
24 /*
25 * Process a ajax request. Returns 1 always to indicate it handled the URL26 */
27 int websAjaxHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, intarg,28 char_t *url, char_t *path, char_t *query)29 {30 sym_t *sp;31 char_t ajaxBuf[FNAMESIZE];32 char_t *cp, *ajaxName;33 int (*fn)(void *sock, char_t *path, char_t *args);34
35 a_assert(websValid(wp));36 a_assert(url && *url);37 a_assert(path && *path == ‘/‘);38
39 /*
40 * Extract the ajax name41 */
42 gstrncpy(ajaxBuf, path, TSZ(ajaxBuf));43 if ((ajaxName = gstrchr(&ajaxBuf[1], ‘/‘)) ==NULL) {44 websError(wp, 200, T("Missing ajax name"));45 return 1;46 }47 ajaxName++;48 if ((cp = gstrchr(ajaxName, ‘/‘)) !=NULL) {49 *cp = ‘\0‘;50 }51
52 /*
53 * Lookup the C ajax function first and then try tcl (no javascript support54 * yet).55 */
56 sp =symLookup(ajaxSymtab, ajaxName);57 if (sp ==NULL) {58 websError(wp, 404, T("Ajax %s is not defined"), ajaxName);59 } else{60 fn = (int (*)(void *, char_t *, char_t *)) sp->content.value.integer;61 a_assert(fn);62 if(fn) {63 /*
64 * For good practice, ajaxs must call websDone()65 */
66 websAjaxHeader(wp);67 (*fn)((void*) wp, ajaxName, query); //调用实现函数
68 websAjaxHandlerDone(wp);69
70 /*
71 * Remove the test to force websDone, since this prevents72 * the server "push" from a ajax>73 */
74 #if 0 /* push */
75 if(websValid(wp)) {76 websError(wp, 200, T("Ajax didn‘t call websDone"));77 }78 #endif /* push */
79 }80 }81 return 1;82 }83 /******************************************************************************/
84 /*
85 * Define a ajax function in the "ajax" map space.86 */
87
88 int websAjaxDefine(char_t *name, void (*fn)(webs_t wp, char_t *path,89 char_t *query))90 {91 a_assert(name && *name);92 a_assert(fn);93
94 if (fn ==NULL) {95 return -1;96 }97
98 symEnter(ajaxSymtab, name, valueInteger((int) fn), (int) NULL);99 return 0;100 }101
102 /******************************************************************************/
103
104 /*
105 * Open the symbol table for ajaxs.106 */
107
108 voidwebsAjaxOpen()109 {110 ajaxSymtab = symOpen(WEBS_SYM_INIT*2);111 }112
113 /******************************************************************************/
114 /*
115 * Close the symbol table for ajaxs.116 */
117
118 voidwebsAjaxClose()119 {120 if (ajaxSymtab != -1) {121 symClose(ajaxSymtab);122 ajaxSymtab = -1;123 }124 }125 /**********************************Local********************************************/
126 /*
127 * Write a webs header. This is a convenience routine to write a common128 * header for a Ajax back to the browser.129 */
130
131 static voidwebsAjaxHeader(webs_t wp)132 {133 a_assert(websValid(wp));134 websWrite(wp, T("HTTP/1.0 200 OK\n"));135 /*
136 * By license terms the following line of code must not be modified137 */
138 websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);139
140 websWrite(wp, T("Pragma: no-cache\n"));141 websWrite(wp, T("Cache-control: no-cache\n"));142 websWrite(wp, T("Content-Type: text/html\n"));143 websWrite(wp, T("\n"));144
145 }146 /******************************************************************************/
147 /*
148 * ajax respone ok149 */
150 static intwebsAjaxHandlerDone(webs_t wp)151 {152 websDone(wp,200);153 }