/* 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); } }
/* Make an absolute reference for "this" URI. function absolute(base): Uri */ static EjsUri *uri_absolute(Ejs *ejs, EjsUri *up, int argc, EjsObj **argv) { EjsUri *result; HttpUri *uri, *baseUri; if (argc >= 1) { baseUri = toHttpUri(ejs, argv[0], 0); result = cloneUri(ejs, up, 0); uri = result->uri; if (uri->path && uri->path[0] != '/') { httpJoinUriPath(uri, baseUri, uri); } httpCompleteUri(result->uri, baseUri); } else { result = cloneUri(ejs, up, 0); httpCompleteUri(result->uri, NULL); } httpNormalizeUri(result->uri); return result; }
static EjsUri *completeUri(Ejs *ejs, EjsUri *up, EjsObj *missing, int includeQuery) { EjsUri *missingUri; if (!ejsIsDefined(ejs, missing)) { missingUri = 0; } else if (ejsGetLength(ejs, missing) > 0) { missingUri = ejsCreateObj(ejs, ESV(Uri), 0); missingUri->uri = createHttpUriFromHash(ejs, missing, HTTP_COMPLETE_URI); } else { missingUri = ejsToUri(ejs, missing); } if (missingUri == 0) { if (!includeQuery) { up->uri->query = NULL; } httpCompleteUri(up->uri, NULL); } else { httpCompleteUri(up->uri, missingUri->uri); } return up; }
/* Redirect the user to another web page. The targetUri may or may not have a scheme. */ PUBLIC void httpRedirect(HttpConn *conn, int status, cchar *targetUri) { HttpTx *tx; HttpRx *rx; HttpUri *target, *base; HttpEndpoint *endpoint; cchar *msg; char *dir, *cp; assert(targetUri); rx = conn->rx; tx = conn->tx; if (tx->finalized) { /* A response has already been formulated */ return; } tx->status = status; if (schr(targetUri, '$')) { targetUri = httpExpandUri(conn, targetUri); } mprLog(3, "redirect %d %s", status, targetUri); msg = httpLookupStatus(conn->http, status); if (300 <= status && status <= 399) { if (targetUri == 0) { targetUri = "/"; } target = httpCreateUri(targetUri, 0); base = rx->parsedUri; /* Support URIs without a host: https:///path. This is used to redirect onto the same host but with a different scheme. So find a suitable local endpoint to supply the port for the scheme. */ if (!target->port && (!target->host || smatch(base->host, target->host)) && (target->scheme && !smatch(target->scheme, base->scheme))) { endpoint = smatch(target->scheme, "https") ? conn->host->secureEndpoint : conn->host->defaultEndpoint; if (endpoint) { target->port = endpoint->port; } else { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot find endpoint for scheme %s", target->scheme); return; } } if (target->path && target->path[0] != '/') { /* Relative file redirection to a file in the same directory as the previous request. */ dir = sclone(rx->pathInfo); if ((cp = strrchr(dir, '/')) != 0) { /* Remove basename */ *cp = '\0'; } target->path = sjoin(dir, "/", target->path, NULL); } target = httpCompleteUri(target, base); targetUri = httpUriToString(target, 0); httpSetHeader(conn, "Location", "%s", targetUri); httpFormatResponse(conn, "<!DOCTYPE html>\r\n" "<html><head><title>%s</title></head>\r\n" "<body><h1>%s</h1>\r\n<p>The document has moved <a href=\"%s\">here</a>.</p></body></html>\r\n", msg, msg, targetUri); } else { httpFormatResponse(conn, "<!DOCTYPE html>\r\n" "<html><head><title>%s</title></head>\r\n" "<body><h1>%s</h1>\r\n</body></html>\r\n", msg, msg); } httpFinalize(conn); }