TEST_F (WebSockServerTester, FailedHandshakes_NoKey) { HTTP::Request request (HTTP::Method::GET, "/"); request.SetHeader (HTTP::Header ("Connection", "Upgrade")); request.SetHeader (HTTP::Header ("Upgrade", "websocket")); VerifyBadRequest (request); }
TEST_F (WebSockServerTester, FailedHandshakes_NoWebSocket) { HTTP::Request request (HTTP::Method::GET, "/"); request.SetHeader (HTTP::Header ("Connection", "Upgrade")); request.SetHeader (HTTP::Header ("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==")); VerifyBadRequest (request); }
void handleFileExportRequest(const http::Request& request, http::Response* pResponse) { // see if this is a single or multiple file request std::string file = request.queryParamValue("file"); if (!file.empty()) { // resolve alias and ensure that it exists FilePath filePath = module_context::resolveAliasedPath(file); if (!filePath.exists()) { pResponse->setError(http::status::NotFound, "file doesn't exist"); return; } // get the name std::string name = request.queryParamValue("name"); if (name.empty()) { pResponse->setError(http::status::BadRequest, "name not specified"); return; } // download as attachment setAttachmentResponse(request, name, filePath, pResponse); } else { handleMultipleFileExportRequest(request, pResponse); } }
bool Server::Listen() { m_valid = false; if (!m_server.Listen()) return false; //Debug("Handshaking..."); HTTP::Request handshake; if (!handshake.Receive(m_server)) { Error("Failed to process HTTP request"); } map<string, string> & headers = handshake.Headers(); auto i = headers.find("Sec-WebSocket-Key"); if (i == headers.end()) { Error("No Sec-WebSocket-Key header!"); for (i = headers.begin(); i != headers.end(); ++i) { Error("Key: %s = %s", i->first.c_str(), i->second.c_str()); } return false; } //Debug("Finished handshake"); string magic = Foxbox::WS::Magic(i->second); m_server.Send("HTTP/1.1 101 Switching Protocols\r\n"); m_server.Send("Upgrade: WebSocket\r\n"); m_server.Send("Connection: Upgrade\r\n"); m_server.Send("Sec-WebSocket-Accept: %s\r\n", magic.c_str()); m_server.Send("Sec-WebSocket-Protocol: %s\r\n\r\n", headers["Sec-WebSocket-Protocol"].c_str()); m_valid = true; return true; }
void Authenticator::updateAuthInfo(http::Request& request) { if (request.has("Authorization")) { const std::string& authorization = request.get("Authorization"); if (isBasicCredentials(authorization)) { BasicAuthenticator(_username, _password).authenticate(request); } // else if (isDigestCredentials(authorization)) // ; // TODO } }
void handleFileShow(const http::Request& request, http::Response* pResponse) { // get the file path FilePath filePath(request.queryParamValue("path")); if (!filePath.exists()) { pResponse->setNotFoundError(request.uri()); return; } // send it back pResponse->setCacheWithRevalidationHeaders(); pResponse->setCacheableFile(filePath, request); }
void RFC6455::Client::HandleHandshake (const HTTP::Request& inRequest) { HTTP::Response response (HTTP::Code::BAD_REQUEST, inRequest.mVersion); bool isUpgraded (false); try { if (inRequest.GetHeaderValue ("Connection") == "Upgrade" && inRequest.GetHeaderValue ("Upgrade") == "websocket" && inRequest.GetHeaderValue ("Sec-WebSocket-Key") != "" && inRequest.mMethod == HTTP::Method::GET && inRequest.mVersion == HTTP::Version::V11 ) { const auto key (inRequest.GetHeaderValue ("Sec-WebSocket-Key")); const auto keyWithMagicString (key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); char base64[SHA1_BASE64_SIZE]; sha1 (keyWithMagicString.c_str ()).finalize().print_base64 (base64); response.SetHeader (HTTP::Header ("Connection", "Upgrade")); response.SetHeader (HTTP::Header ("Upgrade", "websocket")); response.SetHeader (HTTP::Header ("Sec-WebSocket-Accept", std::string (base64))); response.mCode = HTTP::Code::SWITCHING_PROTOCOLS; isUpgraded = true; } } catch (...) {} mResponseEncoder.Write (response); { using namespace HTTP; LOGINFO << "HTTP/" << VersionToString (response.mVersion) << " " << MethodToString (inRequest.mMethod) << " " << inRequest.mPath << " - " << response.mCode << " " << CodeToString (response.mCode) << " - RFC6455"; } if (!isUpgraded) { Quit (); } else { // Clear the stream, route the pipe through the frame decoder. GetReadStream ().Clear ().Pipe (mFrameDecoder).Pipe (this, &Client::HandleReceivedFrame); mResponseEncoder.Clear (); mPayloadStringEncoder.Pipe (mFrameEncoder).Pipe (GetWriteStream ()); mPayloadBinaryEncoder.Pipe (mFrameEncoder); } }
void handleFilesRequest(const http::Request& request, http::Response* pResponse) { Options& options = session::options(); if (options.programMode() != kSessionProgramModeServer) { pResponse->setError(http::status::NotFound, request.uri() + " not found"); return; } // get prefix and uri std::string prefix = "/files/"; std::string uri = request.uri(); // validate the uri if (prefix.length() >= uri.length() || // prefix longer than uri uri.find(prefix) != 0 || // uri doesn't start with prefix uri.find("..") != std::string::npos) // uri has inavlid char sequence { pResponse->setError(http::status::NotFound, request.uri() + " not found"); return; } // compute path to file int prefixLen = prefix.length(); std::string relativePath = http::util::urlDecode(uri.substr(prefixLen)); if (relativePath.empty()) { pResponse->setError(http::status::NotFound, request.uri() + " not found"); return; } // complete path to file FilePath filePath = module_context::userHomePath().complete(relativePath); // no directory listing available if (filePath.isDirectory()) { pResponse->setError(http::status::NotFound, "No listing available for " + request.uri()); return; } pResponse->setNoCacheHeaders(); pResponse->setFile(filePath, request); }
void setAttachmentResponse(const http::Request& request, const std::string& filename, const FilePath& attachmentPath, http::Response* pResponse) { if (request.headerValue("User-Agent").find("MSIE") == std::string::npos) { pResponse->setNoCacheHeaders(); } else { // Can't set full no-cache headers because this breaks downloads in IE pResponse->setHeader("Expires", "Fri, 01 Jan 1990 00:00:00 GMT"); pResponse->setHeader("Cache-Control", "private"); } // Can't rely on "filename*" in Content-Disposition header because not all // browsers support non-ASCII characters here (e.g. Safari 5.0.5). If // possible, make the requesting URL contain the UTF-8 byte escaped filename // as the last path element. pResponse->setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + http::util::urlEncode(filename, false)); pResponse->setHeader("Content-Type", "application/octet-stream"); pResponse->setBody(attachmentPath); }
void Response::setMovedTemporarily(const http::Request& request, const std::string& location) { std::string uri = URL::complete(request.absoluteUri(), safeLocation(location)); setError(http::status::MovedTemporarily, uri); setHeader("Location", uri); }
int Server::handle(http::Server* server, http::Request& request, http::Response& response) { dfk_userdata_t user = (dfk_userdata_t) {nativeHandle()}; return dfk_fileserver_handler(user, server->nativeHandle(), request.nativeHandle(), response.nativeHandle()); }
BasicAuthenticator::BasicAuthenticator(const http::Request& request) { std::string scheme; std::string authInfo; request.getCredentials(scheme, authInfo); if (util::icompare(scheme, "Basic") == 0) { parseAuthInfo(authInfo); } else throw std::runtime_error("Basic authentication expected"); }
void WebSocketFramer::acceptRequest(http::Request& request, http::Response& response) { if (util::icompare(request.get("Connection", ""), "upgrade") == 0 && util::icompare(request.get("Upgrade", ""), "websocket") == 0) { std::string version = request.get("Sec-WebSocket-Version", ""); if (version.empty()) throw std::runtime_error("WebSocket error: Missing Sec-WebSocket-Version in handshake request"); //, ws::ErrorHandshakeNoVersion if (version != ws::ProtocolVersion) throw std::runtime_error("WebSocket error: Unsupported WebSocket version requested: " + version); //, ws::ErrorHandshakeUnsupportedVersion std::string key = util::trim(request.get("Sec-WebSocket-Key", "")); if (key.empty()) throw std::runtime_error("WebSocket error: Missing Sec-WebSocket-Key in handshake request"); //, ws::ErrorHandshakeNoKey response.setStatus(http::StatusCode::SwitchingProtocols); response.set("Upgrade", "websocket"); response.set("Connection", "Upgrade"); response.set("Sec-WebSocket-Accept", computeAccept(key)); // Set headerState 2 since the handshake was accepted. _headerState = 2; } else throw std::runtime_error("WebSocket error: No WebSocket handshake"); //, ws::ErrorNoHandshake }
void WRestResource::handleRequest(const Http::Request &request, Http::Response &response) { try { auto it = std::find(METHOD_STRINGS.cbegin(), METHOD_STRINGS.cend(), request.method()); auto idx = static_cast<std::size_t>(std::distance(METHOD_STRINGS.cbegin(), it)); if (it == METHOD_STRINGS.cend() || !handlers_[idx]) response.setStatus(405); } catch (Exception e) { response.setStatus(e.status()); } }
void EtagStoreResource::handle_etag(const Http::Request& request, Http::Response& response) { // TODO http://redmine.webtoolkit.eu/issues/2471 // const std::string* cookie_value = request.getCookieValue(cookie_name_); std::string cookies = request.headerValue("Cookie"); if (cookies.empty()) { return; } std::string pattern = cookie_name_ + "="; int cookie_begin = cookies.find(pattern); if (cookie_begin == std::string::npos) { return; } cookie_begin += pattern.length(); int cookie_end = cookies.find(';', cookie_begin); int cookie_length = (cookie_end == -1) ? -1 : (cookie_end - cookie_begin); std::string cookie_value = cookies.substr(cookie_begin, cookie_length); // std::string etag_value = request.headerValue(receive_header()); boost::mutex::scoped_lock lock(cookie_to_etag_mutex_); Map::iterator it = cookie_to_etag_.find(cookie_value); if (it == cookie_to_etag_.end()) { return; } Etag& etag = it->second; if (etag_value.empty()) { etag_value = etag.def; } etag.from_client = etag_value; if (!etag.to_client.empty()) { response.addHeader(send_header(), etag.to_client); etag.to_client.clear(); } else { etag.handler(etag.from_client); } if (!etag.from_client.empty()) { response.addHeader(send_header(), etag.from_client); } }
int main(int argc, char *argv[]) { HTTP::HeaderSet hs; hs.add("Content-Type", "text/plain"); assert(hs.has("Content-Type")); hs.add("Content-Length", "50823"); hs.add("Rubbish", "123"); hs.remove("Rubbish"); assert(!hs.has("Rubbish")); std::string hso = hs.toString(); assert_equal(hso, "Content-Length: 50823\r\nContent-Type: text/plain\r\n\r\n"); HTTP::HeaderSet *hsp = HTTP::HeaderSet::fromString(hso); assert(hsp && "parsed header must be valid"); std::string hspo = hsp->toString(); assert_equal(hspo, hso); //Test the HTTP::Request object. HTTP::Request req; req.type = HTTP::Request::kPOST; req.path = "/meta.json"; req.headers.add("Content-Type", "application/json"); req.headers.add("Content-Length", "11"); req.headers.add("User-Agent", "auris-db"); req.content = "Hello World"; std::string reqo = req.toString(); assert_equal(reqo, "POST /meta.json HTTP/1.1\r\nContent-Length: 11\r\nContent-Type: application/json\r\nUser-Agent: auris-db\r\n\r\nHello World\r\n"); HTTP::Request *reqp = HTTP::Request::fromString(reqo); assert(reqp && "parsed request must be valid"); std::string reqpo = reqp->toString(); assert_equal(reqpo, reqo); std::cout << reqo; return 0; }
void Server::deliver(http::Request& req) { /* google::protobuf::io::OstreamOutputStream out(&std::cerr); google::protobuf::TextFormat::Print(req_, &out); std::cout << "done\n"; */ wire::Message msg; msg.set_destination("/harq-http"); msg.set_payload(req.SerializeAsString()); queue_->write(msg); }
void onRequest(http::Request &request) { std::string ext = ".html"; std::string &url = request.getUrl(); // Retrieve a reference to he url in the request std::string extension = url.substr(url.size() - ext.size()); if (extension == ".html") // If the url ends in ".html" { std::string nUrl = url.substr(0, url.size() - ext.size()); nUrl += ".php"; url.assign(nUrl); // Update the url, our work here is done } }
bool validateCSRFForm(const http::Request& request, http::Response* pResponse) { // extract token from HTTP cookie (set above) std::string headerToken = request.cookieValue(kCSRFTokenName); http::Fields fields; // parse the form and check for a matching token http::util::parseForm(request.body(), &fields); std::string bodyToken = http::util::fieldValue<std::string>(fields, kCSRFTokenName, ""); // report an error if they don't match if (headerToken.empty() || bodyToken != headerToken) { pResponse->setStatusCode(http::status::BadRequest); pResponse->setBody("Missing or incorrect token."); return false; } // all is well return true; }
void handleContentRequest(const http::Request& request, http::Response* pResponse) { // get content file info std::string title; FilePath contentFilePath; Error error = contentFileInfo(request.uri(), &title, &contentFilePath); if (error) { pResponse->setError(error); return; } // set private cache forever headers pResponse->setPrivateCacheForeverHeaders(); // set file pResponse->setFile(contentFilePath, request); bool isUtf8 = true; if (boost::algorithm::starts_with(contentFilePath.mimeContentType(), "text/")) { // If the content looks like valid UTF-8, assume it is. Otherwise, assume // it's the system encoding. std::string contents; error = core::readStringFromFile(contentFilePath, &contents); if (!error) { for (std::string::iterator pos = contents.begin(); pos != contents.end(); ) { error = string_utils::utf8Advance(pos, 1, contents.end(), &pos); if (error) { isUtf8 = false; break; } } } } // reset content-type with charset pResponse->setContentType(contentFilePath.mimeContentType() + std::string("; charset=") + (isUtf8 ? "UTF-8" : ::locale2charset(NULL))); // set title header pResponse->setHeader("Title", title); }
void gdTVPdfResource::handleRequest(const Http::Request& request, Http::Response& response) { // is not a continuation for more data of a previous request if ( !request.continuation() ) { if ( !m_pTV ) return; std::string strPdf = gdWApp->getUserTmpFile("pdf"); fprintf(stderr, "construction du wtree2pdf\n"); gdViewToPdf* cPdf = new gdViewToPdf(strPdf.c_str(), m_pTV, 0, m_l1row); if ( !cPdf->m_pPdf ) return; fprintf(stderr, "Impression de la page\n"); cPdf->printPdfPage(1, 1, 0); delete cPdf; setFileName(strPdf); } WFileResource::handleRequest(request, response); // this was the last data for the request if ( !response.continuation() ) unlink(fileName().c_str()); }
void WebSocketFramer::createHandshakeRequest(http::Request& request) { assert(_mode == ws::ClientSide); assert(_headerState == 0); // Send the handshake request _key = createKey(); request.setChunkedTransferEncoding(false); request.set("Connection", "Upgrade"); request.set("Upgrade", "websocket"); request.set("Sec-WebSocket-Version", ws::ProtocolVersion); assert(request.has("Sec-WebSocket-Version")); request.set("Sec-WebSocket-Key", _key); assert(request.has("Sec-WebSocket-Key")); //TraceLS(this) << "Sec-WebSocket-Version: " << request.get("Sec-WebSocket-Version") << endl; //TraceLS(this) << "Sec-WebSocket-Key: " << request.get("Sec-WebSocket-Key") << endl; _headerState++; }
void setAttachmentResponse(const http::Request& request, const std::string& filename, const FilePath& attachmentPath, http::Response* pResponse) { if (request.headerValue("User-Agent").find("MSIE") == std::string::npos) { pResponse->setNoCacheHeaders(); } else { // Can't set full no-cache headers because this breaks downloads in IE pResponse->setHeader("Expires", "Fri, 01 Jan 1990 00:00:00 GMT"); pResponse->setHeader("Cache-Control", "private"); } pResponse->setHeader("Content-Disposition", "attachment; filename=" + http::util::urlEncode(filename, false)); pResponse->setBody(attachmentPath); }
void handleTemplateRequest(const FilePath& templatePath, const http::Request& request, http::Response* pResponse) { // setup template variables std::map<std::string,std::string> variables ; http::Fields queryParams = request.queryParams(); for (http::Fields::const_iterator it = queryParams.begin(); it != queryParams.end(); ++it) { variables[it->first] = it->second; } // return browser page (processing template) pResponse->setNoCacheHeaders(); text::TemplateFilter templateFilter(variables); pResponse->setFile(templatePath, request, templateFilter); pResponse->setContentType("text/html"); }
void RequestHandlerGET::HandleRequest( const http::Request& request, http::Response* response) const { string path; string rest; string fragment; if (!DecodeURL(request.uri(), &path, &rest, &fragment)) { *response = Response::StockResponse(Response::BAD_REQUEST); return; } LOG_DEBUG(logger_, "path: " << path) LOG_DEBUG(logger_, "rest: " << rest) LOG_DEBUG(logger_, "fragment: " << fragment) string full_path = root_directory_ + path; LOG_DEBUG(logger_, full_path) CreateResponse(full_path, response); }
virtual void handleRequest(const Http::Request& request, Http::Response& response) { bool triggerUpdate = false; std::vector<Http::UploadedFile> files; #ifdef WT_TARGET_JAVA static Http::UploadedFile* uploaded; #endif Utils::find(request.uploadedFiles(), "data", files); if (!request.tooLarge()) if (!files.empty() || request.getParameter("data")) triggerUpdate = true; response.setMimeType("text/html; charset=utf-8"); response.addHeader("Expires", "Sun, 14 Jun 2020 00:00:00 GMT"); response.addHeader("Cache-Control", "max-age=315360000"); #ifndef WT_TARGET_JAVA std::ostream& o = response.out(); #else std::ostream o(response.out()); #endif // WT_TARGET_JAVA o << "<!DOCTYPE html>" "<html>\n" "<head><script type=\"text/javascript\">\n" "function load() { "; if (triggerUpdate || request.tooLarge()) { o << "if (window.parent." << WApplication::instance()->javaScriptClass() << ") "; if (triggerUpdate) { LOG_DEBUG("Resource handleRequest(): signaling uploaded"); o << "window.parent." << WApplication::instance()->javaScriptClass() << "._p_.update(null, '" << fileUpload_->uploaded().encodeCmd() << "', null, true);"; } else if (request.tooLarge()) { LOG_DEBUG("Resource handleRequest(): signaling file-too-large"); o << "window.parent." << WApplication::instance()->javaScriptClass() << "._p_.update(null, '" << fileUpload_->fileTooLargeImpl().encodeCmd() << "', null, true);"; } } else { LOG_DEBUG("Resource handleRequest(): no signal"); } o << "}\n" "</script></head>" "<body onload=\"load();\"></body></html>"; if (request.tooLarge()) fileUpload_->tooLargeSize_ = request.tooLarge(); else if (!files.empty()) fileUpload_->setFiles(files); }
void DataStore::handleRequest(const Http::Request& request, Http::Response& response) { response.setMimeType("text/x-json"); WModelIndexList matches; if (modelFilterColumn_ != -1) { WString query; const std::string *queryE = request.getParameter("query"); if (queryE) query = WString::fromUTF8(*queryE); matches = model_->match(model_->index(0, modelFilterColumn_), DisplayRole, boost::any(query)); } int start = 0; int rowCount = (modelFilterColumn_ == -1 ? model_->rowCount() : matches.size()); int limit = rowCount; const std::string *s; s = request.getParameter("start"); if (s) try { start = std::max(0, std::min(limit, boost::lexical_cast<int>(*s))); } catch (boost::bad_lexical_cast& e) { LOG_ERROR("start '" << *s << "' is not-a-number."); } s = request.getParameter("limit"); if (s) try { limit = std::max(0, std::min(limit - start, boost::lexical_cast<int>(*s))); } catch (boost::bad_lexical_cast& e) { LOG_ERROR("limit '" << *s << "' is not-a-number."); } std::ostream& o = response.out(); o << "{" << "'count':" << rowCount << "," << "'data':["; for (int row = start; row < start + limit; ++row) { if (row != start) o << ","; o << "{"; int modelRow = modelFilterColumn_ == -1 ? row : matches[row].row(); o << "'id':" << getRecordId(modelRow); for (unsigned j = 0; j < columns_.size(); ++j) o << ",'" << columns_[j].fieldName << "':" << dataAsJSLiteral(modelRow, columns_[j].modelColumn); o << "}"; } o << "]}"; }
void handleMultipleFileExportRequest(const http::Request& request, http::Response* pResponse) { // name parameter std::string name = request.queryParamValue("name"); if (name.empty()) { pResponse->setError(http::status::BadRequest, "name not specified"); return; } // parent parameter std::string parent = request.queryParamValue("parent"); if (parent.empty()) { pResponse->setError(http::status::BadRequest, "parent not specified"); return; } FilePath parentPath = module_context::resolveAliasedPath(parent); if (!parentPath.exists()) { pResponse->setError(http::status::BadRequest, "parent doesn't exist"); return; } // files parameters (paths relative to parent) std::vector<std::string> files; for (int i=0; ;i++) { // get next file (terminate when we stop finding files) std::string fileParam = "file" + boost::lexical_cast<std::string>(i); std::string file = request.queryParamValue(fileParam); if (file.empty()) break; // verify that the file exists FilePath filePath = parentPath.complete(file); if (!filePath.exists()) { pResponse->setError(http::status::BadRequest, "file " + file + " doesn't exist"); return; } // add it files.push_back(file); } // create the zip file FilePath tempZipFilePath = module_context::tempFile("export", "zip"); Error error = r::exec::RFunction(".rs.createZipFile", tempZipFilePath.absolutePath(), parentPath.absolutePath(), files).call(); if (error) { LOG_ERROR(error); pResponse->setError(error); return; } // return attachment setAttachmentResponse(request, name, tempZipFilePath, pResponse); }
void handleFileUploadRequest(const http::Request& request, http::Response* pResponse) { // response content type must always be text/html to be handled // properly by the browser/gwt on the client side pResponse->setContentType("text/html"); // get fields const http::File& file = request.uploadedFile("file"); std::string targetDirectory = request.formFieldValue("targetDirectory"); // first validate that we got the required fields if (file.name.empty() || targetDirectory.empty()) { json::setJsonRpcError(json::errc::ParamInvalid, pResponse); return; } // now validate the file if ( !validateUploadedFile(file, pResponse) ) return ; // form destination path FilePath destDir = module_context::resolveAliasedPath(targetDirectory); FilePath destPath = destDir.childPath(file.name); // establish whether this is a zip file and create appropriate temp file path bool isZip = destPath.extensionLowerCase() == ".zip"; FilePath tempFilePath = module_context::tempFile("upload", isZip ? "zip" : "bin"); // attempt to write the temp file Error saveError = core::writeStringToFile(tempFilePath, file.contents); if (saveError) { LOG_ERROR(saveError); json::setJsonRpcError(saveError, pResponse); return; } // detect any potential overwrites json::Array overwritesJson; if (isZip) { Error error = detectZipFileOverwrites(tempFilePath, destDir, &overwritesJson); if (error) { LOG_ERROR(error); json::setJsonRpcError(error, pResponse); return; } } else { if (destPath.exists()) overwritesJson.push_back(module_context::createFileSystemItem(destPath)); } // set the upload information as the result json::Object uploadTokenJson; uploadTokenJson[kUploadFilename] = file.name; uploadTokenJson[kUploadedTempFile] = tempFilePath.absolutePath(); uploadTokenJson[kUploadTargetDirectory] = destDir.absolutePath(); json::Object uploadJson; uploadJson["token"] = uploadTokenJson; uploadJson["overwrites"] = overwritesJson; json::setJsonRpcResult(uploadJson, pResponse); }
void Connection::write(HTTP::Request &r) { write(r.toString()); }