3 * @purpose Runs the FCGI request loop to handle web interface requests.
5 * fcgi_stdio.h must be included before all else so the stdio function
6 * redirection works ok.
9 #include <fcgi_stdio.h>
14 * Extracts a key/value pair from a request string.
15 * Note that the input is modified by this function.
16 * @param in The string from which to extract the pair
17 * @param key A pointer to a variable to hold the key string
18 * @param value A pointer to a variable to hold the value string
19 * @return A pointer to the start of the next search location, or NULL if
22 char *FCGI_KeyPair(char *in, const char **key, const char **value)
25 if (!in || !*in) { //Invalid input or string is EOL
30 //Find either = or &, whichever comes first
31 if ((ptr = strpbrk(in, "=&"))) {
32 if (*ptr == '&') { //No value specified
36 //Stopped at an '=' sign
39 if ((ptr = strchr(ptr,'&'))) {
45 } else { //No value specified and no other pair
53 * Begins a response to the client in JSON format.
54 * @param status_code The HTTP status code to be returned.
55 * @param module The name of the module that initiated the response.
57 void FCGI_BeginJSON(StatusCodes status_code, const char *module)
59 switch (status_code) {
62 case STATUS_UNAUTHORIZED:
63 printf("Status: 401 Unauthorized\r\n");
66 printf("Status: 400 Bad Request\r\n");
68 printf("Content-type: application/json; charset=utf-8\r\n\r\n");
70 printf("\t\"module\" : \"%s\"", module);
74 * Adds a key/value pair to a JSON response. The response must have already
75 * been initiated by FCGI_BeginJSON. Note that characters are not escaped.
76 * @param key The key of the JSON entry
77 * ¶m value The value associated with the key.
79 void FCGI_BuildJSON(const char *key, const char *value)
81 printf(",\r\n\t\"%s\" : \"%s\"", key, value);
85 * Ends a JSON response that was initiated by FCGI_BeginJSON.
93 * Main FCGI request loop that receives/responds to client requests.
94 * @param data A data field to be passed to the selected module handler.
96 void FCGI_RequestLoop (void *data)
99 while (FCGI_Accept() >= 0) {
100 ModuleHandler module_handler = NULL;
101 char module[BUFSIZ], params[BUFSIZ];
103 //strncpy doesn't zero-truncate properly
104 snprintf(module, BUFSIZ, "%s", getenv("DOCUMENT_URI_LOCAL"));
105 snprintf(params, BUFSIZ, "%s", getenv("QUERY_STRING"));
107 //Remove trailing slashes (if present) from module query
108 size_t lastchar = strlen(module) - 1;
109 if (lastchar > 0 && module[lastchar] == '/')
110 module[lastchar] = 0;
113 if (!strcmp("sensors", module)) {
114 //module_handler = Handler_Sensors;
115 } else if (!strcmp("actuators", module)) {
119 if (module_handler) {
120 module_handler(data, params);
124 FCGI_BeginJSON(400, module);
125 FCGI_BuildJSON("description", "400 Invalid response");
126 snprintf(buf, BUFSIZ, "%d", count);
127 FCGI_BuildJSON("request-number", buf);
128 FCGI_BuildJSON("params", params);
129 FCGI_BuildJSON("host", getenv("SERVER_HOSTNAME"));