Пример #1
0
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);
}
Пример #2
0
/* 
 * 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;
}
Пример #3
0
/**
 * 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;

}
Пример #4
0
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
}
Пример #5
0
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());
  }
}
Пример #6
0
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);

}
Пример #7
0
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
    }
}
Пример #8
0
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;
}
Пример #9
0
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);
    }
}
Пример #10
0
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;
}
Пример #11
0
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();
}
Пример #12
0
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");
}
Пример #14
0
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;
}
Пример #15
0
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
}
Пример #16
0
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);
  }
}
Пример #17
0
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);
    }
}
Пример #18
0
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;
}
Пример #19
0
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;
}
Пример #20
0
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());
}
Пример #21
0
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());
}
Пример #22
0
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 ());
    }
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
0
  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);
  }
Пример #26
0
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 << "]}";
}
Пример #27
0
 void webserver_process(http::Response &response, const http::Request &request)
 {
     S();L("Action");
     response.setStatusCode(200);
     response.setBody("<html><body>Hello world!</body></html>");
 }
Пример #28
0
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;
	}
Пример #29
0
void Connection::write(HTTP::Response &r)
{
	write(r.toString());
}
Пример #30
0
/** 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();
	}
}