void Server::nachrichtEmpfangen() { QTcpSocket *client = dynamic_cast<QTcpSocket *>(sender()); if (client == 0) { std::cerr << "Server::nachrichtEmpfangen : sender() ist nicht QTcpSocket"; } while (client->canReadLine()) { QByteArray nachricht_bytes = client->readLine(); QString nachricht = QString::fromUtf8(nachricht_bytes); QString typ = nachricht.section(QString::fromLatin1("\x1F"),0,0); if (typ == QString::fromLatin1("chat")) { for (int i = 0; i < anzahlClients; ++i) { if (clients[i] != client) { clients[i]->write(nachricht_bytes); } } QString absender = nachricht.section(QString::fromLatin1("\x1F"),1,1); QString text = nachricht.section(QString::fromLatin1("\x1F"),2,-1); emit chatEmpfangen(QString::fromLatin1("<b>") + absender + QString::fromLatin1("</b>: ") + text); } else if (typ == QString::fromLatin1("wurf")) { for (int i = 0; i < anzahlClients; ++i) { if (clients[i] != client) { clients[i]->write(nachricht_bytes); } } int augenzahl = nachricht.section(QString::fromLatin1("\x1F"),1,1).toInt(); emit wurfelnEmpfangen(augenzahl); } } }
static QByteArray readLine(QTcpSocket &sock) { while (!sock.canReadLine() && sock.waitForReadyRead()); if (sock.state() != QAbstractSocket::ConnectedState) return QByteArray(); return sock.readLine(); }
void HttpServer :: readClient() { if (disabled) return; QTcpSocket *socket = (QTcpSocket*)sender(); if( socket->canReadLine()) { QString request = socket->readLine(); QStringList tokens = request.split(QRegExp("[ \r\n][ \r\n]*")); if( tokens[0] == "GET") { d->engine.globalObject().setProperty("token", tokens[1]); QScriptValue reply = d->engine.evaluate("reply(token)"); QTextStream os(socket); os.setAutoDetectUnicode(true); os << reply.toString().toUtf8(); socket->close(); QtServiceBase::instance()->logMessage("Wrote index.html"); if(socket->state() == QTcpSocket::UnconnectedState) { delete socket; QtServiceBase::instance()->logMessage("Conncetion closed"); } } } }
void HttpDaemon::readClient() { QTcpSocket* socket = (QTcpSocket*)sender(); if (socket->canReadLine()) { QTextStream os(socket); os.setAutoDetectUnicode(true); os << "HTTP/1.0 200 Ok\r\n" "Content-Type: text/html; charset=\"utf-8\"\r\n" "\r\n"; QStringList tokens = QString(socket->readLine()).split(QRegExp("[ \r\n][ \r\n]*")); QRegExp pathPattern("^/websocket\\.(html|js)$"); if (pathPattern.exactMatch(tokens[1])) { QFile file (":" + pathPattern.capturedTexts()[0]); file.open(QFile::ReadOnly); os << file.readAll() << "\n\n"; } else { os << "<h1>Nothing to see here</h1>\n\n"; } socket->close(); if (socket->state() == QTcpSocket::UnconnectedState) delete socket; } }
/** * Slot * @brief Serveur::pretALire */ void Serveur::readyRead() { QTcpSocket *client = (QTcpSocket*)sender(); while(client->canReadLine()) { QString ligne = QString::fromUtf8(client->readLine()).trimmed(); qDebug() << "Read line:" << ligne; QRegExp meRegex("^/me:(.*)$"); if(meRegex.indexIn(ligne) != -1) { QString utilisateur = meRegex.cap(1); m_utilisateurs[client] = utilisateur; foreach(QTcpSocket *client, m_clients) client->write(QString("Serveur:" + utilisateur + " a rejoint le serveur.\n").toUtf8()); envoyerListeUtilisateur(); } else if(m_utilisateurs.contains(client)) { QString message = ligne; QString utilisateur = m_utilisateurs[client]; qDebug() << "Utilisateur:" << utilisateur; qDebug() << "Message:" << message; foreach(QTcpSocket *otherClient, m_clients) otherClient->write(QString(utilisateur + ":" + message + "\n").toUtf8()); } else { qWarning() << "Erreur du client:" << client->peerAddress().toString() << ligne; } } }
void KCToolServer::onSocketReadyRead() { QTcpSocket *socket = qobject_cast<QTcpSocket*>(QObject::sender()); // Parse the first line if(!socket->property("firstLineRead").toBool()) { QString line(socket->readLine()); int sepPos1(line.indexOf(" ")); int sepPos2(line.indexOf(" ", sepPos1+1)); QString method(line.left(sepPos1)); QString path(line.mid(sepPos1+1, sepPos2 - sepPos1 - 1)); socket->setProperty("method", method); socket->setProperty("path", path); socket->setProperty("firstLineRead", true); } // Parse Headers! if(!socket->property("headerRead").toBool()) { QVariantMap headers(socket->property("headers").toMap()); while(socket->canReadLine()) { QString line = QString(socket->readLine()).trimmed(); // The header section is terminated by an empty line if(line == "") { socket->setProperty("headerRead", true); break; } // Split it up int sepPos(line.indexOf(":")); QString key(line.left(sepPos).trimmed()); QString val(line.mid(sepPos+1).trimmed()); headers.insertMulti(key, val); } socket->setProperty("headers", headers); } qint64 contentLength = socket->property("headers").toMap().value("Content-Length").toLongLong(); // Read the body into a buffer if(socket->bytesAvailable()) { QByteArray buffer(socket->property("buffer").toByteArray()); qint64 toRead = contentLength - buffer.size(); buffer.append(socket->read(toRead)); socket->setProperty("buffer", buffer); socket->setProperty("toRead", contentLength - buffer.size()); // If we have a Content-Length (toLong() fails with 0) if(contentLength > 0 && buffer.size() >= contentLength) this->handleRequest(socket); } else if(contentLength == -1 || contentLength == 0) { this->handleRequest(socket); } }
void DataTransferServer::readyRead() { QTcpSocket *client = (QTcpSocket*)sender(); while(client->canReadLine()) { QString message = QString::fromUtf8(client->readLine()).trimmed(); qDebug() << "Read line message:" << message; foreach(QTcpSocket *otherClient, clients) otherClient->write(QString(message + "\n").toUtf8()); } }
void LegacyPlayerListener::onDataReady() { QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender()); if (!socket) return; connect( socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()) ); while (socket->canReadLine()) { QString line = QString::fromUtf8( socket->readLine() ); try { PlayerCommandParser parser( line ); QString const id = parser.playerId(); PlayerConnection* connection = 0; if (!m_connections.contains( id )) { connection = m_connections[id] = new PlayerConnection( parser.playerId(), parser.playerName() ); emit newConnection( connection ); } else connection = m_connections[id]; switch (parser.command()) { case CommandBootstrap: qWarning() << "We no longer support Bootstrapping with the LegacyPlayerListener"; break; case CommandTerm: m_connections.remove( id ); // FALL THROUGH default: connection->handleCommand( parser.command(), parser.track() ); break; } socket->write( "OK\n" ); } catch (std::invalid_argument& e) { QString const error = QString::fromUtf8( e.what() ); qWarning() << line << error; QString s = "ERROR: " + error + "\n"; socket->write( s.toUtf8() ); } } socket->close(); }
void HttpDaemon :: readClient() { QTcpSocket *socket = (QTcpSocket*) sender(); if (socket->canReadLine()) { QStringList tokens = QString(socket->readLine()).split(QRegExp("[ \r\n][ \r\n]*")); handleToken(tokens, socket); if (socket->state() == QTcpSocket::UnconnectedState) { delete socket; } } }
void ConnectionThread::run() { Debug() << "Thread started."; QTcpSocket sock; socketNoNagle(sockdescr); if (!sock.setSocketDescriptor(sockdescr)) { Error() << sock.errorString(); return; } QString remoteHostPort = sock.peerAddress().toString() + ":" + QString::number(sock.peerPort()); Log() << "Connection from peer " << remoteHostPort; QString line; forever { if (sock.canReadLine() || sock.waitForReadyRead()) { line = sock.readLine().trimmed(); while (StimApp::instance()->busy()) { // special case case, stimapp is busy so keep polling with 1s intervals Debug() << "StimApp busy, cannot process command right now.. trying again in 1 second"; sleep(1); // keep sleeping 1 second until the stimapp is no longer busy .. this keeps us from getting given commands while we are still initializing } // normal case case, stimapp not busy, proceed normally QString resp; resp = processLine(sock, line); if (sock.state() != QAbstractSocket::ConnectedState) { Debug() << "processLine() closed connection"; break; } if (!resp.isNull()) { if (resp.length()) { Debug() << "Sending: " << resp; if (!resp.endsWith("\n")) resp += "\n"; QByteArray data(resp.toUtf8()); int len = sock.write(data); if (len != data.length()) { Debug() << "Sent " << len << " bytes but expected to send " << data.length() << " bytes!"; } } Debug() << "Sending: OK"; sock.write("OK\n"); } else { Debug() << "Sending: ERROR"; sock.write("ERROR\n"); } } else { if (sock.error() != QAbstractSocket::SocketTimeoutError || sock.state() != QAbstractSocket::ConnectedState) { Debug() << "Socket error: " << sock.error() << " Socket state: " << sock.state(); break; } } } Log() << "Connection ended (peer: " << remoteHostPort << ")"; Debug() << "Thread exiting."; }
void ctkSoapConnectionRunnable::readClient(QTcpSocket& socket) { //qDebug() << socket->readAll(); while (socket.canReadLine()) { QString line = socket.readLine(); qDebug() << line; if (line.trimmed().isEmpty()) { // Read the http body, which contains the soap message QByteArray body = socket.readAll(); qDebug() << body; if (body.trimmed().isEmpty()) { qDebug() << "Message body empty"; return; } QtSoapMessage msg; if (!msg.setContent(body)) { qDebug() << "QtSoap import failed:" << msg.errorString(); return; } QtSoapMessage reply; emit incomingSoapMessage(msg, &reply); if (reply.isFault()) { qDebug() << "QtSoap reply faulty"; return; } qDebug() << "SOAP reply:"; QString soapContent = reply.toXmlString(); QByteArray block; block.append("HTTP/1.1 200 OK\n"); block.append("Content-Type: text/xml;charset=utf-8\n"); block.append("Content-Length: ").append(QString::number(soapContent.size())).append("\n"); block.append("\n"); block.append(soapContent); qDebug() << block; socket.write(block); } } }
void HttpServer::readClient() { if (!m_accept) return; QTcpSocket* socket = (QTcpSocket*)sender(); try { if (socket->canReadLine()) { QString hdr = QString(socket->readLine()); QVariantMap headers; if (hdr.startsWith("POST") || hdr.startsWith("GET")) { QUrl url(hdr.split(' ')[1]); QString l; do { l = socket->readLine(); //collect headers int colon = l.indexOf(':'); if (colon > 0) headers[l.left(colon).trimmed().toLower()] = l.right(l.length() - colon - 1).trimmed(); } while (!(l.isEmpty() || l == "\r" || l == "\r\n")); QString content = socket->readAll(); std::unique_ptr<HttpRequest> request(new HttpRequest(this, std::move(url), std::move(content), std::move(headers))); clientConnected(request.get()); QTextStream os(socket); os.setAutoDetectUnicode(true); QString q; ///@todo: allow setting response content-type, charset, etc os << "HTTP/1.0 200 Ok\r\n"; if (!request->m_responseContentType.isEmpty()) os << "Content-Type: " << request->m_responseContentType << "; "; os << "charset=\"utf-8\"\r\n\r\n"; os << request->m_response; } } } catch(...) { delete socket; throw; } socket->close(); if (socket->state() == QTcpSocket::UnconnectedState) delete socket; }
void LCDServer::readSocket() { QTcpSocket *socket = dynamic_cast<QTcpSocket*>(sender()); m_lastSocket = socket; while(socket->canReadLine()) { QString incoming_data = socket->readLine(); incoming_data = incoming_data.replace( QRegExp("\n"), "" ); incoming_data = incoming_data.replace( QRegExp("\r"), "" ); incoming_data.simplified(); QStringList tokens = parseCommand(incoming_data); parseTokens(tokens, socket); } }
void HttpDaemon::readClient() { if (disabled) return; // This slot is called when the client sent data to the server. The // server looks if it was a get request and sends a very simple HTML // document back. QTcpSocket* socket = (QTcpSocket*)sender(); if (socket->canReadLine()) { QByteArray data = socket->readLine(); QStringList tokens = QString(data).split(QRegExp("[ \r\n][ \r\n]*")); qDebug() << "incoming data" << tokens[1]; QUrl url("http://foo.bar" + tokens[1]); QUrlQuery query(url); qDebug() << "query is" << url.path(); if (url.path() == "/setstate") { emit setState(StateTypeId(query.queryItems().first().first), QVariant(query.queryItems().first().second)); } else if (url.path() == "/generateevent") { qDebug() << "got generateevent" << query.queryItemValue("eventtypeid"); emit triggerEvent(EventTypeId(query.queryItemValue("eventtypeid"))); } else if (url.path() == "/actionhistory") { QTextStream os(socket); os.setAutoDetectUnicode(true); os << generateHeader(); for (int i = 0; i < m_actionList.count(); ++i) { os << m_actionList.at(i).first.toString() << '\n'; } socket->close(); return; } else if (url.path() == "/clearactionhistory") { m_actionList.clear(); } if (tokens[0] == "GET") { QTextStream os(socket); os.setAutoDetectUnicode(true); os << generateWebPage(); socket->close(); qDebug() << "Wrote to client"; if (socket->state() == QTcpSocket::UnconnectedState) { delete socket; qDebug() << "Connection closed"; } } } }
//The method checks for the data recieved and if a destroy command is recieved it echos out the command, if a score command is recieved it saves the score //and if both scores have been recieved it sends out the winner. void MultiplayerGUI::dataRecieved() { QTcpSocket * sock = dynamic_cast<QTcpSocket*>(sender()); while (sock->canReadLine()){ QString line = sock->readLine(); if (line.indexOf("DESTROY:") != -1){ for (QTcpSocket * socket: currentConnections){ if (socket != sock){ socket->write(line.toLocal8Bit()); } } } else if (line.indexOf("SCORE:") != -1){ line = line.remove(0, 6); QStringList scoreList = line.split(":"); if (player1Name == ""){ player1Name = scoreList.at(0); player1Score = scoreList.at(1).toInt(); } else{ player2Name = scoreList.at(0); player2Score = scoreList.at(1).toInt(); if (player1Score > player2Score){ QString winningScore = "WINNER:" + player1Name + " wins with a score of " + QString::number(player1Score) +"\n"; for (QTcpSocket * sock: currentConnections){ sock->write(winningScore.toLocal8Bit()); } } else if (player1Score == player2Score){ QString winningScore = "WINNER: You have tied with a score of " + QString::number(player2Score) + "\n"; for (QTcpSocket * sock: currentConnections){ sock->write(winningScore.toLocal8Bit()); } } else{ QString winningScore = "WINNER:" + player2Name + " wins with a score of " + QString::number(player2Score) + "\n"; for (QTcpSocket * sock: currentConnections){ sock->write(winningScore.toLocal8Bit()); } } } } } // ServerProcessThread * thread = new ServerProcessThread(sock, currentConnections); //connect(thread, &QThread::finished, this, &MultiplayerGUI::serverProcessFinished); //thread->start(); }
void EvopediaWebServer::readClient() { QTcpSocket* socket = (QTcpSocket*)sender(); if (!socket->canReadLine()) return; /* TODO1 wait for end of request header? peek? */ const QList<QByteArray> tokens = socket->readLine().split(' '); if (tokens[0] != "GET" || tokens.size() < 2) { outputHeader(socket, "404"); closeConnection(socket); return; } const QUrl url = QUrl::fromPercentEncoding(tokens[1]); QString path = url.path(); if (path.endsWith("skins/common/images/magnify-clip.png")) path = "/static/magnify-clip.png"; const QStringList pathParts = path.mid(1).split('/'); if (pathParts.length() < 1 || pathParts[0].isEmpty()) { outputIndexPage(socket); closeConnection(socket); return; } const QString &firstPart = pathParts[0]; if (firstPart == "static") { outputStatic(socket, pathParts); } else if (firstPart == "search") { outputSearchResult(socket, url.queryItemValue("q"), url.queryItemValue("lang")); } else if (firstPart == "map") { qreal lat = url.queryItemValue("lat").toDouble(); qreal lon = url.queryItemValue("lon").toDouble(); int zoom = url.queryItemValue("zoom").toInt(); mapViewRequested(lat, lon, zoom); } else if (firstPart == "random") { redirectRandom(socket, pathParts); } else if (firstPart == "math" || (firstPart == "wiki" && pathParts.length() >= 2 && pathParts[1] == "math")) { outputMathImage(socket, pathParts); } else if (firstPart == "wiki" || firstPart == "articles") { outputWikiPage(socket, pathParts); } else { outputHeader(socket, "404"); } closeConnection(socket); }
//recieves x,y,and paddle id from user void Start::dataReceived() { QTcpSocket *sock = dynamic_cast<QTcpSocket*>(sender()); while (sock->canReadLine()) { QString str = sock->readLine(); // qDebug() << str; //World::getInstance()->updateUser(str); akjdhfa //do something with the information that is coming in // "3/Thomas/x/y/ // pos/username/x/y/ vector<QString>* info = World::getInstance()->split(str,'/'); int pos = info->at(0).toInt(); QString userName = info->at(1); if (ok && clock < 50){ Player *inPlayer = World::getInstance()->getGamePlayer(pos); inPlayer->setUsername(userName); gameScreen->setUsernames(); if (clock > 50){ ok = false; } } int x = info->at(2).toInt(); int y = info->at(3).toInt(); QPoint* mouseIn = new QPoint(x,y); World::getInstance()->addMouse(mouseIn,pos); World::getInstance()->setPlayerName(info->at(1), pos); } //} //**********This is Schaub code that we can use as an example**************** /*QTcpSocket *sock = dynamic_cast<QTcpSocket*>(sender()); addToLog("Received data from socket "); while (sock->canReadLine()) { QString str = sock->readLine(); addToLog("-> " + str); // send data to all connected clients for (QObject *obj : server->children()) { QTcpSocket *anotherSock = dynamic_cast<QTcpSocket*>(obj); if (anotherSock != NULL) anotherSock->write(str.toLocal8Bit()); } }*/ }
QByteArray ImapPrivate::readLine (bool *ok) { quint8 attempts = 0; while (!socket->canReadLine() && attempts < 2) { if (!socket->waitForReadyRead()) attempts++; } if (attempts >= 2) { if (ok != NULL) *ok = false; return(QByteArray()); } if (ok != NULL) *ok = true; #ifdef IMAP_DEBUG QByteArray response = socket->readLine(); qDebug() << "readLine()" << response; return(response); #else return(socket->readLine()); #endif }
void HttpServer::readClient() { QTcpSocket * socket = (QTcpSocket*)sender(); if (socket->canReadLine()) { QTextStream os(socket); os.setAutoDetectUnicode(true); QStringList tokens = QString(socket->readLine()).split(QRegExp("[ \r\n][ \r\n]*")); if (tokens[0] == "GET") { QStringList resources = tokens[1].split(QRegExp("\\?")); if (resources.count() == 2) { if (resources[0] == "/canvas.html") { QStringList args = resources[1].split(QRegExp("&(amp){0}")); foreach (QString arg, args) { QStringList kv = arg.split("="); if (kv.count() == 2 && kv[0] == "app") { if (ACLProvider::instance()->isAccepted(kv[1])) { qDebug() << "Sending canvas.html page"; this->sendCanvas(os, kv[1]); goto close_socket; } else { this->sendRejection(os, kv[1]); goto close_socket; } } } qDebug() << "Cannot find application name"; this->sendStatus(os, 400); goto close_socket; }
void ChatBoxServer::readyRead() { // Used to retrieve a pointer to the client QTcpSocket *client = (QTcpSocket*)sender(); while(client->canReadLine()) { QString line = QString::fromUtf8(client->readLine()).trimmed(); qDebug() << "Read line:" << line; QRegExp meRegex("^/me:(.*)$"); if(meRegex.indexIn(line) != -1) { QString user = meRegex.cap(1); // Insert username into QMap users[client] = user; foreach(QTcpSocket *client, clients) client->write(QString("Server:" + user + " has joined.\n").toUtf8()); sendUserList(); } else if(users.contains(client)) { QString message = line; QString user = users[client]; qDebug() << "User:"******"Message:" << message; foreach(QTcpSocket *otherClient, clients) otherClient->write(QString(user + ":" + message + "\n").toUtf8()); } else { qWarning() << "Got bad message from client:" << client->peerAddress().toString() << line; } } }
void ServerPanelRpcServer::ReadClient() { // Check to see if the server is paused if (this->bDisabled) { // We're done return; } // Open the socket QTcpSocket* cSocket = (QTcpSocket*) sender(); // Can we read the socket if (cSocket->canReadLine()) { // Grab the headers QStringList qslTokens = QString(cSocket->readLine().split(QRegExp("[ \r\n][ \r\n]*"))); // What reqeust was sent if (qslTokens[0] == "GET") { // GET // Create a new text stream for the socket QTextStream cSocketStream(cSocket); // Automagically detect the use of unicode cSocketStream.setAutoDetectUnicode(true); // Send a response cSocketStream << "HTTP/1.0 200 Ok\r\n"; cSocketStream << "Content-Type: application/json; charset=\"utf-8\"\r\n"; cSocketStream << "\r\n"; cSocketStream << "{\"sServerResponse\":\"Good!\", \"sServerTime\":\""; cSocketStream << QDateTime::currentDateTime().toString() << "\"}\n"; } else if (qslTokens[0] == "POST") { // POST } else { // Unknown/Unsupported } } // Close the socket cSocket->close(); // Check the state of the socket if (cSocket->state() == QTcpSocket::UnconnectedState) { // Remove the socket delete cSocket; } }
void Servernet::readyRead() { QTcpSocket *client =(QTcpSocket*)sender(); while(client->canReadLine()) { QString line = QString::fromUtf8(client->readLine()).trimmed(); QRegExp meRegex("^/me:(.*)$"); QRegExp commandRegex("^/command:(.*)$"); if(meRegex.indexIn(line) != -1 && players.size()<=this->playernumber) ///az auth rész { QString user = meRegex.cap(1); players.insert(client,user); Command c((uchar)clients.size(),(uchar)255,(int)survive?0:1); client->write(c.ToString().toUtf8()); client->flush(); emit NewPlayerConnected(); sendusernames(); if(players.size()==this->playernumber)emit AllPlayersConnected(); } else if(commandRegex.indexIn(line) != -1) ///command jön a klienstől { uchar id,type; int msg; QStringList command = commandRegex.cap(1).split(' '); id=(uchar)command.at(0).toInt(); type=(uchar)command.at(1).toInt(); msg=command.at(2).toInt(); emit CommandReceivedFromClients(Command(id,type,msg)); } else ///egyéb hülyeség jön a klienstől { qDebug() << "hülyeség jött"; } } }
void httpServer::getClientRequest() { QTcpSocket *client = qobject_cast<QTcpSocket *>(sender()); if(client->canReadLine()) { QStringList lines = QString(client->readLine()).split(QRegExp("[ \r\n][ \r\n]*")); if(lines[0] == "GET") { viewMessage(QString::fromUtf8("Envoi du catalogue à ")+client->peerAddress().toString()+":"+QString::number(client->peerPort())); QFile catalogue(QCoreApplication::applicationDirPath()+"/catalog.tmp"); catalogue.open(QIODevice::ReadOnly | QIODevice::Text); QTextStream os(client); QTextStream is(&catalogue); os << "HTTP/1.1 200 OK\r\nServer: TP_Serveur_3208\r\nConnection: Keep-Alive\r\nContent-Type: text/txt\r\nContent-Length: " << catalogue.size() << "\r\n\r\n"; QString line = is.readLine(); while(!line.isNull()) { os << line.toLocal8Bit().constData() << "\r\n"; line = is.readLine(); } catalogue.close(); } } }
/*! \internal */ void QWebSocketServerPrivate::handshakeReceived() { if (Q_UNLIKELY(!currentSender)) { return; } QTcpSocket *pTcpSocket = qobject_cast<QTcpSocket*>(currentSender->sender); if (Q_UNLIKELY(!pTcpSocket)) { return; } //When using Google Chrome the handshake in received in two parts. //Therefore, the readyRead signal is emitted twice. //This is a guard against the BEAST attack. //See: https://www.imperialviolet.org/2012/01/15/beastfollowup.html //For Safari, the handshake is delivered at once //FIXME: For FireFox, the readyRead signal is never emitted //This is a bug in FireFox (see https://bugzilla.mozilla.org/show_bug.cgi?id=594502) if (!pTcpSocket->canReadLine()) { return; } disconnect(pTcpSocket, &QTcpSocket::readyRead, this, &QWebSocketServerPrivate::handshakeReceived); Q_Q(QWebSocketServer); bool success = false; bool isSecure = false; if (m_pendingConnections.length() >= maxPendingConnections()) { pTcpSocket->close(); pTcpSocket->deleteLater(); setError(QWebSocketProtocol::CloseCodeAbnormalDisconnection, QWebSocketServer::tr("Too many pending connections.")); return; } QWebSocketHandshakeRequest request(pTcpSocket->peerPort(), isSecure); QTextStream textStream(pTcpSocket); request.readHandshake(textStream, MAX_HEADERLINE_LENGTH, MAX_HEADERLINES); if (request.isValid()) { QWebSocketCorsAuthenticator corsAuthenticator(request.origin()); Q_EMIT q->originAuthenticationRequired(&corsAuthenticator); QWebSocketHandshakeResponse response(request, m_serverName, corsAuthenticator.allowed(), supportedVersions(), supportedProtocols(), supportedExtensions()); if (response.isValid()) { QTextStream httpStream(pTcpSocket); httpStream << response; httpStream.flush(); if (response.canUpgrade()) { QWebSocket *pWebSocket = QWebSocketPrivate::upgradeFrom(pTcpSocket, request, response); if (pWebSocket) { addPendingConnection(pWebSocket); Q_EMIT q->newConnection(); success = true; } else { setError(QWebSocketProtocol::CloseCodeAbnormalDisconnection, QWebSocketServer::tr("Upgrade to WebSocket failed.")); } } else { setError(response.error(), response.errorString()); } } else { setError(QWebSocketProtocol::CloseCodeProtocolError, QWebSocketServer::tr("Invalid response received.")); } } if (!success) { pTcpSocket->close(); } }
QString ConnectionThread::processLine(QTcpSocket & sock, const QString & line) { Debug() << "Got Line: " << line; QStringList toks = line.split(QRegExp("\\s+"), QString::SkipEmptyParts); if (toks.size() < 1) return QString::null; QString cmd = toks.front(); toks.pop_front(); cmd = cmd.toUpper(); if (cmd == "NOOP") { return ""; // noop command alwasy prints OK -- used to test server connectivity and for keepaliveage, etc } else if (cmd == "GETTIME") { return QString::number(getTime(), 'f', 9); } else if (cmd == "GETFRAMENUM") { StimPlugin *p = stimApp()->glWin()->runningPlugin(); if (p) { return QString::number(p->getFrameNum()); } else { Error() << "GETFRAMENUM command received but no plugin was running."; } } else if (cmd == "GETHWFRAMENUM") { GetHWFrameCountEvent *e = new GetHWFrameCountEvent(); GetSetData *d = e->d; stimApp()->postEvent(this, e); unsigned hwfc = d->getReply<unsigned>(); delete d; return QString::number(hwfc); } else if (cmd == "GETREFRESHRATE") { unsigned rate = stimApp()->refreshRate(); return QString::number(rate); } else if (cmd == "GETCURRENTRSEED") { int s = stimApp()->glWin() ? (stimApp()->glWin()->runningPlugin() ? stimApp()->glWin()->runningPlugin()->currentRSeed() : 0) : 0; return QString::number(s); } else if (cmd == "GETWIDTH") { return QString::number(stimApp()->glWin()->width()); } else if (cmd == "GETHEIGHT") { return QString::number(stimApp()->glWin()->height()); } else if (cmd == "GETFRAME" && toks.size()) { bool ok; unsigned framenum = toks[0].toUInt(&ok), numFrames = 1; Vec2i co, cs, ds; // params 3,4,5,6,7,8 are crop-origin-x, crop-origin-y, crop-size-width, crop-size-height, downsample-factor-x, downsample-factor-y toks.pop_front(); if (toks.size()) { bool ok2; numFrames = toks.front().toUInt(&ok2); if (ok2) toks.pop_front(); if (!ok2 || numFrames < 1) numFrames = 1; Vec2i *vp[] = { &co, &cs, &ds, 0 }; for (Vec2i **vcur = vp; *vcur; ++vcur) { Vec2i & v = **vcur; v.x = toks.size() ? toks.front().toUInt(&ok2) : 0; if (ok2) toks.pop_front(); if (!ok2 || v.x < 0) v.x = 0; v.y = toks.size() ? toks.front().toUInt(&ok2) : 0; if (ok2) toks.pop_front(); if (!ok2 || v.y < 0) v.y = 0; } } if (!ds.x) ds.x = 1; if (!ds.y) ds.y = 1; int datatype = GL_UNSIGNED_BYTE; if (toks.size()) { QString s = toks.join(" ").toUpper().trimmed(); if (s == "BYTE") datatype = GL_BYTE; else if (s == "UNSIGNED BYTE") datatype = GL_UNSIGNED_BYTE; else if (s == "SHORT") datatype = GL_SHORT; else if (s == "UNSIGNED SHORT") datatype = GL_UNSIGNED_SHORT; else if (s == "INT") datatype = GL_INT; else if (s == "UNSIGNED INT") datatype = GL_UNSIGNED_INT; else if (s == "FLOAT") datatype = GL_FLOAT; else { Error() << "GETFRAME command invalid datatype `" << s << "'."; return QString::null; } } if (ok) { GetFrameEvent *e = new GetFrameEvent(framenum, numFrames, co, cs, ds, datatype); GetSetData *d = e->d; stimApp()->postEvent(this, e); const double tgen0 = getTime(); QList<QByteArray> frames (d->getReply<QList<QByteArray> >()); delete d; if (!frames.isEmpty()) { const unsigned long fbytes = frames.count()*frames.front().size(); Debug() << "Generating " << frames.count() << " frames (" << fbytes << " bytes) took " << getTime()-tgen0 << " secs"; sock.write((QString("BINARY DATA ") + QString::number(fbytes) + "\n").toUtf8()); const double t0 = getTime(); for (QList<QByteArray>::const_iterator it = frames.begin(); it != frames.end(); ++it) sock.write(*it); Debug() << "Sending " << numFrames << " frames (" << fbytes << " bytes) took " << getTime()-t0 << " secs"; return ""; } } } else if (cmd == "LIST") { QList<QString> lst = stimApp()->glWin()->plugins(); QString ret; QTextStream ts(&ret, QIODevice::WriteOnly|QIODevice::Truncate); for(QList<QString>::const_iterator it = lst.begin(); it != lst.end(); ++it) { ts << (*it) << "\n"; } ts.flush(); return ret; } else if (cmd == "GETFRAMEVARS") { QVector<double> data; int nrows, ncols; FrameVariables::readAllFromLast(data, &nrows, &ncols); sock.write(QString().sprintf("MATRIX %d %d\n", nrows, ncols).toUtf8()); if (data.size()) sock.write(QByteArray::fromRawData(reinterpret_cast<char *>(&data[0]),data.size()*sizeof(double))); return ""; } else if (cmd == "GETFRAMEVARNAMES") { QString ret = ""; QTextStream ts(&ret); QStringList hdr = FrameVariables::readHeaderFromLast(); int i = 0; for (QStringList::iterator it = hdr.begin(); it != hdr.end(); ++it, ++i) { ts << *it << "\n"; } ts.flush(); return ret; } else if (cmd == "GETSTATS") { QString theStr(""); QTextStream strm(&theStr, QIODevice::WriteOnly/*|QIODevice::Text*/); GetSetEvent *e = new GetHWFrameCountEvent(); GetSetData *d = e->d; stimApp()->postEvent(this, e); unsigned hwfc = d->getReply<unsigned>(); delete d; e = new IsConsoleHiddenEvent(); d = e->d; stimApp()->postEvent(this, e); bool isConsoleHidden = d->getReply<bool>(); delete d; StimPlugin *p = stimApp()->glWin()->runningPlugin(); strm.setRealNumberPrecision(3); strm.setRealNumberNotation(QTextStream::FixedNotation); strm << "runningPlugin = " << (p ? p->name() : "") << "\n" << "isPaused = " << (stimApp()->glWin()->isPaused() ? "1" : "0") << "\n" << "isInitialized = " << (p ? (p->isInitialized() ? 1 : 0) : 0) << "\n" << "isConsoleWindowHidden = " << (isConsoleHidden ? "1" : "0") << "\n" << "statusBarString = " << (p ? p->getSBString() : "") << "\n" << "currentTime = " << QDateTime::currentDateTime().toString() << "\n" << "beginTime = " << (p ? p->getBeginTime().toString() : "") << "\n" << "width = " << stimApp()->glWin()->width() << "\n" << "height = " << stimApp()->glWin()->height() << "\n" << "fpsAvg = " << (p ? p->getFps() : 0.) << "\n" << "fpsMin = " << (p ? p->getFpsMin() : 0.) << "\n" << "fpsMax = " << (p ? p->getFpsMax() : 0.) << "\n" << "fpsLast = " << (p ? p->getFpsCur() : 0.) << "\n" << "frameNum = " << (p ? p->getFrameNum() : -1) << "\n" << "hardwareFrameCount = " << hwfc << "\n" << "haAccurateHWFrameCount = " << (hasAccurateHWFrameCount() ? "1" : "0") << "\n" << "calibraredRefreshRate = " << stimApp()->refreshRate() << "\n" << "hwRefreshRate = " << getHWRefreshRate() << "\n" << "hasAccurateHWRefreshRate = " << (hasAccurateHWRefreshRate() ? 1 : 0) << "\n" << "numMissedFrames = " << (p ? p->getNumMissedFrames() : 0) << "\n"; QDateTime now(QDateTime::currentDateTime()), beginTime(p ? p->getBeginTime() : now); double secs = beginTime.secsTo(now), fskipsPerSec = 0.; if (p && secs > 0.) { fskipsPerSec = p->getNumMissedFrames() / secs; } strm << "missedFramesPerSec = " << fskipsPerSec << "\n" << "saveDirectory = " << stimApp()->outputDirectory() << "\n" << "pluginList = "; QList<QString> plugins = stimApp()->glWin()->plugins(); for (QList<QString>::const_iterator it = plugins.begin(); it != plugins.end(); ++it) { if (it != plugins.begin()) strm << ", "; strm << *it; } strm << "\n" << "programUptime = " << getTime() << "\n" << "nProcessors = " << getNProcessors() << "\n" << "hostName = " << getHostName() << "\n" << "uptime = " << getUpTime() << "\n"; strm.flush(); return theStr; } else if (cmd == "GETPARAMS" && toks.size()) { QString pluginName = toks.join(" "); StimPlugin *p; if ( (p = stimApp()->glWin()->pluginFind(pluginName)) ) { return p->getParams().toString(); } } else if (cmd == "GETPARAMHISTORY" && toks.size()) { QString pluginName = toks.join(" "); StimPlugin *p; if ( (p = stimApp()->glWin()->pluginFind(pluginName)) ) { return p->paramHistoryToString() + "\n"; } } else if (cmd == "SETPARAMHISTORY" && toks.size()) { QString pluginName = toks.join(" "); StimPlugin *p = stimApp()->glWin()->pluginFind(pluginName); if (!p) { Error() << "SETPARAMHISTORY issued on a non-existant plugin"; } else if (stimApp()->glWin()->runningPlugin() == p) { Error() << "SETPARAMHISTORY cannot be issued on a plugin that is running"; } else { Debug() << "Sending: READY"; sock.write("READY\n"); QString paramstr (""); QTextStream paramts(¶mstr, QIODevice::WriteOnly/*|QIODevice::Text*/); QString line; while ( sock.canReadLine() || sock.waitForReadyRead() ) { line = sock.readLine().trimmed(); if (!line.length()) break; Debug() << "Got Line: " << line; paramts << line << "\n"; } paramts.flush(); p->setPendingParamHistoryFromString(paramstr); p->setSaveParamHistoryOnStopOverride(true); // also tell plugin to save this param history, since it came from an external source return ""; } } else if (cmd == "NUMPARAMSQUEUED" && toks.size()) { QString pluginName = toks.join(" "); StimPlugin *p = stimApp()->glWin()->pluginFind(pluginName); if (!p) { Error() << "NUMPARAMSQUEUED issued on a non-existant plugin"; } else { return QString::number(p->pendingParamsHistorySize()); } } else if (cmd == "SETPARAMQUEUE") { QString pluginName = toks.join(" "); StimPlugin *p = stimApp()->glWin()->pluginFind(pluginName); if (!p) { Error() << "SETPARAMQUEUE issued on a non-existant plugin"; } else if (stimApp()->glWin()->runningPlugin() == p) { Error() << "SETPARAMQUEUE cannot be issued on a plugin that is running"; } else { Debug() << "Sending: READY"; sock.write("READY\n"); QString paramstr (""); QTextStream paramts(¶mstr, QIODevice::WriteOnly/*|QIODevice::Text*/); QString line; while ( sock.canReadLine() || sock.waitForReadyRead() ) { line = sock.readLine().trimmed(); if (!line.length()) break; Debug() << "Got Line: " << line; paramts << line << "\n"; } paramts.flush(); if (p->enqueueParamsForPendingParamsHistoryFromString(paramstr)) { p->setSaveParamHistoryOnStopOverride(false); // also tell plugin to NOT save this param history, since presumably it can be generated again from calling client code.. return ""; } else { Error() << "SETPARAMQUEUE failed to enqueue params from specified param-queue"; } } } else if (cmd == "SETPARAMS" && toks.size()) { QString pluginName = toks.join(" "); StimPlugin *p; if ( (p = stimApp()->glWin()->pluginFind(pluginName)) ) { Debug() << "Sending: READY"; sock.write("READY\n"); QString paramstr (""); QTextStream paramts(¶mstr, QIODevice::WriteOnly/*|QIODevice::Text*/); QString line; while ( sock.canReadLine() || sock.waitForReadyRead() ) { line = sock.readLine().trimmed(); if (!line.length()) break; Debug() << "Got Line: " << line; paramts << line << "\n"; } paramts.flush(); p->setParams(paramstr, p == stimApp()->glWin()->runningPlugin()); return ""; } else if (!p) { Error() << "SETPARAMS issued on a non-existant plugin"; } } else if (cmd == "RUNNING") { StimPlugin *p = stimApp()->glWin()->runningPlugin(); if (p) { return p->name(); } return ""; } else if (cmd == "ISPAUSED") { return QString::number(stimApp()->glWin()->isPaused()); } else if (cmd == "ISINITIALIZED") { StimPlugin *p = stimApp()->glWin()->runningPlugin(); if (p) { return QString::number(p->isInitialized()); } return "0"; } else if (cmd == "PAUSE") { if (!stimApp()->glWin()->isPaused()) stimApp()->glWin()->pauseUnpause(); return ""; } else if (cmd == "UNPAUSE") { if (stimApp()->glWin()->isPaused()) stimApp()->glWin()->pauseUnpause(); return ""; } else if (cmd == "ISCONSOLEHIDDEN") { GetSetEvent *e = new IsConsoleHiddenEvent; GetSetData *d = e->d; stimApp()->postEvent(this, e); QString ret = QString::number(int(d->getReply<bool>())); delete d; return ret; } else if (cmd == "CONSOLEHIDE") { stimApp()->postEvent(this, new ConsoleHideEvent()); return ""; } else if (cmd == "CONSOLEUNHIDE") { stimApp()->postEvent(this, new ConsoleUnHideEvent()); return ""; } else if (cmd == "ISVSYNCDISABLED") { return QString::number(stimApp()->isVSyncDisabled() ? 1 : 0); } else if (cmd == "SETVSYNCDISABLED") { const bool disabled = toks.join("").toInt(); stimApp()->postEvent(this, new SetVSyncDisabledEvent(disabled)); return ""; } else if (cmd == "START" && toks.size()) { // this commands needs to be executed in the main thread // to avoid race conditions and also to have a valid opengl context QString pluginName = toks.front(); bool startUnpaused = toks.size() > 1 && toks[1].toInt(); if ( (stimApp()->glWin()->pluginFind(pluginName)) ) { stimApp()->postEvent(this, new StartStopPluginEvent(pluginName, startUnpaused)); return ""; } } else if (cmd == "STOP") { // this commands needs to be executed in the main thread // to avoid race conditions and also to have a valid opengl context bool doSave = toks.join("").toInt(); if (stimApp()->glWin()->runningPlugin()) stimApp()->postEvent(this, new StartStopPluginEvent(doSave)); return ""; } else if (cmd == "GETSAVEDIR") { return stimApp()->outputDirectory(); } else if (cmd == "SETSAVEDIR") { QString dir = toks.join(" "); return stimApp()->setOutputDirectory(dir) ? QString("") : QString::null; } else if (cmd == "GETVERSION") { return VERSION_STR; } else if (cmd == "BYE") { sock.close(); } // add more cmds here return QString::null; }
void ApiServer::clientProcessCommands() { API_DEBUG_OUT << Q_FUNC_INFO << "ApiServer thread id:" << this->thread()->currentThreadId(); QTcpSocket *client = dynamic_cast<QTcpSocket*>(sender()); while (m_clients.contains(client) && client->canReadLine()) { QByteArray cmdBuffer = client->readLine().trimmed(); API_DEBUG_OUT << cmdBuffer; QString result = CmdUnknown; if (cmdBuffer.isEmpty()) { // Ignore empty lines return; } else if (cmdBuffer == CmdExit) { writeData(client, "Goodbye!\r\n"); if (m_clients.contains(client)) client->close(); return; } else if (cmdBuffer == CmdHelp) { writeData(client, m_helpMessage); return; } else if (cmdBuffer == CmdHelpShort) { writeData(client, m_shortHelpMessage); return; } else if (cmdBuffer.startsWith(CmdApiKey)) { API_DEBUG_OUT << CmdApiKey; if (m_isAuthEnabled) { cmdBuffer.remove(0, cmdBuffer.indexOf(':') + 1); API_DEBUG_OUT << QString(cmdBuffer); if (cmdBuffer == m_apiAuthKey) { API_DEBUG_OUT << CmdApiKey << "OK"; m_clients[client].isAuthorized = true; result = CmdApiKeyResult_Ok; } else { API_DEBUG_OUT << CmdApiKey << "Api key is not valid:" << QString(cmdBuffer); m_clients[client].isAuthorized = false; result = CmdApiKeyResult_Fail; } } else { API_DEBUG_OUT << CmdApiKey << "Authorization is disabled, return ok;"; result = CmdApiKeyResult_Ok; } writeData(client, result); return; } if (m_isAuthEnabled && m_clients[client].isAuthorized == false) { writeData(client, CmdApiCheck_AuthRequired); return; } // We are working only with authorized clients! if (cmdBuffer == CmdGetStatus) { API_DEBUG_OUT << CmdGetStatus; if (m_isRequestBacklightStatusDone) { m_isRequestBacklightStatusDone = false; m_backlightStatusResult = Backlight::StatusUnknown; emit requestBacklightStatus(); // Wait signal from SettingsWindow with status of backlight // or if timeout -- result will be unknown m_time.restart(); while (m_isRequestBacklightStatusDone == false && m_time.elapsed() < SignalWaitTimeoutMs) { QApplication::processEvents(QEventLoop::WaitForMoreEvents, SignalWaitTimeoutMs); } if (m_isRequestBacklightStatusDone) { switch (m_backlightStatusResult) { case Backlight::StatusOn: result = CmdResultStatus_On; break; case Backlight::StatusOff: result = CmdResultStatus_Off; break; case Backlight::StatusDeviceError: result = CmdResultStatus_DeviceError; break; default: result = CmdResultStatus_Unknown; break; } } else { m_isRequestBacklightStatusDone = true; result = CmdResultStatus_Unknown; qWarning() << Q_FUNC_INFO << "Timeout waiting resultBacklightStatus() signal from SettingsWindow"; } } } else if (cmdBuffer == CmdGetStatusAPI) { API_DEBUG_OUT << CmdGetStatusAPI; if (m_lockedClient != NULL) result = CmdResultStatusAPI_Busy; else result = CmdResultStatusAPI_Idle; } else if (cmdBuffer == CmdGetProfiles) { API_DEBUG_OUT << CmdGetProfiles; QStringList profiles = Settings::findAllProfiles(); result = ApiServer::CmdResultProfiles; for (int i = 0; i < profiles.count(); i++) result += profiles[i] + ";"; result += "\r\n"; } else if (cmdBuffer == CmdGetProfile) { API_DEBUG_OUT << CmdGetProfile; result = CmdResultProfile + Settings::getCurrentProfileName() + "\r\n"; } else if (cmdBuffer == CmdGetCountLeds) { API_DEBUG_OUT << CmdGetCountLeds; result = QString("%1%2\r\n").arg(CmdResultCountLeds).arg(Settings::getNumberOfLeds(Settings::getConnectedDevice())); } else if (cmdBuffer == CmdLock) { API_DEBUG_OUT << CmdLock; if (m_lockedClient == NULL) { m_lockedClient = client; emit updateDeviceLockStatus(Api::DeviceLocked); result = CmdResultLock_Success; } else { if (m_lockedClient == client) { result = CmdResultLock_Success; } else { result = CmdResultLock_Busy; } } } else if (cmdBuffer == CmdUnlock) { API_DEBUG_OUT << CmdUnlock; if (m_lockedClient == NULL) { result = CmdResultUnlock_NotLocked; } else { if (m_lockedClient == client) { m_lockedClient = NULL; emit updateDeviceLockStatus(Api::DeviceUnlocked); } result = CmdResultUnlock_Success; } } else if (cmdBuffer.startsWith(CmdSetColor)) { API_DEBUG_OUT << CmdSetColor; if (m_lockedClient == client) { cmdBuffer.remove(0, cmdBuffer.indexOf(':') + 1); API_DEBUG_OUT << QString(cmdBuffer); if (m_isTaskSetColorDone) { m_isTaskSetColorDone = false; m_isTaskSetColorParseSuccess = false; // Start task emit startParseSetColorTask(cmdBuffer); // Wait signal from m_apiSetColorTask with success or fail result of parsing buffer. // After SignalWaitTimeoutMs milliseconds, the cycle of waiting will end and the // variable m_isTaskSetColorDone will be reset to 'true' state. // Also in cycle we process requests from over clients, if this request is setcolor when // it will be ignored because of m_isTaskSetColorDone == false m_time.restart(); while (m_isTaskSetColorDone == false && m_time.elapsed() < SignalWaitTimeoutMs) { QApplication::processEvents(QEventLoop::WaitForMoreEvents, SignalWaitTimeoutMs); } if (m_isTaskSetColorDone) { if (m_isTaskSetColorParseSuccess) result = CmdSetResult_Ok; else result = CmdSetResult_Error; } else { m_isTaskSetColorDone = true; // cmd setcolor is available result = CmdSetResult_Error; qWarning() << Q_FUNC_INFO << "Timeout waiting taskIsSuccess() signal from m_apiSetColorTask"; } } else { qWarning() << Q_FUNC_INFO << "Task setcolor is not completed (you should increase the delay to not skip commands), skip setcolor."; } } else if (m_lockedClient == NULL) { result = CmdSetResult_NotLocked; } else // m_lockedClient != client { result = CmdSetResult_Busy; } } else if (cmdBuffer.startsWith(CmdSetGamma)) { API_DEBUG_OUT << CmdSetGamma; if (m_lockedClient == client) { cmdBuffer.remove(0, cmdBuffer.indexOf(':') + 1); API_DEBUG_OUT << QString(cmdBuffer); // Gamma can contain max five chars (0.00 -- 10.00) if (cmdBuffer.length() > 5) { API_DEBUG_OUT << CmdSetGamma << "Error (gamma max 5 chars)"; result = CmdSetResult_Error; } else { // Try to convert gamma string to double bool ok = false; double gamma = QString(cmdBuffer).toDouble(&ok); if (ok) { if (gamma >= Profile::Device::GammaMin && gamma <= Profile::Device::GammaMax) { API_DEBUG_OUT << CmdSetGamma << "OK:" << gamma; emit updateGamma(gamma); result = CmdSetResult_Ok; } else { API_DEBUG_OUT << CmdSetGamma << "Error (max min test fail):" << gamma; result = CmdSetResult_Error; } } else { API_DEBUG_OUT << CmdSetGamma << "Error (convert fail):" << gamma; result = CmdSetResult_Error; } } } else if (m_lockedClient == NULL) { result = CmdSetResult_NotLocked; } else // m_lockedClient != client { result = CmdSetResult_Busy; } } else if (cmdBuffer.startsWith(CmdSetBrightness)) { API_DEBUG_OUT << CmdSetBrightness; if (m_lockedClient == client) { cmdBuffer.remove(0, cmdBuffer.indexOf(':') + 1); API_DEBUG_OUT << QString(cmdBuffer); // Brightness can contain max three chars (0 -- 100) if (cmdBuffer.length() > 3) { API_DEBUG_OUT << CmdSetBrightness << "Error (smooth max 3 chars)"; result = CmdSetResult_Error; } else { // Try to convert smooth string to int bool ok = false; int brightness = QString(cmdBuffer).toInt(&ok); if (ok) { if (brightness >= Profile::Device::BrightnessMin && brightness <= Profile::Device::BrightnessMax) { API_DEBUG_OUT << CmdSetBrightness << "OK:" << brightness; emit updateBrightness(brightness); result = CmdSetResult_Ok; } else { API_DEBUG_OUT << CmdSetBrightness << "Error (max min test fail):" << brightness; result = CmdSetResult_Error; } } else { API_DEBUG_OUT << CmdSetBrightness << "Error (convert fail):" << brightness; result = CmdSetResult_Error; } } } else if (m_lockedClient == NULL) { result = CmdSetResult_NotLocked; } else // m_lockedClient != client { result = CmdSetResult_Busy; } } else if (cmdBuffer.startsWith(CmdSetSmooth)) { API_DEBUG_OUT << CmdSetSmooth; if (m_lockedClient == client) { cmdBuffer.remove(0, cmdBuffer.indexOf(':') + 1); API_DEBUG_OUT << QString(cmdBuffer); // Smooth can contain max three chars (0 -- 255) if (cmdBuffer.length() > 3) { API_DEBUG_OUT << CmdSetSmooth << "Error (smooth max 3 chars)"; result = CmdSetResult_Error; } else { // Try to convert smooth string to int bool ok = false; int smooth = QString(cmdBuffer).toInt(&ok); if (ok) { if (smooth >= Profile::Device::SmoothMin && smooth <= Profile::Device::SmoothMax) { API_DEBUG_OUT << CmdSetSmooth << "OK:" << smooth; emit updateSmooth(smooth); result = CmdSetResult_Ok; } else { API_DEBUG_OUT << CmdSetSmooth << "Error (max min test fail):" << smooth; result = CmdSetResult_Error; } } else { API_DEBUG_OUT << CmdSetSmooth << "Error (convert fail):" << smooth; result = CmdSetResult_Error; } } } else if (m_lockedClient == NULL) { result = CmdSetResult_NotLocked; } else // m_lockedClient != client { result = CmdSetResult_Busy; } } else if (cmdBuffer.startsWith(CmdSetProfile)) { API_DEBUG_OUT << CmdSetProfile; if (m_lockedClient == client) { cmdBuffer.remove(0, cmdBuffer.indexOf(':') + 1); API_DEBUG_OUT << QString(cmdBuffer); QString setProfileName = QString(cmdBuffer); QStringList profiles = Settings::findAllProfiles(); if (profiles.contains(setProfileName)) { API_DEBUG_OUT << CmdSetProfile << "OK:" << setProfileName; emit updateProfile(setProfileName); result = CmdSetResult_Ok; } else { API_DEBUG_OUT << CmdSetProfile << "Error (profile not found):" << setProfileName; result = CmdSetResult_Error; } } else if (m_lockedClient == NULL) { result = CmdSetResult_NotLocked; } else // m_lockedClient != client { result = CmdSetResult_Busy; } } else if (cmdBuffer.startsWith(CmdSetStatus)) { API_DEBUG_OUT << CmdSetStatus; if (m_lockedClient == client) { cmdBuffer.remove(0, cmdBuffer.indexOf(':') + 1); API_DEBUG_OUT << QString(cmdBuffer); Backlight::Status status = Backlight::StatusUnknown; if (cmdBuffer == CmdSetStatus_On) status = Backlight::StatusOn; else if (cmdBuffer == CmdSetStatus_Off) status = Backlight::StatusOff; if (status != Backlight::StatusUnknown) { API_DEBUG_OUT << CmdSetStatus << "OK:" << status; emit updateStatus(status); result = CmdSetResult_Ok; } else { API_DEBUG_OUT << CmdSetStatus << "Error (status not recognized):" << status; result = CmdSetResult_Error; } } else if (m_lockedClient == NULL) { result = CmdSetResult_NotLocked; } else // m_lockedClient != client { result = CmdSetResult_Busy; } } else { qWarning() << Q_FUNC_INFO << CmdUnknown << cmdBuffer; } writeData(client, result); } }
void AndroidRetracer::run() { m_androidUtils.reloadAdb(); QString errorStr; bool setupRet; QMetaObject::invokeMethod(this, "setup", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, setupRet), Q_ARG(QString *, &errorStr)); if (!setupRet) { emit finished(errorStr); return; } if (!m_androidUtils.runAdb(QStringList() << _("shell") << _("am") << _("start") << _("-n") << packageName + activityName)) { emit finished(tr("Can't start apitrace application")); return; } QByteArray which; if (!m_androidUtils.runAdb(QStringList() << _("shell") << _("readlink") << _("$(which ps)") , &which)) { emit finished(tr("Can't start adb")); return; } bool isBusyBox = which.startsWith("busybox"); QStringList psArgs; psArgs << _("shell") << _("ps"); if (isBusyBox) psArgs << _("-w"); qint64 processPID; bool wasStarted = false; QTime startTime; startTime.start(); QTcpSocket stdoutSocket; QTcpSocket stderrSocket; ImageHash thumbnails; QVariantMap parsedJson; trace::Profile* profile = isProfiling() ? new trace::Profile() : NULL; QList<ApiTraceError> errors; QRegExp regexp("(^\\d+): +(\\b\\w+\\b): ([^\\r\\n]+)[\\r\\n]*$"); QString msg = QLatin1String("Replay finished!"); QByteArray ubjsonBuffer; QByteArray outputBuffer; bool keepGoing = true; while(keepGoing) { if (!wasStarted || startTime.elapsed() > 1000) { QByteArray psOut; m_androidUtils.runAdb(psArgs, &psOut); processPID = extractPid(psOut); if (wasStarted) startTime.restart(); } if (processPID == -1) { if (wasStarted) { break; } else { if (startTime.elapsed() > 3000) { // wait 3 seconds to start emit finished(tr("Unable to start retrace on device.")); return; } } msleep(100); continue; } // we have a valid pid, it means the application started if (!wasStarted) { // connect the sockets int tries = 0; do { stdoutSocket.connectToHost(QHostAddress::LocalHost, m_stdoutPort); } while (!stdoutSocket.waitForConnected(100) && ++tries < 10); if (stdoutSocket.state() != QAbstractSocket::ConnectedState) { emit finished(tr("Can't connect to stdout socket.")); return; } // Android doesn't suport GPU and PPD profiling (at leats not on my devices) //setProfiling(false, isProfilingCpu(), false); QString args = (retraceArguments() << m_androdiFileName).join(" ") + _("\n"); stdoutSocket.write(args.toUtf8()); if (!stdoutSocket.waitForBytesWritten()) { emit finished(tr("Can't send params.")); return; } stderrSocket.connectToHost(QHostAddress::LocalHost, m_stderrPort); stderrSocket.waitForConnected(100); if (stderrSocket.state() != QAbstractSocket::ConnectedState) { emit finished(tr("Can't connect to stderr socket.")); return; } wasStarted = true; } // We are going to read both channels at the same time // read stdout channel if (stdoutSocket.waitForReadyRead(100)) { if (captureState()) ubjsonBuffer.append(stdoutSocket.readAll()); else if (captureThumbnails()) { // read one image image::PNMInfo info; QByteArray header; int headerLines = 3; // assume no optional comment line for (int headerLine = 0; headerLine < headerLines; ++headerLine) { QByteArray line = readLine(stdoutSocket); if (line.isEmpty()) { keepGoing = false; break; } header += line; // if header actually contains optional comment line, ... if (headerLine == 1 && line[0] == '#') { ++headerLines; } } const char *headerEnd = image::readPNMHeader(header.constData(), header.size(), info); // if invalid PNM header was encountered, ... if (headerEnd == NULL || info.channelType != image::TYPE_UNORM8) { qDebug() << "error: invalid snapshot stream encountered"; keepGoing = false; break; } unsigned channels = info.channels; unsigned width = info.width; unsigned height = info.height; // qDebug() << "channels: " << channels << ", width: " << width << ", height: " << height"; QImage snapshot = QImage(width, height, channels == 1 ? QImage::Format_Mono : QImage::Format_RGB888); int rowBytes = channels * width; for (int y = 0; y < height; ++y) { unsigned char *scanLine = snapshot.scanLine(y); if (!read(stdoutSocket, (char *) scanLine, rowBytes)) { keepGoing = false; break; } } QImage thumb = thumbnail(snapshot); thumbnails.insert(info.commentNumber, thumb); } else if (isProfiling()) { QByteArray line = readLine(stdoutSocket); if (line.isEmpty()) { keepGoing = false; break; } line.append('\0'); trace::Profiler::parseLine(line.constData(), profile); } else { outputBuffer.append(stdoutSocket.readAll()); } } // read stderr channel if (stderrSocket.waitForReadyRead(5) && stderrSocket.canReadLine()) { QString line = stderrSocket.readLine(); if (regexp.indexIn(line) != -1) { ApiTraceError error; error.callIndex = regexp.cap(1).toInt(); error.type = regexp.cap(2); error.message = regexp.cap(3); errors.append(error); } else if (!errors.isEmpty()) { // Probably a multiligne message ApiTraceError &previous = errors.last(); if (line.endsWith("\n")) { line.chop(1); } previous.message.append('\n'); previous.message.append(line); } } } if (outputBuffer.size() < 80) msg = outputBuffer; if (captureState()) { QBuffer io(&ubjsonBuffer); io.open(QIODevice::ReadOnly); parsedJson = decodeUBJSONObject(&io).toMap(); ApiTraceState *state = new ApiTraceState(parsedJson); emit foundState(state); } if (captureThumbnails() && !thumbnails.isEmpty()) { emit foundThumbnails(thumbnails); } if (isProfiling() && profile) { emit foundProfile(profile); } if (!errors.isEmpty()) { emit retraceErrors(errors); } emit finished(msg); }
void HttpSocket::readClient() { if (terminated) { return; } QTcpSocket *socket = static_cast<QTcpSocket *>(sender()); if (!socket) { return; } if (socket->bytesAvailable() >= constMaxBuffer) { // Request too large, reject sendErrorResponse(socket, 400); socket->close(); DBUG << "Request too large"; return; } if (socket->canReadLine()) { QList<QByteArray> tokens = split(socket->readLine()); // QRegExp("[ \r\n][ \r\n]*")); if (tokens.length()>=2 && "GET"==tokens[0]) { QStringList params = QString(socket->readAll()).split(QRegExp("[\r\n][\r\n]*")); DBUG << "params" << params << "tokens" << tokens; QUrl url(QUrl::fromEncoded(tokens[1])); QUrlQuery q(url); bool ok=false; qint32 readBytesFrom=0; qint32 readBytesTo=0; getRange(params, readBytesFrom, readBytesTo); DBUG << "readBytesFrom" << readBytesFrom << "readBytesTo" << readBytesTo; if (q.hasQueryItem("cantata")) { Song song=HttpServer::self()->decodeUrl(url); if (!isCantataStream(song.file)) { sendErrorResponse(socket, 400); socket->close(); DBUG << "Not cantata stream file"; return; } if (song.isCdda()) { #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND QStringList parts=song.file.split("/", QString::SkipEmptyParts); if (parts.length()>=3) { QString dev=QLatin1Char('/')+parts.at(1)+QLatin1Char('/')+parts.at(2); CdParanoia cdparanoia(dev, false, false, true, Settings::self()->paranoiaOffset()); if (cdparanoia) { int firstSector = cdparanoia.firstSectorOfTrack(song.id); int lastSector = cdparanoia.lastSectorOfTrack(song.id); qint32 totalSize = ((lastSector-firstSector)+1)*CD_FRAMESIZE_RAW; int count = 0; bool writeHeader=0==readBytesFrom; // Only write header if we are not seeking... // int bytesToDiscard = 0; // Number of bytes to discard in first read sector due to range request in HTTP header // if (readBytesFrom>=ExtractJob::constWavHeaderSize) { // readBytesFrom-=ExtractJob::constWavHeaderSize; // } // if (readBytesFrom>0) { // int sectorsToSeek=readBytesFrom/CD_FRAMESIZE_RAW; // firstSector+=sectorsToSeek; // bytesToDiscard=readBytesFrom-(sectorsToSeek*CD_FRAMESIZE_RAW); // } cdparanoia.seek(firstSector, SEEK_SET); ok=true; writeMimeType(QLatin1String("audio/x-wav"), socket, readBytesFrom, totalSize+ExtractJob::constWavHeaderSize, false); if (writeHeader) { ExtractJob::writeWavHeader(*socket, totalSize); } bool stop=false; while (!terminated && (firstSector+count) <= lastSector && !stop) { qint16 *buf = cdparanoia.read(); if (!buf) { break; } char *buffer=(char *)buf; qint32 writePos=0; qint32 toWrite=CD_FRAMESIZE_RAW; // if (bytesToDiscard>0) { // int toSkip=qMin(toWrite, bytesToDiscard); // writePos=toSkip; // toWrite-=toSkip; // bytesToDiscard-=toSkip; // } if (toWrite>0 && !write(socket, &buffer[writePos], toWrite, stop)) { break; } count++; } } } #endif } else if (!song.file.isEmpty()) { #ifdef Q_OS_WIN if (tokens[1].startsWith("//") && !song.file.startsWith(QLatin1String("//")) && !QFile::exists(song.file)) { QString share=QLatin1String("//")+url.host()+song.file; if (QFile::exists(share)) { song.file=share; DBUG << "fixed share-path" << song.file; } } #endif QFile f(song.file); if (f.open(QIODevice::ReadOnly)) { qint32 totalBytes = f.size(); writeMimeType(detectMimeType(song.file), socket, readBytesFrom, totalBytes, true); ok=true; qint32 readPos = 0; qint32 bytesRead = 0; if (0!=readBytesFrom) { if (!f.seek(readBytesFrom)) { ok=false; } bytesRead+=readBytesFrom; } if (0!=readBytesTo && readBytesTo>readBytesFrom && readBytesTo!=totalBytes) { totalBytes-=(totalBytes-readBytesTo); } if (ok) { static const int constChunkSize=32768; char buffer[constChunkSize]; bool stop=false; do { bytesRead = f.read(buffer, constChunkSize); readPos+=bytesRead; if (!write(socket, buffer, bytesRead, stop) || f.atEnd()) { break; } } while (readPos<totalBytes && !stop && !terminated); } } else { DBUG << "Failed to open" << song.file; } } } if (!ok) { sendErrorResponse(socket, 404); } socket->close(); if (QTcpSocket::UnconnectedState==socket->state()) { socket->deleteLater(); } } else { // Bad Request sendErrorResponse(socket, 400); socket->close(); DBUG << "Bad Request"; return; } } }
void QWsServer::dataReceived() { QTcpSocket * tcpSocket = qobject_cast<QTcpSocket*>( sender() ); if (tcpSocket == 0) return; bool allHeadersFetched = false; const QLatin1String emptyLine("\r\n"); while ( tcpSocket->canReadLine() ) { QString line = tcpSocket->readLine(); if (line == emptyLine) { allHeadersFetched = true; break; } headerBuffer[ tcpSocket ].append(line); } if (!allHeadersFetched) return; QString request( headerBuffer[ tcpSocket ].join("") ); QRegExp regExp; regExp.setMinimal( true ); // Extract mandatory datas // Version regExp.setPattern( QWsServer::regExpVersionStr ); regExp.indexIn(request); QString versionStr = regExp.cap(1); EWebsocketVersion version; if ( ! versionStr.isEmpty() ) { version = (EWebsocketVersion)versionStr.toInt(); } else if ( tcpSocket->bytesAvailable() >= 8 ) { version = WS_V0; request.append( tcpSocket->read(8) ); } else { version = WS_VUnknow; } // Resource name regExp.setPattern( QWsServer::regExpResourceNameStr ); regExp.indexIn(request); QString resourceName = regExp.cap(1); // Host (address & port) regExp.setPattern( QWsServer::regExpHostStr ); regExp.indexIn(request); QString host = regExp.cap(1); QStringList hostTmp = host.split(':'); QString hostAddress = hostTmp[0]; QString hostPort; if ( hostTmp.size() > 1 ) hostPort = hostTmp.last(); // fix for IPv6 // Key QString key, key1, key2, key3; if ( version >= WS_V4 ) { regExp.setPattern( QWsServer::regExpKeyStr ); regExp.indexIn(request); key = regExp.cap(1); } else { regExp.setPattern( QWsServer::regExpKey1Str ); regExp.indexIn(request); key1 = regExp.cap(1); regExp.setPattern( QWsServer::regExpKey2Str ); regExp.indexIn(request); key2 = regExp.cap(1); regExp.setPattern( QWsServer::regExpKey3Str ); regExp.indexIn(request); key3 = regExp.cap(1); } //////////////////////////////////////////////////////////////////// // If the mandatory fields are not specified, we abord the connection to the Websocket server if ( version == WS_VUnknow || resourceName.isEmpty() || hostAddress.isEmpty() || ( key.isEmpty() && ( key1.isEmpty() || key2.isEmpty() || key3.isEmpty() ) ) ) { // Send bad request response QString response = QWsServer::composeBadRequestResponse( QList<EWebsocketVersion>() << WS_V6 << WS_V7 << WS_V8 << WS_V13 ); tcpSocket->write( response.toUtf8() ); tcpSocket->flush(); return; } //////////////////////////////////////////////////////////////////// // Extract optional datas // Origin regExp.setPattern( QWsServer::regExpOriginStr ); if ( regExp.indexIn(request) == -1 ) { regExp.setPattern( QWsServer::regExpOrigin2Str ); regExp.indexIn(request); } QString origin = regExp.cap(1); // Protocol regExp.setPattern( QWsServer::regExpProtocolStr ); regExp.indexIn(request); QString protocol = regExp.cap(1); // Extensions regExp.setPattern( QWsServer::regExpExtensionsStr ); regExp.indexIn(request); QString extensions = regExp.cap(1); //////////////////////////////////////////////////////////////////// // Compose opening handshake response QString response; if ( version >= WS_V6 ) { QString accept = computeAcceptV4( key ); response = QWsServer::composeOpeningHandshakeResponseV6( accept, protocol ); } else if ( version >= WS_V4 ) { QString accept = computeAcceptV4( key ); QString nonce = generateNonce(); response = QWsServer::composeOpeningHandshakeResponseV4( accept, nonce, protocol ); } else { QString accept = computeAcceptV0( key1, key2, key3 ); response = QWsServer::composeOpeningHandshakeResponseV0( accept, origin, hostAddress, hostPort, resourceName , protocol ); } // Handshake OK, disconnect readyRead disconnect( tcpSocket, SIGNAL(readyRead()), this, SLOT(dataReceived()) ); // Send opening handshake response if ( version == WS_V0 ) tcpSocket->write( response.toLatin1() ); else tcpSocket->write( response.toUtf8() ); tcpSocket->flush(); QWsSocket * wsSocket = new QWsSocket( this, tcpSocket, version ); wsSocket->setResourceName( resourceName ); wsSocket->setHost( host ); wsSocket->setHostAddress( hostAddress ); wsSocket->setHostPort( hostPort.toInt() ); wsSocket->setOrigin( origin ); wsSocket->setProtocol( protocol ); wsSocket->setExtensions( extensions ); wsSocket->serverSideSocket = true; // ORIGINAL CODE //int socketDescriptor = tcpSocket->socketDescriptor(); //incomingConnection( socketDescriptor ); // CHANGED CODE FOR LINUX COMPATIBILITY addPendingConnection( wsSocket ); emit newConnection(); }
void CHttpServer::readClient(void) { QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender()); CTcpRequestEvent* event_ = new CTcpRequestEvent(); CHttpHeader header; try { if(isPaused()) throw("output disabled"); if(socket->bytesAvailable() <= 0 && socket->bytesAvailable() >= (1 << 20)) // hard limit of 1MB input throw("Illegal request size."); if(!socket->canReadLine()) throw("Invalid request"); if(!header.read(socket)) return; switch(hashed_t(header.method())) { // HTTP 1.0 case "GET"_hash: if(header.path() == "/favicon.ico") { static QByteArray favicon; if(favicon.isEmpty()) favicon = CFileCache::get(1); socket->write("HTTP/1.1 200 OK\r\n" "Content-Type: image/png\r\n" "Connection: close\r\n\r\n"); socket->write(favicon); // favicon throw("favicon"); } if(header.path() == "/") { socket->write("HTTP/1.1 301 Moved Permanently\r\n" "Location: /Main_Page\r\n"); throw("forward to Main_Page"); } if(header.path().contains("%20")) { QByteArray path = header.path(); path = path.replace("%20", "_"); socket->write("HTTP/1.1 301 Moved Permanently\r\nLocation: "); socket->write(path); socket->write("\r\n"); throw("forward to proper page name"); } break; case "HEAD"_hash: break; case "POST"_hash: break; // HTTP 1.1 case "OPTIONS"_hash: break; case "PUT"_hash: break; case "DELETE"_hash: break; case "TRACE"_hash: break; case "CONNECT"_hash: break; case "PATCH"_hash: break; // HTTP 2.x (?) case "MOVE"_hash: break; case "PURGE"_hash: break; case "REFRESH"_hash: break; // WebDAV // HTTP 1.1 case "PROPFIND"_hash: break; case "PROPPATCH"_hash: break; case "MKCOL"_hash: break; case "COPY"_hash: break; case "LOCK"_hash: break; case "UNLOCK"_hash: break; // HTTP 2.x case "VERSION-CONTROL"_hash: break; case "REPORT"_hash: break; case "CHECKIN"_hash: break; case "CHECKOUT"_hash: break; case "UNCHECKOUT"_hash: break; case "UPDATE"_hash: break; case "MKWORKSPACE"_hash: break; case "LABEL"_hash: break; case "MERGE"_hash: break; case "BASELINE-CONTROL"_hash: break; case "MKACTIVITY"_hash: break; case "BIND"_hash: break; case "SEARCH"_hash: break; default: qDebug() << "unknown header type"; break; } event_->setHeader(header); event_->setSocket(socket); QCoreApplication::postEvent(qApp, event_, Qt::RealTimeEventPriority); // set network request event QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::X11ExcludeTimers); // process the network request event QtServiceBase::instance()->logMessage("Wrote to client"); } catch(const char* error_message) { QtServiceBase::instance()->logMessage(error_message); } if(socket->isOpen()) socket->close(); if(socket->state() == QTcpSocket::UnconnectedState) { delete socket; QtServiceBase::instance()->logMessage("Connection closed"); } }