void LoginHTTPRequestHandler::createResponse(const HTTPRequest &r) { HTTPResponse response; QString page = "\r\n<html><body>" "<form method=\"POST\">" "%1" "Username: <input type=\"text\" name=\"username\">" "Password: <input type=\"password\" name=\"pass\">" "<INPUT type=\"submit\" value=\"Auth\">" "</form></body></html>"; if("GET" == r.method){ response.setStatusCode(200); response.setReasonPhrase("OK"); QList<QNetworkCookie> cookieList = QtConcurrent::blockingFiltered(r.cookieJar, [] (const QNetworkCookie &cookie) -> bool { return cookie.name() == "loggedin" && cookie.value() == "1"; } ); if(1 == cookieList.size()){ response.setBody("You're logged in!"); } else{ response.setBody(page.arg("")); } emit responseWritten(response); emit endOfWriting(); return; } if("POST" == r.method && !r.postData.isEmpty()){ if(r.postData.contains("username") && "Ion" == r.postData["username"] && r.postData.contains("pass") && "1234" == r.postData["pass"]){ response.setStatusCode(200); response.setReasonPhrase("OK"); //TODO: this could be something randomized in order to avoid replicating QNetworkCookie cookie("loggedin", "1"); cookie.setHttpOnly(true); response.setCookie(cookie); response.setBody("You're logged in!\n"); emit responseWritten(response); emit endOfWriting(); return; } response.setStatusCode(200); response.setReasonPhrase("OK"); response.setBody(page.arg("Login failed, try again!<br>")); emit responseWritten(response); emit endOfWriting(); return; } response.setStatusCode(400); response.setReasonPhrase("Bad request"); emit responseWritten(response); emit endOfWriting(); }
HTTPResponse FileAction::execute(const HTTPRequest& request) { HTTPResponse response; struct stat statbuf; char md5_hex[33]; string path = document_root + request.path; // TODO: Sanitize path, ie. remove ".." and leading "/" if (request.method == "GET" || request.method == "HEAD") { if (stat(path.c_str(), &statbuf) >= 0) { ostringstream os; os << statbuf.st_size; response = HTTPResponse(200, WebUtil::pathToMimetype(path)); response.addHeader("Content-Length",os.str()); response.addHeader("Last-Modified",WebUtil::formatDate(statbuf.st_mtime)); FILE* f = fopen(path.c_str(), "r"); md5_stream_hex(f,md5_hex); md5_hex[32] = '\0'; response.addHeader("Content-MD5",string(md5_hex)); if (request.method == "GET") { rewind(f); response.setBody(f); } else { fclose(f); } } else { response = HTTPResponse(404, "text/plain"); } } else if (request.method == "DELETE") { // This method isn't strictly HTTP1.1, but we need it // and I don't want to implement a complete WebDAV stack. unlink(path.c_str()); response = HTTPResponse(200, "text/plain"); } else if (request.method == "PUT") { long size = atoi(request.getHeader("Content-length").c_str()); // TODO: If no content-header is sent, return "411 Length required" as per the RFC. bool exists = stat(path.c_str(), &statbuf) != -1; FILE* f = fopen(path.c_str(), "w"); WebUtil::copy(request.bodyFILE, f, size); fclose(f); if (exists) { response = HTTPResponse(200, "text/plain"); response.setBody("File modified"); } else { response = HTTPResponse(201, "text/plain"); response.setBody("File created"); } } else if (request.method == "MKCOL") { // This method isn't strictly HTTP1.1, but we need it // and I don't want to implement a complete WebDAV stack. if (mkdir(path.c_str(), 0777) == -1) { response = HTTPResponse(201, "text/plain"); response.setBody("Dir not created"); } else { response = HTTPResponse(201, "text/plain"); response.setBody("Dir created"); printf("Dir %s created\n", path.c_str()); } } else { cout << "Unknown method " << request.method << endl; response = HTTPResponse(405, "text/plain"); response.addHeader("Allow", "PUT, GET, HEAD, DELETE, MKCOL"); } return response; }
HTTPResponse execute(const HTTPRequest& request) { HTTPResponse response = HTTPResponse(200, "text/plain"); response.setBody("Hello world! RayGay renderserver up and running."); return response; };