static void upload(MaQueue *q) { MaConn *conn; char *sw; char *newLocation; int responseStatus; conn = q->conn; newLocation = 0; responseStatus = 0; sw = (char*) strstr(maGetFormVar(conn, "QUERY_STRING", ""), "SWITCHES="); if (sw) { sw = mprStrdup(q, sw + 9); mprUrlDecode(sw, (int) strlen(sw) + 1, sw); if (*sw == '-') { if (sw[1] == 'l') { newLocation = sw + 3; } else if (sw[1] == 's') { responseStatus = atoi(sw + 3); } } } maSetResponseCode(conn, 200); maSetResponseMimeType(conn, "text/html"); maDontCacheResponse(conn); /* * Test writing headers. The Server header overwrote the "Server" header * * maSetHeader(conn, "MyCustomHeader: true"); * maSetHeader(conn, "Server: private"); */ if (maGetCookies(conn) == 0) { maSetCookie(conn, "appwebTest", "Testing can be fun", 43200, "/", 0); } if (newLocation) { maRedirect(conn, 302, newLocation); } else if (responseStatus) { maFailRequest(conn, responseStatus, "Custom Status"); } else { maWrite(q, "<HTML><TITLE>egiProgram: EGI Output</TITLE><BODY>\r\n"); printRequestHeaders(q); printQueryData(q); printBodyData(q); maWrite(q, "</BODY></HTML>\r\n"); } if (sw) { mprFree(sw); } }
static void myEgi(MaQueue *q) { MaConn *conn; conn = q->conn; maSetResponseCode(conn, 200); maWrite(q, "<HTML><TITLE>simpleEgi</TITLE><BODY>\r\n"); maWrite(q, "<p>Name: %s</p>\n", maGetFormVar(conn, "name", "-")); maWrite(q, "<p>Address: %s</p>\n", maGetFormVar(conn, "address", "-")); maWrite(q, "</BODY></HTML>\r\n"); #if POSSIBLE /* * Useful things to do in egi forms */ maSetResponseCode(conn, 200); maSetResponseMimeType(conn, "text/plain"); maDontCacheResponse(conn); maRedirect(conn, 302, "/myURl"); maFailRequest(conn, 409, "My message : %d", 5); #endif }
/* Parse the CGI output headers. Sample CGI program: Content-type: text/html <html..... */ static bool parseHeader(MaConn *conn, MprCmd *cmd) { MaResponse *resp; MaQueue *q; MprBuf *buf; char *endHeaders, *headers, *key, *value, *location; int fd, len; resp = conn->response; location = 0; value = 0; buf = mprGetCmdBuf(cmd, MPR_CMD_STDOUT); mprAddNullToBuf(buf); headers = mprGetBufStart(buf); /* Split the headers from the body. */ len = 0; fd = mprGetCmdFd(cmd, MPR_CMD_STDOUT); if ((endHeaders = strstr(headers, "\r\n\r\n")) == NULL) { if ((endHeaders = strstr(headers, "\n\n")) == NULL) { if (fd >= 0 && strlen(headers) < MA_MAX_HEADERS) { /* Not EOF and less than max headers and have not yet seen an end of headers delimiter */ return 0; } } else len = 2; } else { len = 4; } if (endHeaders) { endHeaders[len - 1] = '\0'; endHeaders += len; } /* Want to be tolerant of CGI programs that omit the status line. */ if (strncmp((char*) buf->start, "HTTP/1.", 7) == 0) { if (!parseFirstCgiResponse(conn, cmd)) { /* maFailConnection already called */ return 0; } } if (endHeaders && strchr(mprGetBufStart(buf), ':')) { mprLog(conn, 4, "CGI: parseHeader: header\n%s", headers); while (mprGetBufLength(buf) > 0 && buf->start[0] && (buf->start[0] != '\r' && buf->start[0] != '\n')) { if ((key = getCgiToken(buf, ":")) == 0) { maFailConnection(conn, MPR_HTTP_CODE_BAD_REQUEST, "Bad header format"); return 0; } value = getCgiToken(buf, "\n"); while (isspace((int) *value)) { value++; } len = (int) strlen(value); while (len > 0 && (value[len - 1] == '\r' || value[len - 1] == '\n')) { value[len - 1] = '\0'; len--; } mprStrLower(key); if (strcmp(key, "location") == 0) { location = value; } else if (strcmp(key, "status") == 0) { maSetResponseCode(conn, atoi(value)); } else if (strcmp(key, "content-type") == 0) { maSetResponseMimeType(conn, value); } else if (strcmp(key, "content-length") == 0) { maSetEntityLength(conn, (MprOff) mprAtoi(value, 10)); resp->chunkSize = 0; } else { /* Now pass all other headers back to the client */ maSetHeader(conn, 0, key, "%s", value); } } buf->start = endHeaders; } if (location) { maRedirect(conn, resp->code, location); q = resp->queue[MA_QUEUE_SEND].nextQ; maPutForService(q, maCreateEndPacket(q), 1); } cmd->userFlags |= MA_CGI_SEEN_HEADER; return 1; }
static void setMimeType(void *handle, cchar *mimeType) { maSetResponseMimeType(handle, mimeType); }