예제 #1
0
	websocketpp::http::status_code::value FileServer::handlePostRequest(const websocketpp::http::parser::request& aRequest,
		std::string& output_, StringPairList& headers_, const SessionPtr& aSession) noexcept {

		const auto& requestPath = aRequest.get_uri();
		if (requestPath == "/temp") {
			if (!aSession || !aSession->getUser()->hasPermission(Access::FILESYSTEM_EDIT)) {
				output_ = "Not authorized";
				return websocketpp::http::status_code::unauthorized;
			}

			const auto fileName = Util::toString(Util::rand());
			const auto filePath = Util::getTempPath() + fileName;

			try {
				File file(filePath, File::WRITE, File::TRUNCATE | File::CREATE, File::BUFFER_SEQUENTIAL);
				file.write(aRequest.get_body());
			} catch (const FileException& e) {
				output_ = "Failed to write the file: " + e.getError();
				return websocketpp::http::status_code::internal_server_error;
			}

			{
				WLock l(cs);
				tempFiles.emplace(fileName, filePath);
			}

			headers_.emplace_back("Location", fileName);
			return websocketpp::http::status_code::created;
		}

		output_ = "Requested resource was not found";
		return websocketpp::http::status_code::not_found;
	}
예제 #2
0
StringPairList ShareManager::getDirectories() const noexcept {
	Lock l(cs);
	StringPairList ret;
	for(auto& i: shares) {
		ret.emplace_back(i.second, i.first);
	}
	return ret;
}
예제 #3
0
	websocketpp::http::status_code::value FileServer::handleRequest(const string& aResource, const websocketpp::http::parser::request& aRequest,
		string& output_, StringPairList& headers_) noexcept {

		dcassert(!resourcePath.empty());
		dcdebug("Requesting file %s\n", aResource.c_str());

		// Get the disk path path
		string request;
		if (aResource.length() >= 6 && aResource.compare(0, 6, "/view/") == 0) {
			try {
				request = parseViewFilePath(aResource.substr(6));
			} catch (const std::exception& e) {
				output_ = e.what();
				return websocketpp::http::status_code::bad_request;
			}
		} else {
			request = parseResourcePath(aResource, aRequest, headers_);
		}

		// Read file
		try {
			File f(request, File::READ, File::OPEN);
			output_ = f.read();
		} catch (const FileException& e) {
			output_ = e.getError();
			return websocketpp::http::status_code::not_found;
		}

		// Get the mime type
		auto extension = getExtension(request);
		for (int i = 0; mimes[i].ext != NULL; i++) {
			if (extension == mimes[i].ext) {
				headers_.emplace_back("Content-Type", mimes[i].type);
				break;
			}
		}

		return websocketpp::http::status_code::ok;
	}
예제 #4
0
	string FileServer::parseResourcePath(const string& aResource, const websocketpp::http::parser::request& aRequest, StringPairList& headers_) const noexcept {
		auto request = aResource;

		auto extension = getExtension(request);
		if (!extension.empty()) {
			// Strip the dot
			extension = extension.substr(1);

			// We have compressed versions only for JS files
			if (extension == "js" && aRequest.get_header("Accept-Encoding").find("gzip") != string::npos) {
				request += ".gz";
				headers_.emplace_back("Content-Encoding", "gzip");
			}
		} else if (request.find("/build") != 0 && request != "/favicon.ico") {
			// Forward all requests for non-static files to index
			request = "/index.html";
		}

		// For windows
		Util::replace(request, "/", PATH_SEPARATOR_STR);

		return resourcePath + request;
	}
예제 #5
0
	websocketpp::http::status_code::value FileServer::handleGetRequest(const websocketpp::http::parser::request& aRequest,
		string& output_, StringPairList& headers_, const SessionPtr& aSession) noexcept {

		const auto& requestUrl = aRequest.get_uri();
		dcdebug("Requesting file %s\n", requestUrl.c_str());

		// Get the disk path
		string filePath;
		try {
			if (requestUrl.length() >= 6 && requestUrl.compare(0, 6, "/view/") == 0) {
				filePath = parseViewFilePath(requestUrl.substr(6), headers_, aSession);
			} else {
				filePath = parseResourcePath(requestUrl, aRequest, headers_);
			}
		} catch (const RequestException& e) {
			output_ = e.what();
			return e.getCode();
		}

		auto fileSize = File::getSize(filePath);
		int64_t startPos = 0, endPos = fileSize - 1;

		auto partialContent = parsePartialRange(aRequest.get_header("Range"), startPos, endPos);

		// Read file
		try {
			File f(filePath, File::READ, File::OPEN);
			f.setPos(startPos);
			output_ = f.read(static_cast<size_t>(endPos) + 1);
		} catch (const FileException& e) {
			dcdebug("Failed to serve the file %s: %s\n", filePath.c_str(), e.getError().c_str());
			output_ = e.getError();
			return websocketpp::http::status_code::not_found;
		} catch (const std::bad_alloc&) {
			output_ = "Not enough memory on the server to serve this request";
			return websocketpp::http::status_code::internal_server_error;
		}

		{
			const auto ext = Util::getFileExt(filePath);
			if (ext == ".nfo") {
				string encoding;

				// Platform-independent encoding conversion function could be added if there is more use for it
#ifdef _WIN32
				encoding = "CP.437";
#else
				encoding = "cp437";
#endif
				output_ = Text::toUtf8(output_, encoding);
			} else if (ext == ".gz" && aRequest.get_header("Accept-Encoding").find("gzip") != string::npos) {
				headers_.emplace_back("Content-Encoding", "gzip");
			}
		}

		{
			// Get the mime type (but get it from the original request with gzipped content)
			auto usingEncoding = find_if(headers_.begin(), headers_.end(), CompareFirst<string, string>("Content-Encoding")) != headers_.end();
			auto type = getMimeType(usingEncoding ? requestUrl : filePath);
			if (type) {
				headers_.emplace_back("Content-Type", type);
			}
		}

		if (partialContent) {
			headers_.emplace_back("Content-Range", formatPartialRange(startPos, endPos, fileSize));
			headers_.emplace_back("Accept-Ranges", "bytes");
			return websocketpp::http::status_code::partial_content;
		}

		return websocketpp::http::status_code::ok;
	}
예제 #6
0
	void FileServer::addCacheControlHeader(StringPairList& headers_, int aDaysValid) noexcept {
		headers_.emplace_back("Cache-Control", aDaysValid == 0 ? "no-store" : "max-age=" + Util::toString(aDaysValid * 24 * 60 * 60));
	}