示例#1
0
bool WinHttpStream::enumHeaders( IEnumHeaders &enumHdr )
{
	setState(stReadResponse);

	AutoArray<char> buffer;
	buffer.resize(1000);
	DWORD size = (DWORD)buffer.length();
	while (!HttpQueryInfoA(hHTTPConn,HTTP_QUERY_RAW_HEADERS,
		buffer.data(),&size,0)) {
			DWORD res = GetLastError();
			if (res == ERROR_INSUFFICIENT_BUFFER) {
				buffer.resize(size);
			} else {
				throw ErrNoWithDescException(THISLOCATION,GetLastError(),
					"Cannot retrieve headers from the request");
			}
	}
	buffer.resize(size);

	AutoArray<char>::SplitIterator iter=buffer.split((char)0);
	TextParser<char> parser;
	while (iter.hasItems()) {
		ConstStrA line = iter.getNext();
		if (parser("%1 : %2",line)) {
			ConstStrA field = parser[1].str();
			ConstStrA value = parser[2].str();
			if(enumHdr(field, value)) return true;
		}
	}

	return false;


}
示例#2
0
static void couchLoadData(PrintTextA &print) {
	CouchDB db(getTestCouch());
	db.use(DATABASENAME);


	AutoArray<Document, SmallAlloc<50> > savedDocs;

	Changeset chset(db.createChangeset());
	natural id=10000;
	JSON::Value data = db.json.factory->fromString(strdata);
	for (JSON::Iterator iter = data->getFwIter(); iter.hasItems();) {
		const JSON::KeyValue &kv= iter.getNext();
		Document doc;
		doc.edit(db.json)
				("name",kv[0])
				("age",kv[1])
				("height",kv[2])
				("_id",ToString<natural>(id,16));
		id+=14823;
		savedDocs.add(doc);
		chset.update(doc);
	}
	chset.commit(false);
	Set<StringA> uuidmap;

	for (natural i = 0; i < savedDocs.length(); i++) {
		StringA uuid = savedDocs[i]["_id"]->getStringUtf8();
//		print("%1\n") << uuid;
		uuidmap.insert(uuid);
	}
	print("%1") << uuidmap.size();

}
示例#3
0
	integer ServiceApp::postMessage(ConstStrA command, const Args & args, SeqFileOutput output)
	{

		if (instance->imOwner()) return onMessage(command,args,output);

		AutoArrayStream<char, StaticAlloc<65536> > buffer;
		if (args.length() > 127) return onCommandLineError(args);
		buffer.write((char)(args.length()));
		buffer.copy(command.getFwIter());
		buffer.write(0);
		for(natural i = 0, cnt = args.length();i < cnt;i++){
			buffer.copy(WideToUtf8Reader<ConstStrW::Iterator>(args[i].getFwIter()));
			buffer.write(0);
		}
		AutoArray<byte,SmallAlloc<4096> > replybuff;
		replybuff.resize(instance->getReplyMaxSize());
		natural sz = instance->request(buffer.data(), buffer.length(), replybuff.data(), replybuff.length(), timeout);
		if (sz < sizeof(integer))
			throw ErrorMessageException(THISLOCATION,String("Invalid reply"));
		else {
			integer res = *reinterpret_cast<integer *>(replybuff.data());
			ConstStrA msg(reinterpret_cast<char *>(replybuff.data()+sizeof(integer)),sz - sizeof(integer));
			output.copy(msg.getFwIter());
			return res;
		}
	}
void LinuxNetworkEventListener::workerProc() {

	while (!Thread::canFinish()) {
		try {
			PollBase::Result res;
			PollBase::WaitStatus wt = fdSelect.wait(nil, res);

			if (wt == PollBase::waitWakeUp) {
				while (pumpMessage());
			} else {

				AutoArray<std::pair<ISleepingObject *, natural>,SmallAlloc<32> > tocall;

				SysTime tm  = SysTime::now();
				FdData *listeners = reinterpret_cast<FdData *>(res.userData);
				for (ListenerMap::Iterator iter = listeners->listeners.getFwIter(); iter.hasItems();) {
					const FdListener &l = iter.peek();
					if (res.flags & l.waitMask) {
						tocall.add(std::make_pair(l.notify,res.flags & l.waitMask));
						listeners->listeners.erase(iter);
//						l.notify->wakeUp(con.waitMask & l.waitMask);
					} else if (l.waitTimeout.expired(tm)) {
						tocall.add(std::make_pair(l.notify,0));
						listeners->listeners.erase(iter);
	//					l.notify->wakeUp(0);
					} else {
						iter.skip();
					}
				}
				updateFdData(listeners,res.fd);

				for (natural i = 0; i < tocall.length(); i++) {
					tocall[i].first->wakeUp(tocall[i].second);
				}
			}
		} catch (const Exception &e) {
			AppBase::current().onThreadException(e);
		} catch (const std::exception &e) {
			AppBase::current().onThreadException(StdException(THISLOCATION,e));
		} catch (...) {
			AppBase::current().onThreadException(UnknownException(THISLOCATION));
		}
	}

	fdSelect.cancelAll(CleanUpProc(this));
/*	fdSelect.dropAll();
	while (fdSelect.hasItems()) {
		const LinuxFdSelect::FdInfo &con = fdSelect.getNext();
		FdData *listeners = reinterpret_cast<FdData *>(con.data);
		if (listeners) delete listeners;
		fdSelect.unset(con.fd);
	}
	*/

}
示例#5
0
StringA WinHttpStream::getReplyHeaders()
{
	setState(stReadResponse);
	AutoArray<char> buffer;
	buffer.resize(1000);
	DWORD size = (DWORD)buffer.length();
	while (!HttpQueryInfoA(hHTTPConn,HTTP_QUERY_RAW_HEADERS_CRLF,
		buffer.data(),&size,0)) {
			DWORD res = GetLastError();
			if (res == ERROR_INSUFFICIENT_BUFFER) {
				buffer.resize(size);
			} else {
				throw ErrNoWithDescException(THISLOCATION,GetLastError(),
					"Cannot retrieve headers from the request");
			}
	}
	buffer.resize(size);
	return buffer;
}
示例#6
0
	bool ServiceApp::processRequest(const void *request)
	{
		const char *p = reinterpret_cast<const char*>(request);
		natural count = *p++;
		ConstStrA command(p);
		p += command.length() + 1;
		AutoArray<String,StaticAlloc<256> > params;
		AutoArray<ConstStrW,StaticAlloc<256> > wparams;
		for(natural i = 0;i < count;i++){
			ConstStrA param(p);
			p += param.length() + 1;
			params.add(String(param));
			wparams.add(ConstStrW(params[i]));
		}
		AutoArray<byte> output;
		output.resize(instance->getReplyMaxSize());
		SeqOutputBuffer fakeout(output.data() + sizeof (integer), output.length() - sizeof (integer));
		fakeout.setStaticObj();
		integer res = -1;
		bool stop = false;
		SeqFileOutput out(&fakeout);
		try {
			res = onMessage(command, wparams, out);
			stop = command == ConstStrA(stopCmd);
		}
		catch(std::exception & e){
			TextOut<SeqFileOutput> msg(out);
			msg("%1") << e.what();
			res = -1;
		}
		try {
			*reinterpret_cast<integer*>(output.data()) = res;
			instance->sendReply(output.data(), fakeout.length() + sizeof (integer));
		}
		catch(...){
		}
		return !stop;
	}
示例#7
0
HttpResponse& HttpClient::sendRequestInternal(ConstStrA url, Method method, SeqFileInput data, const HdrItem* headers, bool wo100) {

	//for HTTP/1.0 we need to buffer request (sad)
	if (useHTTP10) {
		//create buffer
		AutoArray<byte> buffer;
		if (data.hasItems()) {
			do {
				natural pos = buffer.length();
				//reserve buffer
				buffer.resize(pos+4096);
				//read buffer
				natural sz = data.blockRead(buffer.data()+pos,4096,true);
				//adjust buffer size
				buffer.resize(pos+sz);
				//continue until end
			} while (data.hasItems());
		}
		//send request
		return sendRequest(url,method,buffer,headers);
	} else {
		//while reading from the stream, we need to ensure, that server is ready to accept our data
		//so in this case, we will use Expect: 100-continue precondition
		try {
			//create request for url
			HttpRequest &rq = createRequest(url,method);
			//we don't need to use 100-continue if connection was recently opened
			if (!connectionReused) wo100 = true;
			//set content length to infinity - this should switch to chunked
			rq.setContentLength(naturalNull);
			//load headers
			feedHeaders(rq, headers);
			//set Expect: 100-continue
			if (!wo100) rq.setHeader(fldExpect,"100-continue");
			//close headers and start body, but we must wait for response now
			rq.beginBody();
			//so create response (do not read headers)
			HttpResponse& resp = createResponse(false);
			//now wait some time to server's response.
			//because it could ignore our header, we must not wait for infinity time
			if (wo100 || nstream->wait(INetworkResource::waitForInput,10000) != INetworkResource::waitTimeout) {
				//data arrived in time - read headers
				resp.readHeaders();
				//there can other response, so if we cannot continue, return response to the caller
				if (!resp.canContinue()) {
					//check status
					if (resp.getStatus() == 417) //we got precondition failed - no worries, we can repeat the request
						//at least we know, that connection is alive
						return sendRequestInternal(url,method,data,headers,true);
					else {
						//other status is send to the caller
						return resp;
					}
				}
			}

			//until now, request could be repeated anytime for network errors
			//- because keep-alive can be closed by the server anytime during request

			//now we should prevent repeating request when network error happened
			//because we starting reading the stream
			connectionReused = false;

			//create a buffer for data
			CArray<byte, 1024> buffer;
			//open request as stream
			SeqFileOutput dout(&rq);
			//use blockcopy to copy data to the request
			dout.blockCopy(data,buffer,naturalNull);
			//close the output
			rq.closeOutput();
			//now wait for response.
			resp.waitAfterContinue(HttpResponse::readHeadersNow);

			//because we could skip waiting on 100-continue above, we need to receive it now
			//and any other such responses
			while (resp.canContinue()) {
				resp.waitAfterContinue(HttpResponse::readHeadersNow);
			}

			//return other response to the caller
			return resp;
		} catch (const NetworkException &e) {
			if (connectionReused) {
				closeConnection();
				return sendRequest(url, method, data, headers);
			} else {
				throw;
			}
		}
	}
}
示例#8
0
void WinHttpStream::initRequest()
{
	TextParser<wchar_t> parser;
	if (!parser(L"%1://%[*-_.a-zA-Z0-9:@]2%%[/](*)*3",url))
		throw FileOpenError(THISLOCATION,ERROR_FILE_NOT_FOUND,url);

	String protocol = parser[1].str();
	String hostident = parser[2].str();
	String::SplitIterator hostidentsplit = hostident.split('@');
	String ident;
	String domain;
	domain = hostidentsplit.getNext();
	while (hostidentsplit.hasItems()) {
		ident = ident + domain + ConstStrW('@');
		domain = hostidentsplit.getNext();
	}
	String path = parser[3].str();
	natural port;
	String username;
	String password;
	bool secure;

	if (parser( L"%1:%u2",domain)) {
		domain = parser[1].str();
		port = parser[2];
		secure = false;
	} else if (protocol == ConstStrW(L"http")) {
		port = INTERNET_DEFAULT_HTTP_PORT;
		secure = false;
	} else if (protocol == ConstStrW(L"https")) {
		port = INTERNET_DEFAULT_HTTPS_PORT;
		secure = true;
	} else
		throw FileOpenError(THISLOCATION,ERROR_NOT_FOUND,url);

	if (!ident.empty()) {
		if (parser(L"%1:%2@",ident))  {
			username = parser[1].str();
			password = parser[2].str();
		} else {
			throw FileMsgException(THISLOCATION,0,url,"Invalid identification field in the url");
		}
	}
	DWORD accessType;
	switch (settings.proxyMode) {
	case pmManual:  accessType = INTERNET_OPEN_TYPE_PROXY;
	case pmDirect:  accessType = INTERNET_OPEN_TYPE_DIRECT;
	case pmAuto:  accessType = INTERNET_OPEN_TYPE_PRECONFIG;
	}

	TextFormatBuff<wchar_t> fmt;

	String proxyName;
	if (accessType == INTERNET_OPEN_TYPE_PROXY) {
		fmt(L"%1:%2") << settings.proxyAddr << settings.proxyPort;
		proxyName = fmt.write();
	}

	if (hInternet) InternetCloseHandle(hInternet);
	hInternet = InternetOpenW(settings.userAgent.cStr(),accessType,proxyName.cStr(),0,0);
	if (hInternet == 0) 
		throw FileMsgException(THISLOCATION,GetLastError(),url,"Cannot initialize WinInet");

	if (hConnect) InternetCloseHandle(hConnect);
	hConnect = InternetConnectW(hInternet,domain.cStr(),(INTERNET_PORT)port,
		username.empty()?0:username.cStr(),
		password.empty()?0:password.cStr(),
		INTERNET_SERVICE_HTTP ,0,0);
	if (hConnect == 0) 
		throw FileMsgException(THISLOCATION,GetLastError(),url,"Cannot connect remote site");
	
	DWORD reqFlags = INTERNET_FLAG_NO_UI |INTERNET_FLAG_HYPERLINK ;
	if (redirDisabled) reqFlags|=INTERNET_FLAG_NO_AUTO_REDIRECT ;
	if (!settings.cookiesEnabled) reqFlags|=INTERNET_FLAG_NO_COOKIES;
	if (secure) reqFlags|=INTERNET_FLAG_SECURE;
	

	hHTTPConn = HttpOpenRequestW(hConnect,String(method).cStr(),path.cStr(),
					0,0,0,reqFlags,0);
	if (hHTTPConn == 0) 
		throw FileMsgException(THISLOCATION,GetLastError(),url,"Cannot connect remote site");
	AutoArray<wchar_t> hdrall;
	for (HeaderMap::Iterator iter = hdrmap.getFwIter(); iter.hasItems();) {

		const HeaderMap::Entity &e = iter.getNext();
		fmt(L"%1: %2\n") << e.key << e.value;
		hdrall.append(fmt.write());
	}	
	if (!hdrall.empty() &&
		!HttpAddRequestHeadersW(hHTTPConn,hdrall.data(),(DWORD)hdrall.length(),HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDREQ_FLAG_ADD))
		throw FileMsgException(THISLOCATION,GetLastError(),url,"AddRequest failed");
	
	if (!HttpSendRequestW(hHTTPConn,0,0,postBuffer.data(),(DWORD)postBuffer.length())) {
		bool stillError = true;
		DWORD dwError = GetLastError();	
		if (dwError == ERROR_INTERNET_INVALID_CA && settings.allowUntrustedCert) {
			DWORD dwFlags;
			DWORD dwBuffLen = sizeof(dwFlags);

			InternetQueryOption (hHTTPConn, INTERNET_OPTION_SECURITY_FLAGS,
				(LPVOID)&dwFlags, &dwBuffLen);

			dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
			InternetSetOption (hHTTPConn, INTERNET_OPTION_SECURITY_FLAGS,
				&dwFlags, sizeof (dwFlags) );
			if (HttpSendRequestW(hHTTPConn,0,0,postBuffer.data(),(DWORD)postBuffer.length()))
				stillError = false;			
		}
		if (stillError)
			throw FileMsgException(THISLOCATION,GetLastError(),url,"Failed to SendRequest");
	}
	postBuffer.clear();
}