Exemplo n.º 1
0
pplx::task<http_response> client::http_client::request(http_request request, pplx::cancellation_token token)
{
    if(!request.headers().has(header_names::user_agent))
    {
        request.headers().add(header_names::user_agent, USERAGENT);
    }

    request._set_base_uri(base_uri());
    request._set_cancellation_token(token);
    return m_pipeline->propagate(request);
}
void MetaCDNReceiver::handle_delete(http_request message) {
	/*
	Use cases:
	1. when CDN deletes a file from itself to store some other file because of its limited capacity

	JSON Format
	Request
	{
		"FileName": "a.txt",
		"CdnId" : 2
	}

	Response: status OK or Forbidden (no json object included)
	*/
	try {
		int result;
		if(message.headers().content_type()==U("application/json")) {
			cout << endl << "---------------"<< endl;
			cout << message.to_string() << endl <<endl;

			json::value jsonObj = message.extract_json().get();
			int cdnId = jsonObj.at(U("CdnId")).as_integer();
			string fileName = utility::conversions::to_utf8string(jsonObj.at(U("FileName")).as_string());
			result = m_meta->deleteCdnFromMetaEntry(fileName, cdnId);
			message.reply(status_codes::OK, result==0? U("Deleted successfully") : U("Delete failed"));
		} else {
			message.reply(status_codes::Forbidden, U("Json object is required"));
		}
	} catch(json::json_exception &e) {
		message.reply(status_codes::Forbidden, U("Invalid json object"));
		return;
	}
}
void MetaCDNReceiver::handle_register(http_request message) {
	/*
	-when a new CDN joins, it has to register itself to Meta Server

	JSON Format
	Request
	{
		"Type": 0, //0=for cdn, 1=for fss
		"IP": "1.1.1.1:4000", //the sender CDN's IP address + port(listening to incoming requests)
		"Lat": 23.00, //the sender CDN's location
		"Lng": 148.12
	}
	Response
	{
		"CdnId": 1 //the assigned id for the cdn
	}

	*/
	try {

		int assignedId = -1;
		if(message.headers().content_type()==U("application/json")) {
			cout << endl << "---------------"<< endl;
			cout << message.to_string() << endl <<endl;

			json::value jsonObj = message.extract_json().get();
			if(jsonObj.at(U("Type")).as_integer() == 0) {
				string ipAddr = utility::conversions::to_utf8string(jsonObj.at(U("IP")).as_string());
				//TODO: validate ip address
				Address cdnAddr(make_pair(jsonObj.at(U("Lat")).as_double(), jsonObj.at(U("Lng")).as_double()), ipAddr);
				assignedId = m_meta->registerCdn(cdnAddr);
				json::value respFinal = json::value::object();
				respFinal[U("CdnId")] = json::value::number(assignedId);
				message.reply(assignedId!=-1? status_codes::OK : status_codes::NotFound, respFinal);
			} else if(jsonObj.at(U("Type")).as_integer() == 1){
				string ipAddr = utility::conversions::to_utf8string(jsonObj.at(U("IP")).as_string());
				//TODO: validate ip address
				Address fssAddr(make_pair(jsonObj.at(U("Lat")).as_double(), jsonObj.at(U("Lng")).as_double()), ipAddr);
				m_meta->setFssAddr(fssAddr);
				message.reply(status_codes::OK, "FSS registration complete");
			} else {
				message.reply(status_codes::Forbidden, U("Invalid type"));
			}
		} else {
			message.reply(status_codes::Forbidden, U("Json object is required"));
		}
	} catch(json::json_exception &e) {
		message.reply(status_codes::Forbidden, U("Invalid json object"));
		return;
	}
}
Exemplo n.º 4
0
boost::tribool request_parser::parse_line(http_request &request, const std::string &line)
{
	if (line.empty() || line[line.size() - 1] != '\r')
		return false;

	const bool is_empty_line = line.compare(0, line.size(), "\r", 1) == 0;

	switch (m_state_new) {
		case request_line: {
			if (is_empty_line) {
				// Ignore CRLF characters between requests in Keep-Alive connection
				return boost::indeterminate;
			}

			const auto first_space = line.find(' ');
			if (first_space == std::string::npos)
				return false;

			request.set_method(line.substr(0, first_space));

			const auto second_space = line.find(' ', first_space + 1);
			if (second_space == std::string::npos)
				return false;

			request.set_url(line.substr(first_space + 1, second_space - first_space - 1));

			if (line.compare(second_space + 1, 5, "HTTP/", 5) != 0)
				return false;

			const auto version_major_start = second_space + 1 + 5;
			const auto dot = line.find('.', version_major_start);
			if (dot == std::string::npos)
				return false;

			const auto version_minor_end = line.find('\r', dot);

			if (version_minor_end == std::string::npos)
				return false;

			boost::tribool result = boost::indeterminate;
			const auto major_version = parse_int(line.data() + version_major_start, line.data() + dot, result);
			const auto minor_version = parse_int(line.data() + dot + 1, line.data() + version_minor_end, result);
			request.set_http_version(major_version, minor_version);

			m_state_new = header_line;
			return result;
		}
		case header_line: {
			if (!m_header.first.empty() && (line[0] == ' ' || line[0] == '\t')) {
				// any number of LWS is allowed after field, rfc 2068
				auto begin = line.begin() + 1;
				auto end = line.end();
				trim_line(begin, end);

				m_header.second += ' ';
				m_header.second.append(begin, end);

				return boost::indeterminate;
			}

			if (!m_header.first.empty()) {
				request.headers().add(m_header);
				m_header.first.resize(0);
				m_header.second.resize(0);
			}

			if (is_empty_line) {
				return true;
			}

			const auto colon = line.find(':');
			if (colon == std::string::npos)
				return false;

			auto name_begin = line.begin();
			auto name_end = line.begin() + colon;
			trim_line(name_begin, name_end);
			m_header.first.assign(name_begin, name_end);

			auto value_begin = line.begin() + colon + 1;
			auto value_end = line.end();
			trim_line(value_begin, value_end);
			m_header.second.assign(value_begin, value_end);

			return boost::indeterminate;
		}
	}

	return false;
}
void MetaCDNReceiver::handle_update(http_request message) {
	/*
	Use cases:
	0. when CDN pulls a file from FSS (syncdown flow)
	1. when CDN updates an existing file (syncup flow; need invalidation process)
	2. when CDN creates a new file and stores in FSS and itself

	JSON Format
	Request
	{
		"Type": 0, // 0=CDN pulls a file from FSS, 1=CDN updates a file (+invalidation process), 2=CDN creates a new file and stores in FSS
		"FileName": "a.txt",
		"FileHash": "ahash", //could be empty string when Type=0 //only for type 1,2
		"CdnId": 1
		"TimeStamp": "12312312312" //REQUIRED for use case 1 and 2
	}

	Response: status OK or Forbidden (no json object included)
	*/

	try {
		if(message.headers().content_type()==U("application/json")) {
			cout << endl << "---------------"<< endl;
			cout << message.to_string() << endl <<endl;

			json::value jsonObj = message.extract_json().get();
			int cdnId = jsonObj.at(U("CdnId")).as_integer();
			string fileName = utility::conversions::to_utf8string(jsonObj.at(U("FileName")).as_string());
			
			int result;
			if(jsonObj.at(U("Type")).as_integer() == 0) {
				result = m_meta->addCdnToMetaEntry(fileName, cdnId);
			} else if(jsonObj.at(U("Type")).as_integer() == 1) {
				string fileHash = utility::conversions::to_utf8string(jsonObj.at(U("FileHash")).as_string());
				vector<int> newCdnList;
				newCdnList.push_back(cdnId);
				result = m_meta->updateMetaEntry(fileName, fileHash, newCdnList);
				if(result == 0) {
					result = m_meta->updateTimeStamp(fileName, jsonObj.at(U("TimeStamp")).as_string());
				} else {
					cout<<"MetaCDNReceiver::handle_update() - failed to update meta entry"<<endl;
					return;
				}

				//now, send invalidation msgs to other cdns
				unordered_map<int, Address>::const_iterator itr = m_meta->getCdnIdToAddrMap().begin();
				while(itr != m_meta->getCdnIdToAddrMap().end()) {
					if(itr->first == cdnId) {
						++itr;
						continue;
					}
					http_client cdn_client = http_client("http://" + itr->second.ipAddr);
					http_response resp = cdn_client.request(methods::DEL, "cdn/cache"+fileName).get();
					if (resp.status_code() != status_codes::OK) {
						cout<<"MetaCDNReceiver::handle_update() - failed to send invalidation message to "+itr->second.ipAddr<<endl;
					}
					++itr;
				}

			} else if(jsonObj.at(U("Type")).as_integer() == 2) {
				string fileHash = utility::conversions::to_utf8string(jsonObj.at(U("FileHash")).as_string());
				vector<int> newCdnList;
				newCdnList.push_back(cdnId);
				result = m_meta->addNewMetaEntry(fileName, fileHash, newCdnList);
				if(result == 0)
					result = m_meta->addNewTimeStamp(fileName, jsonObj.at(U("TimeStamp")).as_string());
			} else {
				message.reply(status_codes::Forbidden, U("Undefined Type"));
				return;
			}
			message.reply(result==0? status_codes::OK : status_codes::NotFound, result==0? U("Updated successfully") : U("Update failed"));

		} else {
			message.reply(status_codes::Forbidden, U("Json object is required"));
		}
	} catch(json::json_exception &e) {
		message.reply(status_codes::Forbidden, U("Invalid json object"));
		return;
	}
}
Exemplo n.º 6
0
    // Handler to process HTTP::GET requests.
    // Replies to the request with data.
    void odata_test_service::handle_get(http_request message)
    {
        try
        {
            bool is_async = false;
            auto prefer_header = message.headers().find(U("Prefer"));
            if (prefer_header != message.headers().end())
            {
                if (prefer_header->second.find(U("respond-async")) != ::odata::utility::string_t::npos)
                {
                    is_async = true;
                }
            }


            auto parsed_uri = m_uri_parser->parse_uri(message.relative_uri());

            odata_message_writer writer(m_model, m_service_root);
            odata_context_url_builder context_url_builder(m_model, m_service_root);
            odata_metadata_builder metadata_builder(m_model, m_service_root);
            ::odata::utility::string_t content;
            if (parsed_uri->is_service_document())
            {
                // Write service document
                content = writer.write_service_document(m_service_document);
            }
            else if (parsed_uri->is_metadata_document())
            {
                // Write metadata document
                content = writer.write_metadata_document();
            }
            else
            {
                if (parsed_uri->path()->size() >= 1)
                {
                    if (parsed_uri->path()->segment_at(0)->segment_type() == odata_path_segment_type::EntitySet)
                    {
                        auto entity_set_segment = parsed_uri->path()->segment_at(0)->as<odata_entity_set_segment>();
                        if (entity_set_segment->entity_set()->get_name() == U("People"))
                        {
                            if (parsed_uri->path()->size() == 1)
                            {
                                auto people = get_people();
                                auto context_url = context_url_builder.get_context_uri_for_collection_of_entities(entity_set_segment->entity_set());
                                people->set_context_url(context_url);
                   
                                if (is_async)
                                {
                                    std::unordered_map<string_t, string_t> headers;
                                    headers[U("OData-Version")] = U("4.0");
                                    headers[U("Content-Type")] = U("application/json;odata.metadata=full");

                                    content = writer.write_asynchronous_odata_value(people, 200, U("OK"), headers);
                                }
                                else
                                {
                                    content = writer.write_odata_value(people);
                                }
                            }
                            else if (parsed_uri->path()->segment_at(1)->segment_type() == odata_path_segment_type::Key)
                            {
                                auto key_segment = parsed_uri->path()->segment_at(1)->as<odata_key_segment>();
                                auto key = key_segment->keys()[0].second->as<::odata::utility::string_t>();

                                auto single_person = get_single_people(key);
                                single_person->set_is_top_level(true);
                                auto context_url = context_url_builder.get_context_uri_for_entity(entity_set_segment->entity_set());
                                single_person->set_context_url(context_url);
                                
                                auto id = metadata_builder.get_entity_id(single_person, entity_set_segment->entity_set());
                                single_person->set_id(id);

                                auto read_link = metadata_builder.get_read_link(single_person, entity_set_segment->entity_set());
                                single_person->set_read_link(read_link);

                                auto edit_link = metadata_builder.get_edit_link(single_person, entity_set_segment->entity_set());
                                single_person->set_edit_link(edit_link);



                                content = writer.write_odata_value(single_person);
                            }
                        }
                    }
                }
            }

            message.reply(status_codes::OK, content).then(std::bind(&handle_error, std::placeholders::_1));
        }
        catch (::odata::core::odata_exception &e)
        {
            message.reply(status_codes::BadRequest, U("Exception: ") + e.what()).then(std::bind(&handle_error, std::placeholders::_1));
        }
        ////Get odata objects from resorce and odata_path
        //

    }
Exemplo n.º 7
0
void
RestEngineUri::handle_post(http_request request)
{
    std::cout << request.method() << " : " << request.absolute_uri().path() << std::endl;
    std::cout << request.method() << " : " << request.headers()["Cookie"] << std::endl;
    int rc = 0;
    std::string resultstr;
    std::pair<bool, std::string> result {true, std::string()};

    std::string cookie = request.headers()["Cookie"];

    if (cookie != "session_cookie=" +  _active_session_token)
    {
        //http_response response(status_codes::Locked);
        //make_response(response, resultstr, result);
        //request.reply(response);
        //return;
    }

    if (!is_session_owner(request))
    {
        send_busy_response(request);
        return;
    }

    ostringstream o;
    o << "COOKIE:" << cookie << std::endl;
    o << "ACTIVE COOKIE:" << _active_session_token << std::endl;
    std::cout << o.str();
    log (m_s.masterlogfile,o.str());

    char json[1024];

    // extract json from request
    snprintf(json, sizeof(json), "%s", request.extract_string(true).get().c_str());
    std::cout << "JSON:\n" << json << std::endl;

    rapidjson::Document document;
    if (document.Parse(json).HasParseError())
    {
        rc = 1;
        resultstr += "document invalid";
    }

    rapidjson::SchemaValidator validator(*_schema);
    if (!document.Accept(validator)) {
        rc = 1;
        resultstr += get_schema_validation_error(&validator);
    }

    std::string select_str;
    std::string hosts_list;

    const Value& hosts = document["hosts"];
    json_to_host_list(hosts, hosts_list);

    const Value& select = document["select"];
    json_to_select_str(select, select_str);

    // Execute Ivy Engine command
    if (rc == 0)
    {
        std::unique_lock<std::mutex> u_lk(goStatementMutex);

        std::string outputfolder = m_s.get("output_folder_root").second;
        std::string testname = m_s.get("test_name").second;

        result = m_s.startup(outputfolder, testname, m_s.ivyscript_filename, hosts_list, select_str);
    }

    http_response response(status_codes::OK);
    make_response(response, resultstr, result);
    request.reply(response);
}