예제 #1
0
std::string ZLCurlNetworkManager::perform(const ZLExecutionData::Vector &dataList) const {
	const ZLResource &errorResource = ZLResource::resource("dialog")["networkError"];

	if (dataList.empty()) {
		return errorResource["emptyLibrariesList"].value();
	}

	std::set<std::string> errors;

	const std::string proxy = proxyHost() + ':' + proxyPort();
	CURLM *handle = curl_multi_init();

	std::map<CURL*,shared_ptr<ZLExecutionData> > handleToRequest;

	for (ZLExecutionData::Vector::const_iterator it = dataList.begin(); it != dataList.end(); ++it) {
		if (it->isNull() || !(*it)->isInstanceOf(ZLNetworkRequest::TYPE_ID)) {
			continue;
		}
		ZLNetworkRequest &request = (ZLNetworkRequest&)**it;
		const std::string err = doBeforeRequest(request);
		if (!err.empty()) {
			errors.insert(err);
			continue;
		}
		CURL *easyHandle = curl_easy_init();
		if (easyHandle != 0) {
			handleToRequest[easyHandle] = *it;
			setStandardOptions(easyHandle, proxy);
			setRequestOptions(easyHandle, request);
			curl_multi_add_handle(handle, easyHandle);
		}
	}

	int counter;
	CURLMcode res;
	do {
		res = curl_multi_perform(handle, &counter);
	} while ((res == CURLM_CALL_MULTI_PERFORM) || (counter > 0));

	CURLMsg *message;
	do {
		int queueSize;
		message = curl_multi_info_read(handle, &queueSize);
		if ((message != 0) && (message->msg == CURLMSG_DONE)) {
			ZLNetworkRequest &request = (ZLNetworkRequest&)*handleToRequest[message->easy_handle];
			const std::string &url = request.url();

			CURLcode result = message->data.result;
			bool doAfterResult = request.doAfter(result == CURLE_OK);
			if (result == CURLE_OK && !doAfterResult) {
				result = CURLE_WRITE_ERROR;
			}

			switch (result) {
				case CURLE_OK:
					break;
				case CURLE_WRITE_ERROR:
					if (!request.errorMessage().empty()) {
						errors.insert(request.errorMessage());
					} else {
						errors.insert(ZLStringUtil::printf(errorResource["somethingWrongMessage"].value(), ZLNetworkUtil::hostFromUrl(url)));
					}
					break;
				default:
					errors.insert(ZLStringUtil::printf(errorResource["somethingWrongMessage"].value(), ZLNetworkUtil::hostFromUrl(url)));
					break;
				case CURLE_COULDNT_RESOLVE_PROXY:
					errors.insert(ZLStringUtil::printf(errorResource["couldntResolveProxyMessage"].value(), proxyHost()));
					break;
				case CURLE_COULDNT_RESOLVE_HOST:
					errors.insert(ZLStringUtil::printf(errorResource["couldntResolveHostMessage"].value(), ZLNetworkUtil::hostFromUrl(url)));
					break;
				case CURLE_COULDNT_CONNECT:
					errors.insert(ZLStringUtil::printf(errorResource["couldntConnectMessage"].value(), ZLNetworkUtil::hostFromUrl(url)));
					break;
				case CURLE_OPERATION_TIMEDOUT:
					errors.insert(errorResource["operationTimedOutMessage"].value());
					break;
				case CURLE_SSL_CONNECT_ERROR:
					errors.insert(ZLStringUtil::printf(errorResource["sslConnectErrorMessage"].value(), curl_easy_strerror(CURLE_SSL_CONNECT_ERROR)));
					break;
#if LIBCURL_VERSION_NUM > 0x071100
				case CURLE_PEER_FAILED_VERIFICATION:
#else
				case CURLE_SSL_PEER_CERTIFICATE:
#endif
					errors.insert(ZLStringUtil::printf(errorResource["peerFailedVerificationMessage"].value(), ZLNetworkUtil::hostFromUrl(url)));
					break;
				case CURLE_SSL_CACERT:
					errors.insert(ZLStringUtil::printf(errorResource["sslCertificateAuthorityMessage"].value(), ZLNetworkUtil::hostFromUrl(url)));
					break;
				case CURLE_SSL_CACERT_BADFILE:
					errors.insert(ZLStringUtil::printf(errorResource["sslBadCertificateFileMessage"].value(), request.sslCertificate().Path));
					break;
				case CURLE_SSL_SHUTDOWN_FAILED:
					errors.insert(ZLStringUtil::printf(errorResource["sslShutdownFailedMessage"].value(), ZLNetworkUtil::hostFromUrl(url)));
					break;
			}
		}
	} while ((message != 0) && (errors.size() < 3));

	for (std::map<CURL*,shared_ptr<ZLExecutionData> >::const_iterator jt = handleToRequest.begin(); jt != handleToRequest.end(); ++jt) {
		CURL *easyHandle = jt->first;
		curl_multi_remove_handle(handle, easyHandle);
		curl_easy_cleanup(easyHandle);

		ZLNetworkRequest &request = (ZLNetworkRequest&)*jt->second;
		clearRequestOptions(request);
	}
	handleToRequest.clear();
	curl_multi_cleanup(handle);

	std::string result;
	for (std::set<std::string>::const_iterator et = errors.begin(); et != errors.end(); ++et) {
		if (!result.empty()) {
			result += '\n';
		}
		result += *et;
	}
	return result;
}
/*
QNetworkCookieJar *ZLQtNetworkManager::cookieJar() const {
	return myCookieJar;
}

QNetworkProxy ZLQtNetworkManager::proxy() const {
	if (useProxy()) {
		const QString proxyHost = QString::fromStdString(ZLNetworkManager::proxyHost());
		const int proxyPort = atoi(ZLNetworkManager::proxyPort().c_str());
		return QNetworkProxy(QNetworkProxy::HttpProxy, proxyHost, proxyPort);
	}
	return QNetworkProxy(QNetworkProxy::DefaultProxy);
}
*/
std::string ZLbadaNetworkManager::perform(const ZLExecutionData::Vector &dataList) const {
	AppLog("ZLbadaNetworkManager::perform");
	result r = E_SUCCESS;
	std::set<std::string> errors;
	std::set<HttpThread*> httpTreads;

	HttpMonitor* myMonitor = new HttpMonitor;
	myMonitor->Construct();

    int ThreadCounter = 0;

	for (ZLExecutionData::Vector::const_iterator it = dataList.begin(); it != dataList.end(); ++it) {
		if (it->isNull() || !(*it)->isInstanceOf(ZLNetworkRequest::TYPE_ID)) {continue;}

		ZLNetworkRequest &request = (ZLNetworkRequest&)**it;
		AppLog("###### request.url() = %s", request.url().c_str());
		HttpThread* httpTread = new HttpThread(myMonitor, request);
		httpTreads.insert(httpTread);
		if (!request.doBefore()) {
			//if (!request.hasListener())
			{
				std::string error = request.errorMessage();
				if (error.empty()) {
					const ZLResource &errorResource = ZLResource::resource("dialog")["networkError"];
					error = ZLStringUtil::printf(errorResource["somethingWrongMessage"].value(),
												  request.url().c_str());
												 //networkRequest.url().host().toStdString());
				}
				errors.insert(error);
			}
			continue;
		}
		std::string error;
		AppLog("new HttpThread");
		r = httpTread->Construct();
		if (r == E_SUCCESS) AppLog("Construct E_SUCCESS");
		AppLog("Construct");
		myMonitor->Enter();
		AppLog("myMonitor Enter");
		if (myMonitor->count > 5) {
			    AppLog("myMonitor count>5");
				myMonitor->Wait();
				AppLog("Wait %d",myMonitor->count);
				}
		myMonitor->Exit();
		AppLog("myMonitor Exit");
		if (httpTread->Start() == E_SUCCESS) AppLog("Start E_SUCCESS");
		//httpTread->initRequest();
		//if (__pHttpThread->OnStart()) AppLog("Start true");
		AppLog("Start");


		/*
		qDebug("Do request to %s", qPrintable(networkRequest.url().toString()));
		
		networkRequest.setRawHeader("User-Agent", userAgent().c_str());
		QSslConfiguration configuration;
		if (!request.sslCertificate().DoVerify)
			configuration.setPeerVerifyMode(QSslSocket::VerifyNone);
		networkRequest.setSslConfiguration(configuration);
		
		ZLQtNetworkReplyScope scope = { &request, &replies, &errors, &eventLoop };
		if (request.hasListener()) {
			scope.replies = 0;
			scope.errors = 0;
			scope.eventLoop = 0;
		}
		
		prepareReply(scope, qVariantFromValue(data), networkRequest);
*/	}

	int counter;
	result res = E_SUCCESS;
	myMonitor->Enter();
	AppLog("Enter");
	do {
		myMonitor->Wait();
		AppLog("Wait %d",myMonitor->count);
		//AppLog("TransactionCount = %d", counter );
		//res = curl_multi_perform(handle, &counter);
	} while (myMonitor->count > 0);

	AppLog("doAfter");
	myMonitor->Exit();
	AppLog("Exit");
	//	std::set<HttpThread*> httpTreads;
	for (std::set<HttpThread*>::const_iterator it = httpTreads.begin(); it != httpTreads.end(); ++it) {
		    AppLog("Interator doAfter");
	    	HttpThread* httpTread = (HttpThread*)*it;
	    	std::string error = httpTread->myRequest->errorMessage();
			//CURLcode result = message->data.result;
			//bool doAfterResult = request.doAfter(result == CURLE_OK);
	    	bool doAfterResult = httpTread->myRequest->doAfter(true);
	    	httpTread->Join();
	    	delete httpTread;
	}
	AppLog("Exit 2");
	std::string result;
	for (std::set<std::string>::const_iterator et = errors.begin(); et != errors.end(); ++et) {
		if (!result.empty()) {
			result += '\n';
		}
		result += *et;
	}
	httpTreads.clear();
	delete myMonitor;
	return result;
}