예제 #1
0
	void startClient()
	{
		state = ClientStarting;

		refreshTimeout();
		update();
	}
예제 #2
0
void UserDesktopWidget::timerEvent(QTimerEvent* e)
{
    if(e->timerId() == m_refresh_timerid)
        refreshTimeout();
    else if(e->timerId() == m_sendinput_timerid)
        sendDesktopInputTimeout();
}
예제 #3
0
void HTTPTransaction::processIngressBody(unique_ptr<IOBuf> chain, size_t len) {
  DestructorGuard g(this);
  if (aborted_) {
    return;
  }
  refreshTimeout();
  transport_.notifyIngressBodyProcessed(len);
  if (handler_) {
    if (!isIngressComplete()) {
      handler_->onBody(std::move(chain));
    }

    if (useFlowControl_ && !isIngressEOMSeen()) {
      recvToAck_ += len;
      if (recvToAck_ > 0) {
        uint32_t divisor = 2;
        if (transport_.isDraining()) {
          // only send window updates for draining transports when window is
          // closed
          divisor = 1;
        }
        if (uint32_t(recvToAck_) >= (recvWindow_.getCapacity() / divisor)) {
          flushWindowUpdate();
        }
      }
    } // else don't care about window updates
  }
}
예제 #4
0
void HTTPTransaction::updateReadTimeout() {
  if (isExpectingIngress()) {
    refreshTimeout();
  } else {
    cancelTimeout();
  }
}
예제 #5
0
	void startServer()
	{
		state = ServerStarting;

		startKeepAlive();
		refreshTimeout();
		update();
	}
예제 #6
0
void HTTPTransaction::setIdleTimeout(
    std::chrono::milliseconds transactionTimeout) {
  transactionTimeout_ = transactionTimeout;
  VLOG(4) << "HTTPTransaction: transaction timeout is set to  "
          << std::chrono::duration_cast<std::chrono::milliseconds>(
                 transactionTimeout)
                 .count();
  refreshTimeout();
}
예제 #7
0
void HTTPTransaction::processIngressTrailers(unique_ptr<HTTPHeaders> trailers) {
  DestructorGuard g(this);
  if (aborted_) {
    return;
  }
  refreshTimeout();
  if (handler_ && !isIngressComplete()) {
    handler_->onTrailers(std::move(trailers));
  }
}
예제 #8
0
void HTTPTransaction::processIngressChunkComplete() {
  DestructorGuard g(this);
  if (aborted_) {
    return;
  }
  refreshTimeout();
  if (handler_ && !isIngressComplete()) {
    handler_->onChunkComplete();
  }
}
예제 #9
0
// Set a new weight for this node
void
HTTP2PriorityQueue::Node::updateWeight(uint8_t weight) {
  int16_t delta = weight - weight_ + 1;
  weight_ = weight + 1;
  parent_->totalChildWeight_ += delta;
  if (isEnqueued()) {
    parent_->totalEnqueuedWeight_ += delta;
  }
  refreshTimeout();
}
예제 #10
0
void HTTPTransaction::processIngressHeadersComplete(
    std::unique_ptr<HTTPMessage> msg) {
  DestructorGuard g(this);
  if (aborted_) {
    return;
  }
  refreshTimeout();
  if (handler_ && !isIngressComplete()) {
    handler_->onHeadersComplete(std::move(msg));
  }
}
예제 #11
0
StreamOutputWidget::StreamOutputWidget(QWidget *parent)
    : QWidget(parent), m_mutex(QMutex::Recursive), m_audioOutput(NULL), m_IODevice(NULL), m_enabled(false)

{
    //Create GUI components
    m_ui.setupUi(this);

    m_timer =new QTimer(this);

    //Connect signals
    connect(m_ui.m_startButton,SIGNAL(clicked()),this,SLOT(startButtonClicked()));
    connect(m_ui.m_stopButton,SIGNAL(clicked()),this,SLOT(stopButtonClicked()));
    connect(m_ui.m_clearButton,SIGNAL(clicked()),this,SLOT(clearButtonClicked()));
    connect(m_timer,SIGNAL(timeout()),this,SLOT(refreshTimeout()));
    connect(m_ui.m_enabledCheckbox,SIGNAL(toggled(bool)),this,SLOT(enabledButtonClicked(bool)));

    //Scan audio output devices
    scanOutputDevice();

    m_timer->start(100); //100ms timer
}
예제 #12
0
bool CloudAuthenticator::startAuthentication()
{
    qCDebug(dcCloud()) << "Authenticator: Start authenticating" << m_username;

    // Check if we have username and password
    if(!m_username.isEmpty() && !m_password.isEmpty()) {
        m_refreshToken.clear();
        stopAuthentication();

        QUrlQuery query;
        query.addQueryItem("grant_type", "password");
        query.addQueryItem("username", m_username);
        query.addQueryItem("password", m_password);
        setQuery(query);

        QNetworkRequest request(m_url);
        QByteArray data = QString(m_clientId + ":" + m_clientSecret).toUtf8().toBase64();
        QString header = "Basic " + data;
        request.setRawHeader("Authorization", header.toLocal8Bit());
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

        QNetworkReply *reply = m_networkManager->post(request, m_query.toString().toUtf8());
        m_tokenRequests.append(reply);
        return true;

    } else if (!m_refreshToken.isEmpty()) {
        // Use the refreshtoken if there is one
        refreshTimeout();
        return true;
    }

    qCWarning(dcCloud()) << "Authenticator: Cannot start authentication. There is no refresh token, username or password around.";
    stopAuthentication();
    m_error = Cloud::CloudErrorLoginCredentialsMissing;
    return false;
}
예제 #13
0
	void handle(const ZhttpResponsePacket &packet)
	{
		if(state == ClientRequestStartWait)
		{
			if(packet.from.isEmpty())
			{
				state = Stopped;
				errored = true;
				errorCondition = ErrorGeneric;
				cleanup();
				log_warning("zhttp client: error id=%s initial ack for streamed input request did not contain from field", packet.id.data());
				emit q->error();
				return;
			}

			toAddress = packet.from;

			state = ClientRequesting;

			startKeepAlive();
		}
		else if(state == ClientRequestFinishWait)
		{
			toAddress = packet.from;

			state = ClientReceiving;

			if(!doReq)
				startKeepAlive();
		}

		if(packet.type == ZhttpResponsePacket::Error)
		{
			errored = true;
			errorCondition = convertError(packet.condition);

			log_debug("zhttp client: error id=%s cond=%s", packet.id.data(), packet.condition.data());

			state = Stopped;
			cleanup();
			emit q->error();
			return;
		}
		else if(packet.type == ZhttpResponsePacket::Cancel)
		{
			log_debug("zhttp client: received cancel id=%s", packet.id.data());

			errored = true;
			errorCondition = ErrorGeneric;
			state = Stopped;
			cleanup();
			emit q->error();
			return;
		}

		// if non-req mode, check sequencing
		if(!doReq && packet.seq != inSeq)
		{
			log_warning("zhttp client: error id=%s received message out of sequence, canceling", packet.id.data());

			// if this was not an error packet, send cancel
			if(packet.type != ZhttpResponsePacket::Error && packet.type != ZhttpResponsePacket::Cancel)
			{
				ZhttpRequestPacket p;
				p.type = ZhttpRequestPacket::Cancel;
				writePacket(p);
			}

			state = Stopped;
			errored = true;
			errorCondition = ErrorGeneric;
			cleanup();
			emit q->error();
			return;
		}

		++inSeq;

		refreshTimeout();

		if(doReq && (packet.type != ZhttpResponsePacket::Data || packet.more))
		{
			log_warning("zhttp/zws client req: received invalid req response");

			state = Stopped;
			errored = true;
			errorCondition = ErrorGeneric;
			cleanup();
			emit q->error();
			return;
		}

		if(packet.type == ZhttpResponsePacket::Data)
		{
			if(!haveResponseValues)
			{
				haveResponseValues = true;

				responseCode = packet.code;
				responseReason = packet.reason;
				responseHeaders = packet.headers;
			}

			if(doReq)
			{
				if(responseBodyBuf.size() + packet.body.size() > REQ_BUF_MAX)
					log_warning("zhttp client req: id=%s server response too large", packet.id.data());
			}
			else
			{
				if(responseBodyBuf.size() + packet.body.size() > IDEAL_CREDITS)
					log_warning("zhttp client: id=%s server is sending too fast", packet.id.data());
			}

			responseBodyBuf += packet.body;

			if(!doReq && packet.credits > 0)
			{
				outCredits += packet.credits;
				if(outCredits > 0)
				{
					// try to write anything that was waiting on credits
					QPointer<QObject> self = this;
					tryWrite();
					if(!self)
						return;
				}
			}

			if(packet.more)
			{
				if(!packet.body.isEmpty())
					emit q->readyRead();
			}
			else
			{
				// always emit readyRead here even if body is empty, for EOF
				state = Stopped;
				cleanup();
				emit q->readyRead();
			}
		}
		else if(packet.type == ZhttpResponsePacket::Credit)
		{
			if(packet.credits > 0)
			{
				outCredits += packet.credits;
				if(outCredits > 0)
					tryWrite();
			}
		}
		else if(packet.type == ZhttpResponsePacket::KeepAlive)
		{
			// nothing to do
		}
		else
		{
			log_debug("zhttp client: unsupported packet type id=%s type=%d", packet.id.data(), (int)packet.type);
		}
	}
예제 #14
0
HTTPTransaction::HTTPTransaction(TransportDirection direction,
                                 HTTPCodec::StreamID id,
                                 uint32_t seqNo,
                                 Transport& transport,
                                 HTTP2PriorityQueue& egressQueue,
                                 const WheelTimerInstance& timeout,
                                 HTTPSessionStats* stats,
                                 bool useFlowControl,
                                 uint32_t receiveInitialWindowSize,
                                 uint32_t sendInitialWindowSize,
                                 http2::PriorityUpdate priority,
                                 HTTPCodec::StreamID assocId):
    deferredEgressBody_(folly::IOBufQueue::cacheChainLength()),
    direction_(direction),
    id_(id),
    seqNo_(seqNo),
    transport_(transport),
    timeout_(timeout),
    stats_(stats),
    recvWindow_(receiveInitialWindowSize),
    sendWindow_(sendInitialWindowSize),
    egressQueue_(egressQueue),
    assocStreamId_(assocId),
    priority_(priority),
    ingressPaused_(false),
    egressPaused_(false),
    flowControlPaused_(false),
    handlerEgressPaused_(false),
    egressRateLimited_(false),
    useFlowControl_(useFlowControl),
    aborted_(false),
    deleting_(false),
    firstByteSent_(false),
    firstHeaderByteSent_(false),
    inResume_(false),
    inActiveSet_(true),
    ingressErrorSeen_(false),
    priorityFallback_(false),
    headRequest_(false) {

  if (assocStreamId_) {
    if (isUpstream()) {
      egressState_ = HTTPTransactionEgressSM::State::SendingDone;
    } else {
      ingressState_ = HTTPTransactionIngressSM::State::ReceivingDone;
    }
  }

  refreshTimeout();
  if (stats_) {
    stats_->recordTransactionOpened();
  }

  queueHandle_ = egressQueue_.addTransaction(id_, priority, this, false,
                                             &insertDepth_);
  if(priority.streamDependency != 0 && insertDepth_ == 1) {
    priorityFallback_ = true;
  }

  currentDepth_ = insertDepth_;
}
예제 #15
0
	void handle(const ZhttpResponsePacket &packet)
	{
		if(packet.type == ZhttpResponsePacket::Error)
		{
			errorCondition = convertError(packet.condition);

			log_debug("zws client: error id=%s cond=%s", packet.id.data(), packet.condition.data());

			responseCode = packet.code;
			responseReason = packet.reason;
			responseHeaders = packet.headers;
			responseBody = packet.body;

			state = Idle;
			cleanup();
			emit q->error();
			return;
		}
		else if(packet.type == ZhttpResponsePacket::Cancel)
		{
			log_debug("zws client: received cancel id=%s", packet.id.data());

			errorCondition = ErrorGeneric;
			state = Idle;
			cleanup();
			emit q->error();
			return;
		}

		if(!packet.from.isEmpty())
			toAddress = packet.from;

		if(packet.seq != inSeq)
		{
			log_warning("zws client: error id=%s received message out of sequence, canceling", packet.id.data());

			tryRespondCancel(packet);

			state = Idle;
			errorCondition = ErrorGeneric;
			cleanup();
			emit q->error();
			return;
		}

		if(!toAddress.isEmpty() && !keepAliveTimer->isActive())
			startKeepAlive();

		++inSeq;

		refreshTimeout();

		if(state == Connecting)
		{
			if(packet.type != ZhttpResponsePacket::Data && packet.type != ZhttpResponsePacket::Credit && packet.type != ZhttpResponsePacket::KeepAlive)
			{
				state = Idle;
				errorCondition = ErrorGeneric;
				cleanup();
				log_warning("zws client: error id=%s initial response wrong type", packet.id.data());
				emit q->error();
				return;
			}

			if(packet.from.isEmpty())
			{
				state = Idle;
				errorCondition = ErrorGeneric;
				cleanup();
				log_warning("zws client: error id=%s initial ack did not contain from field", packet.id.data());
				emit q->error();
				return;
			}
		}

		if(packet.type == ZhttpResponsePacket::Data || packet.type == ZhttpResponsePacket::Ping || packet.type == ZhttpResponsePacket::Pong)
		{
			if(state == Connecting)
			{
				// this is assured earlier
				assert(packet.type == ZhttpResponsePacket::Data);

				responseCode = packet.code;
				responseReason = packet.reason;
				responseHeaders = packet.headers;

				if(packet.credits > 0)
					outCredits += packet.credits;

				state = Connected;
				update();
				emit q->connected();
			}
			else
			{
				if(inSize + packet.body.size() > IDEAL_CREDITS)
					log_warning("zws client: id=%s server is sending too fast", packet.id.data());

				if(packet.type == ZhttpResponsePacket::Data)
				{
					handleIncomingDataPacket(packet.contentType, packet.body, packet.more);
				}
				else if(packet.type == ZhttpResponsePacket::Ping)
				{
					inFrames += Frame(Frame::Ping, packet.body, false);
					inSize += packet.body.size();
				}
				else if(packet.type == ZhttpResponsePacket::Pong)
				{
					inFrames += Frame(Frame::Pong, packet.body, false);
					inSize += packet.body.size();
				}

				if(packet.credits > 0)
				{
					outCredits += packet.credits;
					if(outCredits > 0)
					{
						// try to write anything that was waiting on credits
						QPointer<QObject> self = this;
						tryWrite();
						if(!self)
							return;
					}
				}

				emit q->readyRead();
			}
		}
		else if(packet.type == ZhttpResponsePacket::Close)
		{
			handlePeerClose(packet.code);
		}
		else if(packet.type == ZhttpResponsePacket::Credit)
		{
			if(packet.credits > 0)
			{
				outCredits += packet.credits;
				if(outCredits > 0)
					tryWrite();
			}
		}
		else if(packet.type == ZhttpResponsePacket::KeepAlive)
		{
			// nothing to do
		}
		else
		{
			log_debug("zws client: unsupported packet type id=%s type=%d", packet.id.data(), (int)packet.type);
		}
	}
예제 #16
0
	void handle(const ZhttpRequestPacket &packet)
	{
		if(packet.type == ZhttpRequestPacket::Error)
		{
			errorCondition = convertError(packet.condition);

			log_debug("zws server: error id=%s cond=%s", packet.id.data(), packet.condition.data());

			state = Idle;
			cleanup();
			emit q->error();
			return;
		}
		else if(packet.type == ZhttpRequestPacket::Cancel)
		{
			log_debug("zws server: received cancel id=%s", packet.id.data());

			errorCondition = ErrorGeneric;
			state = Idle;
			cleanup();
			emit q->error();
			return;
		}

		if(packet.seq != inSeq)
		{
			log_warning("zws server: error id=%s received message out of sequence, canceling", packet.id.data());

			tryRespondCancel(packet);

			state = Idle;
			errorCondition = ErrorGeneric;
			cleanup();
			emit q->error();
			return;
		}

		++inSeq;

		refreshTimeout();

		if(packet.type == ZhttpRequestPacket::Data || packet.type == ZhttpRequestPacket::Ping || packet.type == ZhttpRequestPacket::Pong)
		{
			if(inSize + packet.body.size() > IDEAL_CREDITS)
				log_warning("zws client: id=%s server is sending too fast", packet.id.data());

			if(packet.type == ZhttpRequestPacket::Data)
			{
				handleIncomingDataPacket(packet.contentType, packet.body, packet.more);
			}
			else if(packet.type == ZhttpRequestPacket::Ping)
			{
				inFrames += Frame(Frame::Ping, packet.body, false);
				inSize += packet.body.size();
			}
			else if(packet.type == ZhttpRequestPacket::Pong)
			{
				inFrames += Frame(Frame::Pong, packet.body, false);
				inSize += packet.body.size();
			}

			if(packet.credits > 0)
			{
				outCredits += packet.credits;
				if(outCredits > 0)
				{
					// try to write anything that was waiting on credits
					QPointer<QObject> self = this;
					tryWrite();
					if(!self)
						return;
				}
			}

			emit q->readyRead();
		}
		else if(packet.type == ZhttpRequestPacket::Close)
		{
			handlePeerClose(packet.code);
		}
		else if(packet.type == ZhttpRequestPacket::Credit)
		{
			if(packet.credits > 0)
			{
				outCredits += packet.credits;
				tryWrite();
			}
		}
		else if(packet.type == ZhttpRequestPacket::KeepAlive)
		{
			// nothing to do
		}
		else
		{
			log_debug("zws server: unsupported packet type id=%s type=%d", packet.id.data(), (int)packet.type);
		}
	}
예제 #17
0
	void handle(const ZhttpRequestPacket &packet)
	{
		if(paused)
			return;

		if(packet.type == ZhttpRequestPacket::Error)
		{
			errored = true;
			errorCondition = convertError(packet.condition);

			log_debug("zhttp server: error id=%s cond=%s", packet.id.data(), packet.condition.data());

			state = Stopped;
			cleanup();
			emit q->error();
			return;
		}
		else if(packet.type == ZhttpRequestPacket::Cancel)
		{
			log_debug("zhttp server: received cancel id=%s", packet.id.data());

			errored = true;
			errorCondition = ErrorGeneric;
			state = Stopped;
			cleanup();
			emit q->error();
			return;
		}

		if(packet.seq != inSeq)
		{
			log_warning("zhttp server: error id=%s received message out of sequence, canceling", packet.id.data());

			// if this was not an error packet, send cancel
			if(packet.type != ZhttpRequestPacket::Error && packet.type != ZhttpRequestPacket::Cancel)
			{
				ZhttpResponsePacket p;
				p.type = ZhttpResponsePacket::Cancel;
				writePacket(p);
			}

			state = Stopped;
			errored = true;
			errorCondition = ErrorGeneric;
			cleanup();
			emit q->error();
			return;
		}

		++inSeq;

		refreshTimeout();

		if(packet.type == ZhttpRequestPacket::Data)
		{
			requestBodyBuf += packet.body;

			bool done = haveRequestBody;

			if(!packet.more)
			{
				haveRequestBody = true;
				state = ServerResponseWait;
			}

			if(packet.credits > 0)
				outCredits += packet.credits;

			if(!packet.body.isEmpty() || (!done && haveRequestBody))
				emit q->readyRead();
		}
		else if(packet.type == ZhttpRequestPacket::Credit)
		{
			if(packet.credits > 0)
			{
				outCredits += packet.credits;
				tryWrite();
			}
		}
		else if(packet.type == ZhttpRequestPacket::KeepAlive)
		{
			// nothing to do
		}
		else if(packet.type == ZhttpRequestPacket::HandoffProceed)
		{
			if(pausing)
			{
				pausing = false;
				paused = true;
				emit q->paused();
			}
		}
		else
		{
			log_debug("zhttp server: unsupported packet type id=%s type=%d", packet.id.data(), (int)packet.type);
		}
	}
예제 #18
0
	void tryWrite()
	{
		if(state == Requesting)
		{
			// if all we have to send is EOF, we don't need credits for that
			if(out.isEmpty() && outFinished)
			{
				ZurlRequestPacket p;
				p.id = rid.second;
				p.seq = outSeq++;
				p.body = QByteArray(""); // need to set body to count as content packet

				state = Receiving;
				manager->write(p, replyAddress);
				refreshTimeout();
				return;
			}

			if(!out.isEmpty() && outCredits > 0)
			{
				// if we have data to send, and the credits to do so, then send data.
				// also send credits if we need to.

				int size = qMin(outCredits, out.size());

				QByteArray buf = out.mid(0, size);
				out = out.mid(size);

				outCredits -= size;

				ZurlRequestPacket p;
				p.id = rid.second;
				p.seq = outSeq++;
				p.body = buf;
				if(!out.isEmpty() || !outFinished)
					p.more = true;
				if(pendingInCredits > 0)
				{
					p.credits = pendingInCredits;
					pendingInCredits = 0;
				}

				if(!p.more)
					state = Receiving;

				manager->write(p, replyAddress);
				refreshTimeout();
				emit q->bytesWritten(size);
			}
		}
		else if(state == Receiving)
		{
			if(pendingInCredits > 0)
			{
				// if we have no data to send but we need to send credits, do at least that
				ZurlRequestPacket p;
				p.id = rid.second;
				p.seq = outSeq++;
				p.credits = pendingInCredits;
				pendingInCredits = 0;

				manager->write(p, replyAddress);
				refreshTimeout();
			}
		}
	}
예제 #19
0
	void handle(const ZurlResponsePacket &packet)
	{
		if(state == RequestStartWait)
		{
			if(packet.replyAddress.isEmpty())
			{
				state = Private::Stopped;
				errorCondition = ErrorGeneric;
				cleanup();
				log_warning("initial ack for streamed input request did not contain reply-address");
				emit q->error();
				return;
			}

			replyAddress = packet.replyAddress;

			state = Requesting;
		}
		else if(state == RequestFinishWait)
		{
			replyAddress = packet.replyAddress;

			state = Receiving;
		}

		if(packet.isError)
		{
			// zurl conditions:
			//  remote-connection-failed
			//  connection-timeout
			//  tls-error
			//  bad-request
			//  policy-violation
			//  max-size-exceeded
			//  cancel

			QByteArray cond = packet.condition;
			if(cond == "policy-violation")
				errorCondition = ErrorPolicy;
			else if(cond == "remote-connection-failed")
				errorCondition = ErrorConnect;
			else if(cond == "tls-error")
				errorCondition = ErrorTls;
			else if(cond == "length-required")
				errorCondition = ErrorLengthRequired;
			else if(cond == "connection-timeout")
				errorCondition = ErrorTimeout;
			else // bad-request, max-size-exceeded, cancel
				errorCondition = ErrorGeneric;

			state = Private::Stopped;
			cleanup();
			emit q->error();
			return;
		}

		if(packet.seq != inSeq)
		{
			log_warning("received message out of sequence, canceling");

			// if this was not an error packet, send cancel
			if(packet.condition.isEmpty())
			{
				ZurlRequestPacket p;
				p.id = rid.second;
				p.seq = outSeq++;
				p.cancel = true;
				manager->write(p, replyAddress);
			}

			state = Private::Stopped;
			errorCondition = ErrorGeneric;
			cleanup();
			emit q->error();
			return;
		}

		++inSeq;

		refreshTimeout();

		bool doReadyRead = false;

		if(!packet.body.isNull())
		{
			if(!haveResponseValues)
			{
				haveResponseValues = true;

				responseCode = packet.code;
				responseStatus = packet.reason;
				responseHeaders = packet.headers;
			}

			if(in.size() + packet.body.size() > IDEAL_CREDITS)
				log_warning("zurl is sending too fast");

			in += packet.body;

			if(packet.more)
			{
				if(!packet.body.isEmpty())
					doReadyRead = true;
			}
			else
			{
				// always emit readyRead here even if body is empty, for EOF
				state = Private::Stopped;
				cleanup();
				emit q->readyRead();
				return;
			}
		}

		if(packet.credits > 0)
			outCredits += packet.credits;

		// the only reason we should need to write as a result of a read
		//   is if we were given credits or we have credits to give
		if(packet.credits > 0 || pendingInCredits > 0)
		{
			QPointer<QObject> self = this;
			tryWrite();
			if(!self)
				return;
		}

		if(doReadyRead)
			emit q->readyRead();
	}
예제 #20
0
	void write(const QVariant &vrequest)
	{
		ZurlRequestPacket request;
		if(!request.fromVariant(vrequest))
		{
			QVariantHash vhash = vrequest.toHash();
			if(!vhash["cancel"].toBool())
			{
				QMetaObject::invokeMethod(this, "respondError", Qt::QueuedConnection, Q_ARG(QByteArray, "bad-request"));
			}
			else
			{
				cleanup();
				QMetaObject::invokeMethod(q, "finished", Qt::QueuedConnection);
			}

			return;
		}

		// cancel session if a wrong sequenced packet is received
		if(inSeq == -1 || request.seq == -1 || request.seq != inSeq + 1)
		{
			if(!request.cancel)
			{
				QMetaObject::invokeMethod(this, "respondError", Qt::QueuedConnection, Q_ARG(QByteArray, "cancel"));
			}
			else
			{
				cleanup();
				QMetaObject::invokeMethod(q, "finished", Qt::QueuedConnection);
			}

			return;
		}

		if(request.cancel)
		{
			cleanup();
			QMetaObject::invokeMethod(q, "finished", Qt::QueuedConnection);
			return;
		}

		refreshTimeout();

		inSeq = request.seq;

		// all we care about from follow-up writes are body and credits

		if(request.credits != -1)
			outCredits += request.credits;

		if(!request.body.isNull())
		{
			if(bodySent)
			{
				QMetaObject::invokeMethod(this, "respondError", Qt::QueuedConnection, Q_ARG(QByteArray, "bad-request"));
				return;
			}

			if(!request.body.isEmpty())
				hreq->writeBody(request.body);

			// the 'more' flag only has significance if body field present
			if(!request.more)
			{
				bodySent = true;
				hreq->endBody();
			}
		}

		// if we needed credits to send something, take care of that now
		if(request.credits != -1 && stuffToRead)
			trySend();
	}
예제 #21
0
				inline ClientHandler(PacketHandler<ClientHandler>& mPacketHandler) : packetHandler(mPacketHandler)
				{
					onPacketReceived += [this](sf::Packet mPacket){ packetHandler.handle(*this, mPacket); refreshTimeout(); };
					timeoutFuture = std::async(std::launch::async, [this]
					{
						while(running)
						{
							std::this_thread::sleep_for(800ms);

							if(!isBusy() || --untilTimeout > 0) continue;

							HG_LO_VERBOSE("ClientHandler") << "Client (" << uid << ") timed out\n";
							onDisconnect(); disconnect();
						}
					});
				}
예제 #22
-1
파일: worker.cpp 프로젝트: HunterChen/zurl
	void write(const QVariant &vrequest)
	{
		ZhttpRequestPacket request;
		if(!request.fromVariant(vrequest))
		{
			QVariantHash vhash = vrequest.toHash();
			if(vhash["type"].toByteArray() != "cancel")
			{
				QMetaObject::invokeMethod(this, "respondError", Qt::QueuedConnection, Q_ARG(QByteArray, "bad-request"));
			}
			else
			{
				cleanup();
				QMetaObject::invokeMethod(q, "finished", Qt::QueuedConnection);
			}

			return;
		}

		// cancel session if a wrong sequenced packet is received
		if(inSeq == -1 || request.seq == -1 || request.seq != inSeq + 1)
		{
			if(request.type != ZhttpRequestPacket::Cancel)
			{
				QMetaObject::invokeMethod(this, "respondCancel", Qt::QueuedConnection);
			}
			else
			{
				cleanup();
				QMetaObject::invokeMethod(q, "finished", Qt::QueuedConnection);
			}

			return;
		}

		if(request.type == ZhttpRequestPacket::Cancel)
		{
			cleanup();
			QMetaObject::invokeMethod(q, "finished", Qt::QueuedConnection);
			return;
		}

		inSeq = request.seq;

		refreshTimeout();

		// all we care about from follow-up writes are body and credits

		if(request.credits != -1)
			outCredits += request.credits;

		if(transport == HttpTransport)
		{
			if(request.type == ZhttpRequestPacket::Data)
			{
				if(bodySent)
				{
					QMetaObject::invokeMethod(this, "respondError", Qt::QueuedConnection, Q_ARG(QByteArray, "bad-request"));
					return;
				}

				refreshActivityTimeout();

				if(!request.body.isEmpty())
					hreq->writeBody(request.body);

				// the 'more' flag only has significance if body field present
				if(!request.more)
				{
					bodySent = true;
					hreq->endBody();
				}
			}
		}
		else // WebSocketTransport
		{
			if(request.type == ZhttpRequestPacket::Data || request.type == ZhttpRequestPacket::Close || request.type == ZhttpRequestPacket::Ping || request.type == ZhttpRequestPacket::Pong)
			{
				refreshActivityTimeout();

				if(request.type == ZhttpRequestPacket::Data)
				{
					WebSocket::Frame::Type ftype;
					if(wsSendingMessage)
						ftype = WebSocket::Frame::Continuation;
					else if(request.contentType == "binary")
						ftype = WebSocket::Frame::Binary;
					else
						ftype = WebSocket::Frame::Text;

					wsSendingMessage = request.more;

					wsPendingWrites += request.body.size();
					ws->writeFrame(WebSocket::Frame(ftype, request.body, request.more));
				}
				else if(request.type == ZhttpRequestPacket::Ping)
				{
					wsPendingWrites += 0;
					ws->writeFrame(WebSocket::Frame(WebSocket::Frame::Ping, QByteArray(), false));
				}
				else if(request.type == ZhttpRequestPacket::Pong)
				{
					wsPendingWrites += 0;
					ws->writeFrame(WebSocket::Frame(WebSocket::Frame::Pong, QByteArray(), false));
				}
				else if(request.type == ZhttpRequestPacket::Close)
					ws->close(request.code);
			}
		}

		// if we needed credits to send something, take care of that now
		if(request.credits != -1 && stuffToRead)
			trySend();
	}