void EtagStoreResource::handleRequest(const Http::Request& request, Http::Response& response) { handle_etag(request, response); response.setMimeType("image/gif"); response.addHeader("Content-Length", TO_S(EMPTY_GIF_SIZE)); response.out().write(EMPTY_GIF, EMPTY_GIF_SIZE); }
/* * Throws XMLTree::PraseException and other * std::exception's from string methods */ std::vector<std::string> BaseService::parseGenericResponse(const Http::Response& response, const char *expectedId) const { XMLTree responseTree(false, response.getBodyPtr(), response.getBodyLen()); XMLElement element = responseTree.getRootElement(); std::vector<std::string> responses; if (element.isNamed(RESPONSE_SET)) { std::string version; std::string requestId; if (element.getAttributeValue(VERSION, version) && std::strcmp(version.c_str(), RESPONSE_SET_VERSION) == 0 && element.getAttributeValue(REQUEST_ID, requestId) && std::strcmp(requestId.c_str(), expectedId) == 0) { std::string responseData; for (element = element.getFirstSubElement(); element.isNamed(RESPONSE); element.nextSibling()) { if (element.getValue(responseData)) { responses.push_back(responseData); } else { element.log(logModule, Log::LOG_ERROR); throw XMLTree::ParseException("unable to get Response " "data"); } } if (element.isValid()) { element.log(logModule, Log::LOG_ERROR); throw XMLTree::ParseException("unexpected element in " "ResponseSet"); } } else if (std::strcmp(version.c_str(), RESPONSE_SET_VERSION) == 0) { element.log(logModule, Log::LOG_ERROR); throw XMLTree::ParseException(std::string("missing or mismatched " "request id in " "ResponseSet: ") + requestId); } else { element.log(logModule, Log::LOG_ERROR); throw XMLTree::ParseException(std::string("missing or unsupported " "version in " "ResponseSet: ") + version); } } else { element.log(logModule, Log::LOG_ERROR); throw XMLTree::ParseException("unexpected element in response"); } return responses; }
/** * Fetches agent profile attributes using REST attribute service * Agent has to be authenticated before doing this. * If successful, properties object gets loaded with profile attributes */ am_status_t AgentProfileService::getAgentAttributes( const std::string appSSOToken, const std::string sharedAgentProfileName, const std::string realmName, am_properties_t properties) { am_status_t status = AM_FAILURE; Http::Response response; std::string certName; std::string::size_type pos; std::string encodedAgentToken = Http::encode(appSSOToken); std::string encodedSharedAgentProfileName = Http::encode(sharedAgentProfileName); std::string encodedRealmName = Http::encode(realmName); std::string urlParams = "?name="; urlParams.append(encodedSharedAgentProfileName); urlParams.append("&attributes_names=realm"); urlParams.append("&attributes_values_realm="); urlParams.append(encodedRealmName); urlParams.append("&attributes_names=objecttype"); urlParams.append("&attributes_values_objecttype=Agent" ); urlParams.append("&admin=" ); urlParams.append(encodedAgentToken); try { setRestSvcInfo(mRestURL); } catch (InternalException &iex) { status = AM_FAILURE; } status = doHttpGet(mRestSvcInfo, urlParams, Http::CookieList(), response, READ_INIT_BUF_LEN, certName); if(status == AM_SUCCESS) { std::string xmlResponse(response.getBodyPtr()); pos = xmlResponse.find(EXCEPTION,0); if(pos != std::string::npos){ status = AM_REST_ATTRS_SERVICE_FAILURE; } else { try { status = parseAgentResponse(xmlResponse, properties); } catch(...) { Log::log(logModule, Log::LOG_ERROR, "parseAgentResponse(): Attribute xml parsing error"); status = AM_REST_ATTRS_SERVICE_FAILURE; } } } else { status = AM_REST_ATTRS_SERVICE_FAILURE; } return status; }
void WebSocketFramer::completeHandshake(http::Response& response) { std::string connection = response.get("Connection", ""); if (util::icompare(connection, "Upgrade") != 0) throw std::runtime_error("WebSocket error: No Connection: Upgrade header in handshake response"); //, ws::ErrorNoHandshake std::string upgrade = response.get("Upgrade", ""); if (util::icompare(upgrade, "websocket") != 0) throw std::runtime_error("WebSocket error: No Upgrade: websocket header in handshake response"); //, ws::ErrorNoHandshake std::string accept = response.get("Sec-WebSocket-Accept", ""); if (accept != computeAccept(_key)) throw std::runtime_error("WebSocket error: Invalid or missing Sec-WebSocket-Accept header in handshake response"); //, 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 WRasterImage::handleRequest(const Http::Request& request, Http::Response& response) { response.setMimeType("image/" + impl_->type_); RasterStream s(response.out()); if (impl_->type_ == "png") SkImageEncoder::EncodeStream(&s, *impl_->bitmap_, SkImageEncoder::kPNG_Type, 100); else if (impl_->type_ == "jpg") SkImageEncoder::EncodeStream(&s, *impl_->bitmap_, SkImageEncoder::kJPEG_Type, 100); }
void Authenticator::authenticate(http::Request& request, const http::Response& response) { for (http::Response::ConstIterator iter = response.find("WWW-Authenticate"); iter != response.end(); ++iter) { if (isBasicCredentials(iter->second)) { BasicAuthenticator(_username, _password).authenticate(request); return; } // else if (isDigestCredentials(iter->second)) // ; // TODO } }
bool Client::Register() { Json::Value data(Json::objectValue); data["ip"] = Config::getIPAddr(); data["port"] = Config::getListenPort(); data["name"] = Config::getServerName(); data["terrain-name"] = Config::getTerrainName(); data["max-clients"] = Config::getMaxClients(); data["version"] = RORNET_VERSION; data["use-password"] = Config::isPublic(); m_server_path = "/" + Config::GetServerlistPath() + "/server-list"; Logger::Log(LOG_INFO, "Attempting to register on serverlist (%s)", m_server_path.c_str()); Http::Response response; int result_code = this->HttpRequest(Http::METHOD_POST, data.toStyledString().c_str(), &response); if (result_code < 0) { Logger::Log(LOG_ERROR, "Registration failed, result code: %d", result_code); return false; } else if (result_code != 200) { Logger::Log(LOG_INFO, "Registration failed, response code: HTTP %d, body: %s", result_code, response.GetBody().c_str()); return false; } Json::Value root; Json::Reader reader; if (!reader.parse(response.GetBody().c_str(), root)) { Logger::Log(LOG_ERROR, "Registration failed, invalid server response (JSON parsing failed)"); Logger::Log(LOG_DEBUG, "Raw response: %s", response.GetBody().c_str()); return false; } Json::Value trust_level = root["verified-level"]; Json::Value challenge = root["challenge"]; if (!root.isObject() || !trust_level.isNumeric() || !challenge.isString()) { Logger::Log(LOG_ERROR, "Registration failed, incorrect response from server"); Logger::Log(LOG_DEBUG, "Raw response: %s", response.GetBody().c_str()); return false; } m_token = challenge.asString(); m_trust_level = trust_level.asInt(); m_is_registered = true; return true; }
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); } }
bool RetrievePublicIp() { char url[300] = ""; sprintf(url, "/%s/get-public-ip", Config::GetServerlistPath().c_str()); Http::Response response; int result_code = Http::Request(Http::METHOD_GET, Config::GetServerlistHostC(), url, "application/json", "", &response); if (result_code < 0) { Logger::Log(LOG_ERROR, "Failed to retrieve public IP address"); return false; } Config::setIPAddr(response.GetBody()); return true; }
IpAddress IpAddress::getPublicAddress(Time timeout) { // The trick here is more complicated, because the only way // to get our public IP address is to get it from a distant computer. // Here we get the web page from http://www.sfml-dev.org/ip-provider.php // and parse the result to extract our IP address // (not very hard: the web page contains only our IP address). Http server("www.sfml-dev.org"); Http::Request request("/ip-provider.php", Http::Request::Get); Http::Response page = server.sendRequest(request, timeout); if (page.getStatus() == Http::Response::Ok) return IpAddress(page.getBody()); // Something failed: return an invalid address return IpAddress(); }
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()); }
void API::VersionEndPoint::Get (const HTTP::Request& inRequest, HTTP::Response& outResponse) { json j; j["application"] = OS::Version::GetApplicationName (); j["version"] = OS::Version::GetApplicationVersion (); outResponse.mCode = HTTP::Code::OK; outResponse.SetBody (j.dump (), "application/json"); }
am_status_t BaseService::doHttpPost(const ServiceInfo& service, const std::string& uriParameters, const Http::CookieList& cookieList, const BodyChunkList& bodyChunkList, Http::Response& response, std::size_t initialBufferLen, const std::string &cert_nick_name, bool doFormPost, bool checkHTTPRetCode, const ServerInfo **serverInfo) const { am_status_t status; if(doFormPost) { status = doRequest(service, postPrefixChunk, uriParameters, cookieList, postFormSuffixChunk, bodyChunkList, response, initialBufferLen, cert_nick_name, serverInfo); } else { status = doRequest(service, postPrefixChunk, uriParameters, cookieList, postSuffixChunk, bodyChunkList, response, initialBufferLen, cert_nick_name, serverInfo); } if (checkHTTPRetCode && (AM_SUCCESS == status && Http::OK != response.getStatus())) { Http::Status httpStatus = response.getStatus(); if (Http::NOT_FOUND == httpStatus) { status = AM_NOT_FOUND; } else if (Http::FORBIDDEN == httpStatus) { status = AM_ACCESS_DENIED; } else { Log::log(logModule, Log::LOG_WARNING, "BaseService::doHttpPost() failed, HTTP error = %d", httpStatus); status = AM_HTTP_ERROR; } } return status; }
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 WPdfImage::handleRequest(const Http::Request& request, Http::Response& response) { HPDF_SaveToStream(pdf_); HPDF_ResetStream(pdf_); response.setMimeType("application/pdf"); for (;;) { HPDF_BYTE buf[4096]; HPDF_UINT32 siz = 4096; HPDF_ReadFromStream (pdf_, buf, &siz); if (siz == 0) break; response.out().write((const char *)buf, siz); } }
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); } }
bool WebSocketFramer::checkHandshakeResponse(http::Response& response) { assert(_mode == ws::ClientSide); assert(_headerState == 1); if (response.getStatus() == http::StatusCode::SwitchingProtocols) { // Complete handshake or throw completeHandshake(response); // Success _headerState++; assert(handshakeComplete()); return true; } else if (response.getStatus() == http::StatusCode::Unauthorized) assert(0 && "authentication not implemented"); else throw std::runtime_error("WebSocket error: Cannot upgrade to WebSocket connection: " + response.getReason()); //, ws::ErrorNoHandshake // Need to resend request return false; }
am_status_t BaseService::doHttpPost(const ServiceInfo& service, const std::string& uriParameters, const Http::CookieList& cookieList, const BodyChunkList& bodyChunkList, Http::Response& response, bool doFormPost, bool checkHTTPRetCode, const ServerInfo **serverInfo) const { am_status_t status; if (doFormPost) { status = doRequest(service, BodyChunk(std::string(HTTP_POST_PREFIX)), uriParameters, cookieList, BodyChunk(std::string(HTTP_POST_FORM_SUFFIX)), bodyChunkList, response, serverInfo); } else { status = doRequest(service, BodyChunk(std::string(HTTP_POST_PREFIX)), uriParameters, cookieList, BodyChunk(std::string(HTTP_POST_SUFFIX)), bodyChunkList, response, serverInfo); } if (checkHTTPRetCode && (AM_SUCCESS == status && Http::OK != response.getStatus())) { Http::Status httpStatus = response.getStatus(); if (Http::NOT_FOUND == httpStatus) { status = AM_NOT_FOUND; } else if (Http::FORBIDDEN == httpStatus) { status = AM_ACCESS_DENIED; } else { Log::log(logModule, Log::LOG_ERROR, "BaseService::doHttpPost() failed, HTTP error = %d", httpStatus); status = AM_HTTP_ERROR; } } return status; }
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 Server::send_reply(http::Response& rep) { Connection* con = connections_[rep.stream_id()]; std::stringstream out; out << "HTTP/1.1 " << rep.status() << " Did it\r\n"; for(int i = 0; i < rep.headers_size(); i++) { const http::Header& h = rep.headers(i); out << h.custom_key() << ": " << h.value() << "\r\n"; } out << "Content-Length: " << rep.body().size() << "\r\n"; out << "\r\n"; std::cout << "<DEBUG>\n" << out.str() << "\n</DEBUG>\n"; con->write(out.str()); con->write(rep.body()); }
void SSE::Client::HandleHandshake (const HTTP::Request& inRequest) { HTTP::Response response (HTTP::Code::BAD_REQUEST, inRequest.mVersion); bool isUpgraded (false); try { if (inRequest.GetHeaderValue ("Accept") == "text/event-stream" && inRequest.mMethod == HTTP::Method::GET && inRequest.mVersion == HTTP::Version::V11 ) { // Standard SSE headers response.SetHeader (HTTP::Header ("Connection", "keep-alive")); response.SetHeader (HTTP::Header ("Content-Type", "text/event-stream")); // Prevent caching response.SetHeader (HTTP::Header ("Cache-Control", "no-cache")); // This SSE server most likely does not host the origin of the request // ==> Enable CORS. response.SetHeader (HTTP::Header ("Access-Control-Allow-Origin", "*")); response.SetHeader (HTTP::Header ("Access-Control-Allow-Credentials", "true")); // The response constructor sets the length to zero, this makes connections // assume there is no more data coming. Note: there is a stream in response, so the body // has variable length! Remove this header. response.RemoveHeaders ("Content-Length"); // Optionally check for last event ID. try { const auto list = inRequest.GetHeaders ("Last-Event-ID"); if (!list.empty ()) { uint8_t lastId = std::stoi (list[0].GetValue ()); mEventEncoder.SetLastId (lastId); } } catch (...) {} // Handshake completed. response.mCode = HTTP::Code::OK; isUpgraded = true; } } catch (...) {} // Send the handshake response mResponseEncoder.Write (response); { using namespace HTTP; LOGINFO << "HTTP/" << VersionToString (response.mVersion) << " " << MethodToString (inRequest.mMethod) << " " << inRequest.mPath << " - " << response.mCode << " " << CodeToString (response.mCode) << " - SSE"; } if (!isUpgraded) { Quit (); } else { // Clear the read stream (SSE only contains outgoing events) GetReadStream ().Clear (); mResponseEncoder.Clear (); mToStringConverter.Clear (); mToPacketConverter.Clear (); mRequestDecoder.Clear (); mResponseEncoder.Clear (); mEventEncoder.Pipe (mToPacketConverter).Pipe (GetWriteStream ()); } }
am_status_t BaseService::doRequest(const ServiceInfo& service, const BodyChunk& headerPrefix, const std::string& uriParameters, const Http::CookieList& cookieList, const BodyChunk& headerSuffix, const BodyChunkList& bodyChunkList, Http::Response& response, const ServerInfo** serverInfo) const { am_status_t status = AM_SERVICE_NOT_AVAILABLE; int dataLen = 0; BodyChunk emptyContentLine; // Create a temporary buffer for the Content-Line header // the extra '2' is for the <CR><LF> at the end. The // sizeof the CONTENT_LENGTH_HDR includes space for the // terminating NUL. const std::size_t contentLineLen_sz = sizeof (CONTENT_LENGTH_HDR) + (sizeof (dataLen) * DIGITS_PER_BYTE) + 2; char contentLine[contentLineLen_sz + 1]; std::size_t contentLineLen = 0; for (unsigned int i = 0; i < bodyChunkList.size(); ++i) { dataLen += bodyChunkList[i].data.size(); } memset(&contentLine[0], 0, contentLineLen_sz); contentLineLen = snprintf(contentLine, contentLineLen_sz, "%s%d\r\n", CONTENT_LENGTH_HDR, dataLen); if (contentLineLen_sz > contentLineLen && contentLineLen > 0) { BodyChunk contentLineChunk(contentLine, contentLineLen); ServiceInfo::const_iterator iter; ServiceInfo svc(service); int j = -1, current_index = -1; if (am_web_naming_validation_status() < 2 && svc.getNumberOfServers() > 1) { /* validation is enabled and number of servers is more than one */ char *current_value = read_naming_value(AM_NAMING_LOCK, Log::getLockId()); if (current_value != NULL) { current_index = strtol(current_value, NULL, 10); if (current_index < 0 || errno == ERANGE) { current_index = 0; } else { Log::log(logModule, Log::LOG_MAX_DEBUG, "BaseService::doRequest(): will be using url index: %d", current_index); } free(current_value); } else { current_index = 0; } if ((size_t) current_index >= svc.getNumberOfServers()) { Log::log(logModule, Log::LOG_WARNING, "BaseService::doRequest(): invalid url index: %d (out of %d); validation results ignored.", current_index, svc.getNumberOfServers()); current_index = -1; } } for (iter = svc.begin(); iter != svc.end(); ++iter) { const ServerInfo &svrInfo = (*iter); if (current_index != -1) { if ((++j) != current_index) { Log::log(logModule, Log::LOG_MAX_DEBUG, "BaseService::doRequest(): skipping url(%d) %s", j, svrInfo.getURL().c_str()); continue; } else { Log::log(logModule, Log::LOG_MAX_DEBUG, "BaseService::doRequest(): using url(%d) %s", j, svrInfo.getURL().c_str()); } } Http::HeaderList headerList, proxyHeaderList; Http::Cookie hostHeader("Host", svrInfo.getHost()); headerList.push_back(hostHeader); #ifdef AGENT_PROXY_SUPPORT #ifndef _MSC_VER if (useProxy) { proxyHeaderList.push_back(hostHeader); // Override (temporarily) server credentials if using proxy //svrInfo.setHost(proxyHost); //svrInfo.setPort(proxyPort); // We don't use SSL for initial proxy connection //svrInfo.setUseSSL(false); Log::log(logModule, Log::LOG_DEBUG, "BaseService::doRequest(): Using proxy: %s:%d", proxyHost.c_str(), proxyPort); // Add Proxy-Authorization header if user defined if (useProxyAuth) { // allocate enough for a base64-encoded digest size_t authSize = proxyUser.size() + proxyPassword.size() + 1; // 11 extra bytes for prefix and terminator char * digest = (char *) malloc(authSize * 4 / 3 + 11); strcpy(digest, "Basic "); encode_base64((proxyUser + ":" + proxyPassword).c_str(), authSize, (digest + 6)); Log::log(logModule, Log::LOG_MAX_DEBUG, "BaseService::doRequest(): Using proxy auth as: %s", proxyUser.c_str()); hostHeader = Http::Cookie("Proxy-Authorization", digest); proxyHeaderList.push_back(hostHeader); free(digest); } } #endif #endif // retry to connect to server before marking it as down. // making the number of attempts configurable may have a negative // side effect on performance, if the the value is a high number. int retryAttempts = 3; int retryCount = 0; while (retryCount < retryAttempts) { retryCount++; try { const char *operation = "sending to"; Connection conn(svrInfo.getHost().c_str(), svrInfo.getPort(), svrInfo.useSSL()); #ifdef AGENT_PROXY_SUPPORT std::string requestString = svrInfo.getURI().c_str(); /* * In case the following request would go to a proxy * we need to use full URL and special headers. */ if (useProxy && !(iter->useSSL())) { requestString = iter->getURL(); headerList = proxyHeaderList; } #endif status = sendRequest(conn, headerPrefix, svrInfo.getURI(), uriParameters, headerList, cookieList, dataLen > 0 ? contentLineChunk : emptyContentLine, headerSuffix, bodyChunkList); if (AM_SUCCESS == status) { operation = "receiving from"; status = response.readAndParse(logModule, conn); if (AM_SUCCESS == status) { Log::log(logModule, Log::LOG_MAX_DEBUG, "Response::readAndParse() (%d) %s", response.getBodyLen(), response.getBodyPtr() ? response.getBodyPtr() : "(NULL)"); } } if (AM_NSPR_ERROR == status) { Log::log(logModule, Log::LOG_ALWAYS, "BaseService::doRequest() NSPR failure while " "%s %s", operation, svrInfo.getURL().c_str()); } if (AM_SUCCESS == status) { break; } else { if (retryCount < retryAttempts) { continue; } else { Log::log(logModule, Log::LOG_DEBUG, "BaseService::doRequest() Invoking markSeverDown"); /*svrInfo.markServerDown(poll_primary_server);*/ } } } catch (const NSPRException& exc) { Log::log(logModule, Log::LOG_ERROR, "BaseService::doRequest() caught %s: %s called by %s", exc.what(), exc.getNsprMethod(), exc.getThrowingMethod()); if (retryCount < retryAttempts) { status = AM_NSPR_ERROR; continue; } else { Log::log(logModule, Log::LOG_ERROR, "BaseService::doRequest() Invoking markSeverDown"); /*svrInfo.markServerDown(poll_primary_server);*/ status = AM_NSPR_ERROR; } } } //end of while if (AM_SUCCESS == status) { break; } } // end of for } else { status = AM_BUFFER_TOO_SMALL; } return status; }
am_status_t BaseService::doRequest(const ServiceInfo& service, const BodyChunk& headerPrefix, const std::string& uriParameters, const Http::CookieList& cookieList, const BodyChunk& headerSuffix, const BodyChunkList& bodyChunkList, Http::Response& response, std::size_t initialBufferLen, const std::string &cert_nick_name, const ServerInfo** serverInfo) const { am_status_t status = AM_SERVICE_NOT_AVAILABLE; std::size_t dataLen = 0; // Create a temporary buffer for the Content-Line header // the extra '2' is for the <CR><LF> at the end. The // sizeof the CONTENT_LENGTH_HDR includes space for the // terminating NUL. char contentLine[sizeof(CONTENT_LENGTH_HDR) + (sizeof(dataLen) * DIGITS_PER_BYTE) + 2]; std::size_t contentLineLen; for (unsigned int i = 0; i < bodyChunkList.size(); ++i) { dataLen += bodyChunkList[i].data.size(); } contentLineLen = snprintf(contentLine, sizeof(contentLine), "%s%d\r\n", CONTENT_LENGTH_HDR, dataLen); if (sizeof(contentLine) > contentLineLen) { BodyChunk contentLineChunk(contentLine, contentLineLen); ServiceInfo::const_iterator iter; for (iter = service.begin(); iter != service.end(); ++iter) { ServerInfo svrInfo = ServerInfo((const ServerInfo&)(*iter)); if (!svrInfo.isHealthy(poll_primary_server)) { Log::log(logModule, Log::LOG_WARNING, "BaseService::doRequest(): " "Server is unavailable: %s.", svrInfo.getURL().c_str()); continue; } else { Log::log(logModule, Log::LOG_DEBUG, "BaseService::doRequest(): Using server: %s.", iter->getURL().c_str()); } Http::HeaderList headerList, proxyHeaderList; Http::Cookie hostHeader("Host", svrInfo.getHost()); headerList.push_back(hostHeader); if (useProxy) { proxyHeaderList.push_back(hostHeader); // Override (temporarily) server credentials if using proxy svrInfo.setHost(proxyHost); svrInfo.setPort(proxyPort); // We don't use SSL for initial proxy connection svrInfo.setUseSSL(false); Log::log(logModule, Log::LOG_DEBUG, "BaseService::doRequest(): Using proxy: %s:%d", proxyHost.c_str(),proxyPort); // Add Proxy-Authorization header if user defined if (useProxyAuth) { // allocate enough for a base64-encoded digest int authSize = proxyUser.size() + proxyPassword.size() + 1; // 11 extra bytes for prefix and terminator char * digest = (char *)malloc(authSize * 4/3 + 11); strcpy(digest, "Basic "); encode_base64((proxyUser + ":" + proxyPassword).c_str(), authSize,(digest + 6)); Log::log(logModule, Log::LOG_MAX_DEBUG, "BaseService::doRequest(): Using proxy auth as: %s", proxyUser.c_str()); hostHeader = Http::Cookie("Proxy-Authorization", digest); proxyHeaderList.push_back(hostHeader); free(digest); } } // retry to connect to server before marking it as down. // making the number of attempts configurable may have a negative // side effect on performance, if the the value is a high number. int retryAttempts = 3; int retryCount = 0; while(retryCount < retryAttempts) { retryCount++; try { Connection conn(svrInfo, certDBPasswd, (cert_nick_name.size()>0)?cert_nick_name:certNickName, alwaysTrustServerCert); const char *operation = "sending to"; // in case proxy is defined and target URL is HTTPS, // establish an SSL tunnel first send // CONNECT host:port string if (useProxy && iter->useSSL()) { SECStatus secStatus = SECFailure; // All the other parameters would be empty for a // proxy CONNECT Http::CookieList emptyCookieList; BodyChunk emptyChunk; BodyChunkList emptyChunkList; // Add a Keep-alive header since we're using HTTP/1.0 hostHeader = Http::Cookie("Connection", "Keep-Alive\r\n"); proxyHeaderList.push_back(hostHeader); status = sendRequest(conn, BodyChunk(std::string("CONNECT ")), iter->getHost() + ":" + Utils::toString(iter->getPort()), std::string(""), proxyHeaderList, emptyCookieList, emptyChunk, emptyChunk, emptyChunkList); if (status == AM_SUCCESS) { // Retrieve proxie's response if tunnel // established (void) response.readAndIgnore(logModule, conn); // Secure the tunnel now by upgrading the socket PRFileDesc *sock = conn.secureSocket( certDBPasswd, (cert_nick_name.size()>0)? cert_nick_name:certNickName, alwaysTrustServerCert, NULL); if (sock != static_cast<PRFileDesc *>(NULL)) { secStatus = SSL_SetURL(sock, iter->getHost().c_str()); } } if (status != AM_SUCCESS || SECSuccess != secStatus){ Log::log(logModule, Log::LOG_ERROR, "BaseService::doRequest(): could not " "establish a secure proxy tunnel"); // Can't continue and mark server as down as // it was a proxy failure return AM_FAILURE; } } if(Log::isLevelEnabled(logModule, Log::LOG_MAX_DEBUG)) { std::string commString; for(std::size_t i = 0; i<bodyChunkList.size(); ++i) { if(!bodyChunkList[i].secure) { commString.append(bodyChunkList[i].data); } else { commString.append("<secure data>"); } } for(std::size_t commPos = commString.find("%"); commPos != std::string::npos && commPos < commString.size(); commPos = commString.find("%", commPos)) { commString.replace(commPos, 1, "%%"); commPos += 2; } Log::log(logModule, Log::LOG_MAX_DEBUG, commString.c_str()); } std::string requestString = iter->getURI(); /* * In case the following request would go to a proxy * we need to use full URL and special headers. * If the resource is HTTPS, we're not posting our * request to the proxy, but to the server * through proxy tunnel */ if (useProxy && !(iter->useSSL())) { requestString = iter->getURL(); headerList = proxyHeaderList; } status = sendRequest(conn, headerPrefix, requestString, uriParameters, headerList, cookieList, contentLineChunk, headerSuffix, bodyChunkList); if (AM_SUCCESS == status) { operation = "receiving from"; status = response.readAndParse(logModule, conn, initialBufferLen); if (AM_SUCCESS == status) { Log::log(logModule, Log::LOG_MAX_DEBUG, "%.*s", response.getBodyLen(), response.getBodyPtr()); } } if (AM_NSPR_ERROR == status) { PRErrorCode nspr_code = PR_GetError(); Log::log(logModule, Log::LOG_ALWAYS, "BaseService::doRequest() NSPR failure while " "%s %s, error = %s", operation, (*iter).toString().c_str(), PR_ErrorToName(nspr_code)); } if (AM_SUCCESS == status) { if(serverInfo != NULL) *serverInfo = &(*iter); break; } else { if(retryCount < retryAttempts) { continue; } else { Log::log(logModule, Log::LOG_DEBUG, "BaseService::doRequest() Invoking markSeverDown"); svrInfo.markServerDown(poll_primary_server); } } } catch (const NSPRException& exc) { Log::log(logModule, Log::LOG_DEBUG, "BaseService::doRequest() caught %s: %s called by %s " "returned %s", exc.what(), exc.getNsprMethod(), exc.getThrowingMethod(), PR_ErrorToName(exc.getErrorCode())); if(retryCount < retryAttempts) { status = AM_NSPR_ERROR; continue; } else { Log::log(logModule, Log::LOG_DEBUG, "BaseService::doRequest() Invoking markSeverDown"); svrInfo.markServerDown(poll_primary_server); status = AM_NSPR_ERROR; } } } //end of while if (AM_SUCCESS == status) { if(serverInfo != NULL) *serverInfo = &(*iter); break; } if (status = AM_NSPR_ERROR) { continue; } } // end of for } else { status = AM_BUFFER_TOO_SMALL; } return status; }
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 webserver_process(http::Response &response, const http::Request &request) { S();L("Action"); response.setStatusCode(200); response.setBody("<html><body>Hello world!</body></html>"); }
bool PortMapping::UPnP::add(Protocol protocol, uint16_t internal, uint16_t &external) { if(mControlUrl.empty()) return false; if(!external) external = 1024 + Random().readInt() % (49151 - 1024); unsigned duration = 3600; // 1h unsigned attempts = 20; uint32_t gen = 0; for(int i=0; i<attempts; ++i) { Http::Request request(mControlUrl, "POST"); String host; request.headers.get("Host", host); Socket sock(host, seconds(10.)); Address localAddr = sock.getLocalAddress(); String content = "<?xml version=\"1.0\"?>\r\n\ <s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n\ <s:Body>\r\n\ <m:AddPortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\r\n\ <NewRemoteHost></NewRemoteHost>\r\n\ <NewExternalPort>" + String::number(external) + "</NewExternalPort>\r\n\ <NewProtocol>"+(protocol == TCP ? String("TCP") : String("UDP"))+"</NewProtocol>\r\n\ <NewInternalPort>" + String::number(internal) + "</NewInternalPort>\r\n\ <NewInternalClient>"+Html::escape(localAddr.host())+"</NewInternalClient>\r\n\ <NewEnabled>1</NewEnabled>\r\n\ <NewPortMappingDescription>"+Html::escape(String(APPNAME))+"</NewPortMappingDescription>\r\n\ <NewLeaseDuration>"+String::number(duration)+"</NewLeaseDuration>\r\n\ </m:AddPortMapping>\r\n\ </s:Body>\r\n\ </s:Envelope>\r\n"; request.headers["Content-Leng.hpp"] << content.size(); request.headers["Content-Type"] = "text/xml; charset=\"utf-8\""; request.headers["Soapaction"] = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"; request.send(&sock); sock.write(content); Http::Response response; response.recv(&sock); if(response.code == 200) { sock.clear(); return true; } String result; Stream &stream = result; sock.read(stream); String strErrorCode = extract(result, "errorCode"); if(strErrorCode.empty()) { LogWarn("PortMapping::UPnP", String("AddPortMapping: Unknown error")); return false; } int errorCode = 0; strErrorCode.extract(errorCode); if(errorCode == 718) { // The port mapping entry specified conflicts with a object assigned previously to another client if(i == attempts-2) { // The device is probably bogus, and the object is actually assigned to us remove(protocol, internal, external); } else { if(localAddr.isIpv4()) { if(i == 0) gen = localAddr.host().dottedToInt(256) + external; uint32_t rnd = gen = uint32_t(22695477*gen + 1); rnd = rnd >> 17; external = 1024 + rnd; } else { external = 1024 + Random().readInt() % (49151 - 1024); } } continue; } if(duration && errorCode == 725) { // The NAT implementation only supports permanent lease times on port mapping duration = 0; continue; } LogWarn("PortMapping::UPnP", String("AddPortMapping: Error code " + String::number(errorCode))); return false; }
void Connection::write(HTTP::Response &r) { write(r.toString()); }
/** Called whenever new data arrives in the input buffer. Called on the Connection's * thread, which makes it unnecessary to have a lock for the input buffer. */ void Connection::received() { //Try to parse the HTTP request that was received. unsigned int consumed = 0; HTTP::Request *request = HTTP::Request::fromString(inputBuffer, &consumed); if (consumed > 0) { inputBuffer.assign(inputBuffer, consumed, inputBuffer.length() - consumed); } if (!request) return; clog << "processing request" << endl; clog << request->path << endl; if(request->path.at(0) != '/') { clog << "invalid request" << endl; HTTP::Response r; r.statusCode = 404; r.statusText = string("Requested object ") + request->path + " not found."; r.finalize(); write(r); close(); return; } int i,j; for(i = 1; i < request->path.length() && request->path.at(i) != '/'; i++) {} if (i == request->path.length()) { clog << "invalid request" << endl; HTTP::Response r; r.statusCode = 400; r.statusText = string("Requested object ") + request->path + " not found."; r.finalize(); write(r); close(); return; } std::string command = request->path.substr(0,i); clog << command << endl; if (command == "/play") { for(j = i+1; j < request->path.length() && request->path.at(j) != '/'; j++) {} clog << "j= " << j << endl << "length= " << request->path.length() << endl; if (j == request->path.length()) { clog << "invalid request" << endl; HTTP::Response r; r.statusCode = 400; r.statusText = string("Requested object ") + request->path + " not found."; r.finalize(); write(r); close(); return; } std::string host = request->path.substr(i+1,j-(i+1)); std::string uuid = request->path.substr(j+1); clog << "Creating new session.\n"; //create a new session Session * session = player->makeSession(); clog << "Created new session.\n"; session->play(host, uuid); } else if (command == "/stop") { } else { clog << "unable to serve requested object " << request->path << endl; HTTP::Response r; r.statusCode = 404; r.statusText = string("Requested object ") + request->path + " not found."; r.finalize(); write(r); close(); } }