/* Form login service routine. Called in response to a form-based login request. Only used when httpSetAuthForm is utilized. The password is clear-text so this must be used over SSL to be secure. */ static void loginServiceProc(HttpConn *conn) { HttpAuth *auth; cchar *username, *password, *referrer; auth = conn->rx->route->auth; username = httpGetParam(conn, "username", 0); password = httpGetParam(conn, "password", 0); if (httpLogin(conn, username, password)) { if ((referrer = httpGetSessionVar(conn, "referrer", 0)) != 0) { /* Preserve protocol scheme from existing connection */ HttpUri *where = httpCreateUri(referrer, 0); httpCompleteUri(where, conn->rx->parsedUri); referrer = httpUriToString(where, 0); httpRedirect(conn, HTTP_CODE_MOVED_TEMPORARILY, referrer); } else { if (auth->loggedIn) { httpRedirect(conn, HTTP_CODE_MOVED_TEMPORARILY, auth->loggedIn); } else { httpRedirect(conn, HTTP_CODE_MOVED_TEMPORARILY, "~"); } } } else { httpRedirect(conn, HTTP_CODE_MOVED_TEMPORARILY, auth->loginPage); } }
/* Web form login service routine. Called in response to a form-based login request when defined via httpSetAuthLogin. It is expected that "authCondition" has already authenticated the request. */ static void loginServiceProc(HttpConn *conn) { HttpAuth *auth; auth = conn->rx->route->auth; if (httpIsAuthenticated(conn)) { httpRedirect(conn, HTTP_CODE_MOVED_TEMPORARILY, auth->loggedInPage ? auth->loggedInPage : "~"); } else { httpRedirect(conn, HTTP_CODE_MOVED_TEMPORARILY, auth->loginPage); } }
static void myaction(HttpConn *conn) { HttpQueue *q; q = conn->writeq; /* Set the HTTP response status */ httpSetStatus(conn, 200); /* Add desired headers. "Set" will overwrite, add will create if not already defined. */ httpAddHeaderString(conn, "Content-Type", "text/plain"); httpSetHeaderString(conn, "Cache-Control", "no-cache"); httpWrite(q, "<html><title>simpleAction</title><body>\r\n"); httpWrite(q, "<p>Name: %s</p>\n", httpGetParam(conn, "name", "-")); httpWrite(q, "<p>Address: %s</p>\n", httpGetParam(conn, "address", "-")); httpWrite(q, "</body></html>\r\n"); /* Call finalize output and close the request. Delay closing if you want to do asynchronous output and close later. */ httpFinalize(conn); #if POSSIBLE /* Useful things to do in actions */ httpRedirect(conn, 302, "/other-uri"); httpError(conn, 409, "My message : %d", 5); #endif }
/* Web form-based authentication callback for the "form" auth protocol. Asks the user to login via a web page. */ static void formLogin(HttpConn *conn) { if (conn->rx->route->auth && conn->rx->route->auth->loginPage) { httpRedirect(conn, HTTP_CODE_MOVED_TEMPORARILY, conn->rx->route->auth->loginPage); } else { httpError(conn, HTTP_CODE_UNAUTHORIZED, "Access Denied. Login required"); } }
/* Render a document by mapping a URL target to a document. The target is interpreted relative to route->documents. If target exists, then serve that. If target + extension exists, serve that. If target is a directory and an index.esp, return the index.esp without a redirect. If target is a directory without a trailing "/" but with an index.esp, do an external redirect to "URI/". If target does not end with ".esp", then do not serve that. */ PUBLIC void espRenderDocument(HttpConn *conn, cchar *target) { HttpUri *up; MprKey *kp; cchar *dest; assert(target); for (ITERATE_KEYS(conn->rx->route->extensions, kp)) { if (kp->key && *kp->key) { if ((dest = checkView(conn, target, 0, kp->key)) != 0) { espRenderView(conn, dest, 0); return; } } } if ((dest = checkView(conn, target, 0, "esp")) != 0) { espRenderView(conn, dest, 0); return; } if ((dest = checkView(conn, target, "index", "esp")) != 0) { /* Must do external redirect first if URL does not end with "/" */ if (!sends(conn->rx->parsedUri->path, "/")) { up = conn->rx->parsedUri; httpRedirect(conn, HTTP_CODE_MOVED_PERMANENTLY, httpFormatUri(up->scheme, up->host, up->port, sjoin(up->path, "/", NULL), up->reference, up->query, 0)); return; } espRenderView(conn, dest, 0); return; } /* Remove in version 6 */ #if DEPRECATED || 1 if ((dest = checkView(conn, sjoin("app/", target, NULL), 0, "esp")) != 0) { espRenderView(conn, dest, 0); return; } #endif /* Last chance, forward to the file handler ... not an ESP request. This enables static file requests within ESP routes. */ httpTrace(conn, "esp.handler", "context", "msg: 'Relay to the fileHandler"); conn->rx->target = &conn->rx->pathInfo[1]; httpMapFile(conn); if (conn->tx->fileInfo.isDir) { httpHandleDirectory(conn); } httpSetFileHandler(conn, 0); }
int respDefinedErrorPage( headerOut *header_out , int err_code ) { switch (err_code) { case 404: if (pageIsDefined( servG->http_404_page ) == 0) return 0; httpRedirect( header_out->req , servG->http_404_page ); break; case 500: case 501: case 502: case 503: case 504: case 505: if (pageIsDefined( servG->http_50x_page ) == 0) return 0; httpRedirect( header_out->req , servG->http_50x_page ); break; default: return 0; } return 1; }
/* Logout service for use with httpSetAuthFormDetails. */ static void logoutServiceProc(HttpConn *conn) { HttpRoute *route; HttpAuth *auth; cchar *loggedOut; route = conn->rx->route; auth = route->auth; httpLogout(conn); loggedOut = (auth->loggedOutPage) ? auth->loggedOutPage : auth->loginPage; if (!loggedOut) { loggedOut = "/"; } httpRedirect(conn, HTTP_CODE_MOVED_TEMPORARILY, loggedOut); }
/* Read the output data from the CGI script and return it to the client. This is called by the MPR in response to I/O events from the CGI process for stdout/stderr data from the CGI script and for EOF from the CGI's stdin. IMPORTANT: This event runs on the connection's dispatcher. (ie. single threaded and safe) */ static void cgiCallback(MprCmd *cmd, int channel, void *data) { HttpConn *conn; Cgi *cgi; int suspended; if ((cgi = data) == 0) { return; } if ((conn = cgi->conn) == 0) { return; } conn->lastActivity = conn->http->now; switch (channel) { case MPR_CMD_STDIN: /* Stdin can absorb more data */ httpResumeQueue(cgi->writeq); break; case MPR_CMD_STDOUT: case MPR_CMD_STDERR: readFromCgi(cgi, channel); break; default: /* Child death notification */ if (cmd->status != 0) { httpError(cgi->conn, HTTP_CODE_BAD_GATEWAY, "Bad CGI process termination"); } break; } if (cgi->location) { httpRedirect(conn, conn->tx->status, cgi->location); } if (cmd->complete || cgi->location) { cgi->location = 0; httpFinalize(conn); mprCreateEvent(conn->dispatcher, "cgiComplete", 0, httpIOEvent, conn, 0); return; } suspended = httpIsQueueSuspended(conn->writeq); assert(!suspended || conn->tx->writeBlocked); mprEnableCmdOutputEvents(cmd, !suspended); mprCreateEvent(conn->dispatcher, "cgi", 0, httpIOEvent, conn, 0); }
/* Read the output data from the CGI script and return it to the client. This is called by the MPR in response to I/O events from the CGI process for stdout/stderr data from the CGI script and for EOF from the CGI's stdin. IMPORTANT: This event runs on the connection's dispatcher. (ie. single threaded and safe) */ static void cgiCallback(MprCmd *cmd, int channel, void *data) { HttpConn *conn; Cgi *cgi; int suspended; if ((cgi = data) == 0) { return; } if ((conn = cgi->conn) == 0) { return; } conn->lastActivity = conn->http->now; mprTrace(6, "CGI: cgiCallback event channel %d", channel); switch (channel) { case MPR_CMD_STDIN: /* Stdin can absorb more data */ httpResumeQueue(cgi->writeq); break; case MPR_CMD_STDOUT: case MPR_CMD_STDERR: readFromCgi(cgi, channel); break; default: /* Child death notification */ break; } if (cgi->location) { httpRedirect(conn, conn->tx->status, cgi->location); } if (cmd->complete || cgi->location) { cgi->location = 0; httpFinalize(conn); mprCreateEvent(conn->dispatcher, "cgiComplete", 0, httpIOEvent, conn, 0); return; } suspended = httpIsQueueSuspended(conn->writeq); mprTrace(6, "CGI: %s CGI: cgiCallback. Conn->writeq %d", suspended ? "DISABLE" : "ENABLE", conn->writeq->count); assert(!suspended || conn->tx->writeBlocked); mprEnableCmdOutputEvents(cmd, !suspended); mprCreateEvent(conn->dispatcher, "cgi", 0, httpIOEvent, conn, 0); }
static void errorRedirect(HttpConn *conn, cchar *uri) { HttpTx *tx; /* If the response has started or it is an external redirect ... do a redirect */ tx = conn->tx; if (sstarts(uri, "http") || tx->flags & HTTP_TX_HEADERS_CREATED) { httpRedirect(conn, HTTP_CODE_MOVED_PERMANENTLY, uri); } else { /* No response started and it is an internal redirect, so we can rerun the request. Set finalized to "cap" any output. processCompletion() in rx.c will rerun the request using the errorDocument. */ tx->errorDocument = uri; tx->finalized = tx->finalizedOutput = tx->finalizedConnector = 1; } }
ZEND_METHOD( appnetServer , httpRedirect ) { size_t len; char* url; long status; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &url, &len, &status ) == FAILURE) { return; } //aeServer* appserv = APPNET_G( appserv ); int ret = httpRedirect( url , status ); if ( ret == AE_TRUE ) { RETURN_TRUE; } RETURN_FALSE; }
void espRedirect(HttpConn *conn, int status, cchar *target) { // MOB - should this httpLink be pushed into httpRedirect? httpRedirect(conn, status, httpLink(conn, target, NULL)); }
static void logoutServiceProc(HttpConn *conn) { httpLogout(conn); httpRedirect(conn, HTTP_CODE_MOVED_TEMPORARILY, conn->rx->route->auth->loginPage); }
/* Test if the request matches. This may delegate the request to the dirHandler if a directory listing is required. */ static int matchFileHandler(HttpConn *conn, HttpRoute *route, int dir) { HttpRx *rx; HttpTx *tx; HttpUri *prior; MprPath *info, zipInfo; cchar *index; char *path, *pathInfo, *uri, *zipfile; int next; printf("\n matchFileHandler \n"); rx = conn->rx; tx = conn->tx; rx = conn->rx; prior = rx->parsedUri; info = &tx->fileInfo; httpMapFile(conn, route); assure(info->checked); if (rx->flags & (HTTP_DELETE | HTTP_PUT)) { return HTTP_ROUTE_OK; } if (info->isDir) { /* Manage requests for directories */ if (!sends(rx->pathInfo, "/")) { /* Append "/" and do an external redirect */ pathInfo = sjoin(rx->pathInfo, "/", NULL); uri = httpFormatUri(prior->scheme, prior->host, prior->port, pathInfo, prior->reference, prior->query, 0); httpRedirect(conn, HTTP_CODE_MOVED_PERMANENTLY, uri); return HTTP_ROUTE_OK; } if (route->indicies) { /* Ends with a "/" so do internal redirection to an index file */ for (ITERATE_ITEMS(route->indicies, index, next)) { /* Internal directory redirections. Transparently append index. Test indicies in order. */ path = mprJoinPath(tx->filename, index); if (mprPathExists(path, R_OK)) { pathInfo = sjoin(rx->scriptName, rx->pathInfo, index, NULL); uri = httpFormatUri(prior->scheme, prior->host, prior->port, pathInfo, prior->reference, prior->query, 0); httpSetUri(conn, uri); tx->filename = path; tx->ext = httpGetExt(conn); mprGetPathInfo(tx->filename, info); return HTTP_ROUTE_REROUTE; } } } /* If a directory, test if a directory listing should be rendered. If so, delegate to the dirHandler. Cannot use the sendFile handler and must use the netConnector. */ if (info->isDir && maRenderDirListing(conn)) { tx->handler = conn->http->dirHandler; tx->connector = conn->http->netConnector; return HTTP_ROUTE_OK; } } if (!info->valid && (route->flags & HTTP_ROUTE_GZIP) && rx->acceptEncoding && strstr(rx->acceptEncoding, "gzip") != 0) { /* If the route accepts zipped data and a zipped file exists, then transparently respond with it. */ zipfile = sfmt("%s.gz", tx->filename); if (mprGetPathInfo(zipfile, &zipInfo) == 0) { tx->filename = zipfile; tx->fileInfo = zipInfo; httpSetHeader(conn, "Content-Encoding", "gzip"); } } if (rx->flags & (HTTP_GET | HTTP_HEAD | HTTP_POST) && info->valid && !info->isDir && tx->length < 0) { /* The sendFile connector is optimized on some platforms to use the sendfile() system call. Set the entity length for the sendFile connector to utilize. */ httpSetEntityLength(conn, tx->fileInfo.size); } printf("\n-------------------------\n"); printf("tx->filename:\t%s",tx->filename); printf("\n-------------------------\n"); return HTTP_ROUTE_OK; }
/** Benutzer anmelden (Passwort Überprüfen) */ int main(int argc, char ** argv) { cgi datCGI; init_CGI(&datCGI); person login_person; init_person(&login_person); //fprintf(stderr, "Hallo vor Post\n"); get_CGI_data(&datCGI); if(datCGI.request_method != POST) { print_exit_failure("Use POST!"); } //fprintf(stderr, "POST_DATA: %s", datCGI.POST_data); //Aus POST_data den String zwischen <AttributName>= und '&' ausschneiden extract_POST_data(&datCGI, "email", &login_person.email); remove_newline(login_person.email); extract_POST_data(&datCGI, "pass", &login_person.password); remove_newline(login_person.password); if(login_person.email == NULL) { httpSetCookie("EMAIL", "NULL"); httpSetCookie("SID", "0"); httpCacheControl("no-cache"); char * redirectString=NULL; asprintf(&redirectString, "https://%s/incorrect_password.html", datCGI.http_host); httpRedirect(redirectString); } //fprintf(stderr, "POST_DATA: %s", datCGI.POST_data); //TODO: Verhindern, dass sich ein anderer Nutzer vom selben Rechner aus einloggt wenn der erste noch nicht abgemeldet ist //(zweimaliges Anmelden verhindern) //Das ist sehr unwahrscheinlich /* if(datCGI.http_cookies != NULL){ person already_logged_in_person; init_person(&already_logged_in_person); char * cook_sid=NULL; if(extract_COOKIE_data(&datCGI, "EMAIL", &already_logged_in_person.email) == 0 && extract_COOKIE_data(&datCGI, "SID", &cook_sid) == 0){ //print_exit_failure("Hier ist schon jemand eingeloggt"); already_logged_in_person.sid=atoi(cook_sid); if(get_person_by_sid(&already_logged_in_person)){ print_exit_failure("Hier ist schon jemand eingeloggt"); } } }*/ UserState user_state=verify_user(&login_person); //Zwei cookies setzen if(user_state == PW_CORRECT || user_state == PW_CORRECT_ALREADY_LOGGED_IN) { httpSetCookie("EMAIL", login_person.email); char * sid_string; asprintf(&sid_string, "%d", login_person.sid); httpSetCookie("SID", sid_string); httpCacheControl("no-store, no-cache, must-revalidate, max-age=0"); char * redirectString=NULL; asprintf(&redirectString, "https://%s/cgi-bin/all_messages.cgi", datCGI.http_host); httpRedirect(redirectString); } if(user_state == PW_INCORRECT) { httpSetCookie("EMAIL", "NULL"); httpSetCookie("SID", "0"); httpCacheControl("no-store, no-cache, must-revalidate, max-age=0"); char * redirectString=NULL; asprintf(&redirectString, "https://%s/incorrect_password.html", datCGI.http_host); httpRedirect(redirectString); } /* httpHeader(HTML); printf("<!DOCTYPE html><head>\ <title>InfoWall -- Anmeldung</title>\ <meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />\ <meta name=\"viewport\" content=\"width=device-width\">\ </head>\ <body>"); printf("%s\n", datCGI.POST_data); puts("<h1>Erhaltene Daten:</h1>\n"); printf("<br>CONTENT_LENGTH: %d -- REQUEST_METHOD: %s\n", datCGI.content_length, datCGI.request_method); printf("<br>Name: %s\nPassword: %s\n", login_person.email, login_person.password); printf("<br>Post Data: %s\n", datCGI.POST_data); puts("<br>\n\n\n\n"); if(login_person.auth && user_state==0){ puts("<h2>Personendaten:</h2>\n"); printf("<br>User ID: %d\n", login_person.id); printf("<br>Vorname: %s\n", login_person.first_name); printf("<br>Nachname: %s\n", login_person.name); printf("<br>Email: %s\n", login_person.email); printf("<br>Passwort: %s (richtig)\n", login_person.password); printf("<br>Faecher: %s\n", login_person.courses); if(login_person.isTeacher)printf("<br>Kuerzel: %s\n", login_person.acronym); printf("<br>SID: %d\n", login_person.sid); puts("<a href=\"/cgi-bin/logout.cgi\" style=\"color: green;\">LOGOUT</a>\ <br><a href=\"/cgi-bin/all_messages.cgi\">Alle Nachrichten</a>"); puts("<iframe src=\"/cgi-bin/all_messages.cgi\" style=\"width: 100%; height: 500px;\""); }else{ puts("<br>YOU FAIL!!\n"); if(user_state == 1){ puts("Bereits angemeldet!"); printf("<a href=\"/cgi-bin/logout.cgi\">LOGOUT</a>\ <br><a href=\"/cgi-bin/all_messages.cgi\">Alle Nachrichten</a>"); } } printf("</body>\ </html>");*/ exit(0); }
PUBLIC void espRedirect(HttpConn *conn, int status, cchar *target) { httpRedirect(conn, status, target); }
static int handleDirectory(HttpConn *conn) { HttpRx *rx; HttpTx *tx; HttpRoute *route; HttpUri *req; MprPath *info; cchar *index, *pathInfo, *uri; char *path; int next; rx = conn->rx; tx = conn->tx; req = rx->parsedUri; route = rx->route; info = &tx->fileInfo; /* Manage requests for directories */ if (!sends(req->path, "/")) { /* Append "/" and do an external redirect. Use the original request URI. */ pathInfo = sjoin(req->path, "/", NULL); uri = httpFormatUri(req->scheme, req->host, req->port, pathInfo, req->reference, req->query, 0); httpRedirect(conn, HTTP_CODE_MOVED_PERMANENTLY, uri); return HTTP_ROUTE_OK; } if (route->indexes) { /* Ends with a "/" so do internal redirection to an index file */ for (ITERATE_ITEMS(route->indexes, index, next)) { /* Internal directory redirections. Transparently append index. Test indexes in order. */ path = mprJoinPath(tx->filename, index); if (mprPathExists(path, R_OK)) { pathInfo = sjoin(rx->scriptName, rx->pathInfo, index, NULL); uri = httpFormatUri(req->scheme, req->host, req->port, pathInfo, req->reference, req->query, 0); httpSetUri(conn, uri); tx->filename = path; tx->ext = httpGetExt(conn); mprGetPathInfo(tx->filename, info); return HTTP_ROUTE_REROUTE; } } } #if ME_COM_DIR /* Directory Listing. If a directory, test if a directory listing should be rendered. If so, delegate to the dirHandler. Cannot use the sendFile handler and must use the netConnector. */ if (info->isDir && httpRenderDirListing(conn)) { tx->handler = conn->http->dirHandler; tx->connector = conn->http->netConnector; return HTTP_ROUTE_OK; } #endif return HTTP_ROUTE_OK; }