Пример #1
0
	long ClientWriter::put_request_headers(RequestHeaders request_headers){
		PROFILE_ME;

		StreamBuffer data;

		data.put(get_string_from_verb(request_headers.verb));
		data.put(' ');
		data.put(request_headers.uri);
		if(!request_headers.get_params.empty()){
			data.put('?');
			data.put(url_encoded_from_optional_map(request_headers.get_params));
		}
		char temp[64];
		const unsigned ver_major = request_headers.version / 10000, ver_minor = request_headers.version % 10000;
		unsigned len = (unsigned)std::sprintf(temp, " HTTP/%u.%u\r\n", ver_major, ver_minor);
		data.put(temp, len);

		AUTO_REF(headers, request_headers.headers);
		for(AUTO(it, headers.begin()); it != headers.end(); ++it){
			data.put(it->first.get());
			data.put(": ");
			data.put(it->second);
			data.put("\r\n");
		}
		data.put("\r\n");

		return on_encoded_data_avail(STD_MOVE(data));
	}
Пример #2
0
void TestPV::post(const pvd::BitSet& changed, bool notify)
{
    testDiag("post %s %d changed '%s'", name.c_str(), (int)notify, toString(changed).c_str());
    Guard G(provider->lock);

    channels_t::vector_type toupdate(channels.lock_vector());

    FOREACH(it, end, toupdate) // channel
    {
        TestPVChannel *chan = it->get();

        TestPVChannel::monitors_t::vector_type tomon(chan->monitors.lock_vector());
        FOREACH(it2, end2, tomon) // monitor/subscription
        {
            TestPVMonitor *mon = it2->get();

            if(!mon->running)
                continue;

            mon->overflow->pvStructurePtr->copyUnchecked(*value, changed);

            if(mon->free.empty()) {
                mon->inoverflow = true;
                mon->overflow->overrunBitSet->or_and(*mon->overflow->changedBitSet, changed); // oflow = prev_changed & new_changed
                *mon->overflow->changedBitSet |= changed;
                testDiag("overflow changed '%s' overrun '%s'",
                         toString(*mon->overflow->changedBitSet).c_str(),
                         toString(*mon->overflow->overrunBitSet).c_str());

            } else {
                assert(!mon->inoverflow);

                if(mon->buffer.empty())
                    mon->needWakeup = true;

                AUTO_REF(elem, mon->free.front());
                // Note: can't use 'changed' to optimize this copy since we don't know
                //       the state of the free element
                elem->pvStructurePtr->copyUnchecked(*mon->overflow->pvStructurePtr);
                *elem->changedBitSet = changed;
                elem->overrunBitSet->clear(); // redundant/paranoia

                mon->buffer.push_back(elem);
                mon->free.pop_front();
                testDiag("push %p changed '%s' overflow '%s'", elem.get(),
                         toString(*elem->changedBitSet).c_str(),
                         toString(*elem->overrunBitSet).c_str());
            }

            if(mon->needWakeup && notify) {
                testDiag(" wakeup");
                mon->needWakeup = false;
                UnGuard U(G);
                mon->requester->monitorEvent(*it2);
            }
        }
Пример #3
0
std::vector<EpollDaemon::SnapshotElement> EpollDaemon::snapshot(){
	std::vector<boost::shared_ptr<TcpSessionBase> > sessions;
	g_epoll->snapshot(sessions);

	std::vector<SnapshotElement> ret;
	const AUTO(now, getFastMonoClock());
	for(AUTO(it, sessions.begin()); it != sessions.end(); ++it){
		ret.push_back(SnapshotElement());
		AUTO_REF(item, ret.back());
		item.remote = (*it)->getRemoteInfo();
		item.local = (*it)->getLocalInfo();
		item.msOnline = now - (*it)->getCreatedTime();
	}
	return ret;
}
Пример #4
0
	long ClientWriter::put_chunked_header(RequestHeaders request_headers){
		PROFILE_ME;

		StreamBuffer data;

		data.put(get_string_from_verb(request_headers.verb));
		data.put(' ');
		data.put(request_headers.uri);
		if(!request_headers.get_params.empty()){
			data.put('?');
			data.put(url_encoded_from_optional_map(request_headers.get_params));
		}
		char temp[64];
		const unsigned ver_major = request_headers.version / 10000, ver_minor = request_headers.version % 10000;
		unsigned len = (unsigned)std::sprintf(temp, " HTTP/%u.%u\r\n", ver_major, ver_minor);
		data.put(temp, len);

		AUTO_REF(headers, request_headers.headers);
		if(!headers.has("Content-Type")){
			headers.set(sslit("Content-Type"), "application/x-www-form-urlencoded; charset=utf-8");
		}

		AUTO(transfer_encoding, headers.get("Transfer-Encoding"));
		AUTO(pos, transfer_encoding.find(';'));
		if(pos != std::string::npos){
			transfer_encoding.erase(pos);
		}
		transfer_encoding = to_lower_case(trim(STD_MOVE(transfer_encoding)));

		if(transfer_encoding.empty() || (transfer_encoding == STR_IDENTITY)){
			headers.set(sslit("Transfer-Encoding"), STR_CHUNKED);
		} else {
			headers.set(sslit("Transfer-Encoding"), STD_MOVE(transfer_encoding));
		}

		for(AUTO(it, headers.begin()); it != headers.end(); ++it){
			data.put(it->first.get());
			data.put(": ");
			data.put(it->second);
			data.put("\r\n");
		}
		data.put("\r\n");

		return on_encoded_data_avail(STD_MOVE(data));
	}
Пример #5
0
	long ClientWriter::put_request(RequestHeaders request_headers, StreamBuffer entity){
		PROFILE_ME;

		StreamBuffer data;

		data.put(get_string_from_verb(request_headers.verb));
		data.put(' ');
		data.put(request_headers.uri);
		if(!request_headers.get_params.empty()){
			data.put('?');
			data.put(url_encoded_from_optional_map(request_headers.get_params));
		}
		char temp[64];
		const unsigned ver_major = request_headers.version / 10000, ver_minor = request_headers.version % 10000;
		unsigned len = (unsigned)std::sprintf(temp, " HTTP/%u.%u\r\n", ver_major, ver_minor);
		data.put(temp, len);

		AUTO_REF(headers, request_headers.headers);
		if(entity.empty()){
			headers.erase("Content-Type");
			headers.erase("Transfer-Encoding");

			if((request_headers.verb == V_POST) || (request_headers.verb == V_PUT)){
				headers.set(sslit("Content-Length"), STR_0);
			} else {
				headers.erase("Content-Length");
			}
		} else {
			if(!headers.has("Content-Type")){
				headers.set(sslit("Content-Type"), "application/x-www-form-urlencoded; charset=utf-8");
			}

			AUTO(transfer_encoding, headers.get("Transfer-Encoding"));
			AUTO(pos, transfer_encoding.find(';'));
			if(pos != std::string::npos){
				transfer_encoding.erase(pos);
			}
			transfer_encoding = to_lower_case(trim(STD_MOVE(transfer_encoding)));

			if(transfer_encoding.empty() || (transfer_encoding == STR_IDENTITY)){
				headers.set(sslit("Content-Length"), boost::lexical_cast<std::string>(entity.size()));
			} else {
				// 只有一个 chunk。
				StreamBuffer chunk;
				len = (unsigned)std::sprintf(temp, "%llx\r\n", (unsigned long long)entity.size());
				chunk.put(temp, len);
				chunk.splice(entity);
				chunk.put("\r\n0\r\n\r\n");
				entity.swap(chunk);
			}
		}
		for(AUTO(it, headers.begin()); it != headers.end(); ++it){
			data.put(it->first.get());
			data.put(": ");
			data.put(it->second);
			data.put("\r\n");
		}
		data.put("\r\n");

		data.splice(entity);

		return on_encoded_data_avail(STD_MOVE(data));
	}
Пример #6
0
void CsvParser::load(const char *file){
	LOG_POSEIDON_DEBUG("Loading CSV file: ", file);

	StreamBuffer buffer;
	fileGetContents(buffer, file);
	buffer.put('\n');

	std::vector<OptionalMap> data;

	std::vector<std::vector<std::string> > rows;
	{
		std::vector<std::string> row;
		std::string token;
		bool first = true;
		bool inQuote = false;
		do {
			char ch = buffer.get();
			if(ch == '\r'){
				if(buffer.peek() == '\n'){
					buffer.get();
				}
				ch = '\n';
			}

			if(first){
				first = false;

				if(ch == '\"'){
					inQuote = true;
					continue;
				}
			}

			if(ch == '\"'){
				if(inQuote){
					if(buffer.peek() == '\"'){
						buffer.get();
						token.push_back('\"');
					} else {
						inQuote = false;
					}
					continue;
				}
			}

			if(!inQuote){
				if((ch == ',') || (ch == '\n')){
					std::string trimmed;
					const std::size_t begin = token.find_first_not_of(" \t\r\n");
					if(begin != std::string::npos){
						const std::size_t end = token.find_last_not_of(" \t\r\n") + 1;
						trimmed = token.substr(begin, end - begin);
					}
					row.push_back(STD_MOVE(trimmed));
					token.clear();
					first = true;

					if(ch == '\n'){
						rows.push_back(STD_MOVE(row));
						row.clear();
					}
					continue;
				}
			}

			token.push_back(ch);
		} while(!buffer.empty());
	}
	if(rows.empty() || rows.front().empty()){
		LOG_POSEIDON_ERROR("The first line of a CSV file may not be empty.");
		DEBUG_THROW(Exception, sslit("Bad CSV header"));
	}

	const std::size_t columnCount = rows.front().size();
	std::vector<SharedNts> keys(columnCount);
	for(std::size_t i = 0; i < columnCount; ++i){
		AUTO_REF(key, rows.front().at(i));
		for(std::size_t j = 0; j < i; ++j){
			if(keys.at(j) == key){
				LOG_POSEIDON_ERROR("Duplicate key: ", key);
				DEBUG_THROW(Exception, sslit("Duplicate key"));
			}
		}
		keys.at(i).assign(key.c_str());
	}
	for(std::size_t i = 1; i < rows.size(); ++i){
		rows.at(i - 1).swap(rows.at(i));
	}
	rows.pop_back();

	{
		std::size_t line = 1;
		std::size_t i = 0;
		while(i < rows.size()){
			AUTO_REF(row, rows.at(i));
			++line;
			if((row.size() == 1) && row.front().empty()){
				for(std::size_t j = i + 1; j < rows.size(); ++j){
					rows.at(j - 1).swap(rows.at(j));
				}
				rows.pop_back();
				continue;
			}
			if(row.size() != columnCount){
				LOG_POSEIDON_ERROR("There are ", row.size(), " column(s) on line ", line,
					" but there are ", columnCount, " in the header");
				DEBUG_THROW(Exception, sslit("Inconsistent CSV column numbers"));
			}
			++i;
		}
	}

	const std::size_t rowCount = rows.size();
	data.resize(rowCount);
	for(std::size_t i = 0; i < rowCount; ++i){
		AUTO_REF(row, rows.at(i));
		AUTO_REF(map, data.at(i));
		for(std::size_t j = 0; j < columnCount; ++j){
			map.create(keys.at(j))->second.swap(row.at(j));
		}
	}

	LOG_POSEIDON_DEBUG("Done loading CSV file: ", file);
	m_data.swap(data);
	m_row = static_cast<std::size_t>(-1);
}