static HeadersMap parseHeaders(const QByteArray& headerData) { HeadersMap headersMap; QBuffer sourceBuffer; sourceBuffer.setData(headerData); sourceBuffer.open(QIODevice::ReadOnly); // The first line is special, it's the GET or POST line const QList<QByteArray> firstLine = sourceBuffer.readLine().split(' '); if (firstLine.count() < 3) { qDebug() << "Malformed HTTP request:" << firstLine; return headersMap; } const QByteArray request = firstLine[0]; const QByteArray path = firstLine[1]; const QByteArray httpVersion = firstLine[2]; if (request != "GET" && request != "POST") { qDebug() << "Unknown HTTP request:" << firstLine; return headersMap; } headersMap.insert("_path", path); headersMap.insert("_httpVersion", httpVersion); while (!sourceBuffer.atEnd()) { const QByteArray line = sourceBuffer.readLine(); const int pos = line.indexOf(':'); if (pos == -1) qDebug() << "Malformed HTTP header:" << line; const QByteArray header = line.left(pos); const QByteArray value = line.mid(pos+1).trimmed(); // remove space before and \r\n after //qDebug() << "HEADER" << header << "VALUE" << value; headersMap.insert(header, value); } return headersMap; }
static HeadersMap parseHeaders(const QByteArray& headerData) { HeadersMap headersMap; QBuffer sourceBuffer; sourceBuffer.setData(headerData); sourceBuffer.open(QIODevice::ReadOnly); // The first line is special, it's the GET or POST line const QList<QByteArray> firstLine = sourceBuffer.readLine().split(' '); if (firstLine.count() < 3) { qDebug() << "Malformed HTTP request:" << firstLine; return headersMap; } const QByteArray requestType = firstLine.at(0); const QByteArray path = QDir::cleanPath(QString::fromLatin1(firstLine.at(1).constData())).toLatin1(); const QByteArray httpVersion = firstLine.at(2); headersMap.insert("_requestType", requestType); headersMap.insert("_path", path); headersMap.insert("_httpVersion", httpVersion); while (!sourceBuffer.atEnd()) { const QByteArray line = sourceBuffer.readLine(); const int pos = line.indexOf(':'); if (pos == -1) qDebug() << "Malformed HTTP header:" << line; const QByteArray header = line.left(pos).toLower(); // RFC2616 section 4.2 "Field names are case-insensitive" const QByteArray value = line.mid(pos+1).trimmed(); // remove space before and \r\n after //qDebug() << "HEADER" << header << "VALUE" << value; headersMap.insert(header, value); } return headersMap; }
qint64 Request::writeData(const char* data, qint64 maxSize) { if(m_responseState == WaitingForResponseHeaders) { m_headerBuffer.append(data, maxSize); // We need to buffer the headers, so we can use the STATUS header appropriately QBuffer buffer; buffer.setData(m_headerBuffer); buffer.open(QIODevice::ReadOnly); buffer.seek(m_headerBufferPosition); while(buffer.canReadLine()) { const QByteArray line = buffer.readLine().trimmed(); if(line.isEmpty()) { Q_ASSERT(m_responseHeaders.contains("STATUS")); Q_ASSERT(m_requestHeaders.contains("SERVER_PROTOCOL")); m_responseState = WaitingForResponseBody; const QByteArray status = m_responseHeaders.take("STATUS"); m_socket->write(m_requestHeaders.value("SERVER_PROTOCOL")); m_socket->write(" ", 1); m_socket->write(status); m_socket->write("\r\n", 2); //qDebug() << Q_FUNC_INFO << m_requestHeaders << m_responseHeaders; for( HeaderMap::ConstIterator it = m_responseHeaders.constBegin(); it != m_responseHeaders.constEnd(); ++it ) { m_socket->write(it.key()); m_socket->write(": "); m_socket->write(it.value()); m_socket->write("\r\n"); } m_socket->write("\r\n"); m_socket->write(buffer.readAll()); buffer.close(); m_headerBuffer.clear(); return maxSize; } const int lengthOfName = line.indexOf(':'); const QByteArray name = line.left(lengthOfName); const QByteArray value = line.mid(lengthOfName + 2); // ": " after the name == 2 chars m_responseHeaders.insertMulti(name, value); } m_headerBufferPosition = buffer.pos(); buffer.close(); return maxSize; } Q_ASSERT(m_responseState == WaitingForResponseBody); return m_socket->write(data, maxSize); }
size_t callback_read_file(void *ptr, size_t size, size_t nmemb, void *userp) { // qDebug()<<__FILE__<<__LINE__<<__FUNCTION__<<size<<nmemb<<userp; size_t tlen = size * nmemb, rlen = 0; QBuffer strbuf; QByteArray line; int n = 0, wlen = 0; CurlFtp *ftp = static_cast<CurlFtp*>(userp); QLocalSocket *router = ftp->getDataSock2(); strbuf.setData((const char*)ptr, tlen); strbuf.open(QBuffer::ReadOnly); // Q_ASSERT(strbuf.canReadLine()); // ??? rlen = 0; while (!strbuf.atEnd()) { if (strbuf.canReadLine()) { line = strbuf.readLine(); } else { line = strbuf.readAll(); } rlen += line.length(); wlen = router->write(line); // qDebug()<<"Line: "<<n++<<line.length()<<wlen; // fprintf(stdout, "%s", "."); // fflush(stdout); Q_ASSERT(line.length() == wlen); // break; } strbuf.close(); router->flush(); // qDebug()<<"can rw:"<<router->isReadable()<<router->isWritable()<<router->isOpen(); // fprintf(stdout, "route read file:. %p %d %s", router, router->bytesAvailable(), "\n"); fflush(stdout); return rlen; return 0; }
// 给多少数据就要读取多少,读取不完不行。 size_t callback_read_dir(void *ptr, size_t size, size_t nmemb, void *userp) { qDebug()<<__FILE__<<__LINE__<<__FUNCTION__<<size<<nmemb<<userp; size_t tlen = size * nmemb, rlen = 0; QBuffer strbuf; QByteArray line; int n = 0; strbuf.setData((const char*)ptr, tlen); strbuf.open(QBuffer::ReadOnly); Q_ASSERT(strbuf.canReadLine()); // ??? rlen = 0; while (!strbuf.atEnd()) { line = strbuf.readLine(); rlen += line.length(); qDebug()<<"Line: "<<n++<<line; // break; } strbuf.close(); return rlen; }
//-------------------------------------------------------------------- void tst_QIODevice::unget() { #if defined(Q_OS_WINCE) && defined(WINCE_EMULATOR_TEST) QSKIP("Networking tests in a WinCE emulator are unstable", SkipAll); #endif QBuffer buffer; buffer.open(QBuffer::ReadWrite); buffer.write("ZXCV"); buffer.seek(0); QCOMPARE(buffer.read(4), QByteArray("ZXCV")); QCOMPARE(buffer.pos(), qint64(4)); buffer.ungetChar('a'); buffer.ungetChar('b'); buffer.ungetChar('c'); buffer.ungetChar('d'); QCOMPARE(buffer.pos(), qint64(0)); char buf[6]; QCOMPARE(buffer.readLine(buf, 5), qint64(4)); QCOMPARE(buffer.pos(), qint64(4)); QCOMPARE(static_cast<const char*>(buf), "dcba"); buffer.ungetChar('a'); buffer.ungetChar('b'); buffer.ungetChar('c'); buffer.ungetChar('d'); QCOMPARE(buffer.pos(), qint64(0)); for (int i = 0; i < 5; ++i) { buf[0] = '@'; buf[1] = '@'; QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine: Called with maxSize < 2"); QCOMPARE(buffer.readLine(buf, 1), qint64(-1)); QCOMPARE(buffer.readLine(buf, 2), qint64(i < 4 ? 1 : -1)); switch (i) { case 0: QCOMPARE(buf[0], 'd'); break; case 1: QCOMPARE(buf[0], 'c'); break; case 2: QCOMPARE(buf[0], 'b'); break; case 3: QCOMPARE(buf[0], 'a'); break; case 4: QCOMPARE(buf[0], '\0'); break; } QCOMPARE(buf[1], i < 4 ? '\0' : '@'); } buffer.ungetChar('\n'); QCOMPARE(buffer.readLine(), QByteArray("\n")); buffer.seek(1); buffer.readLine(buf, 3); QCOMPARE(static_cast<const char*>(buf), "XC"); buffer.seek(4); buffer.ungetChar('Q'); QCOMPARE(buffer.readLine(buf, 3), qint64(1)); for (int i = 0; i < 2; ++i) { QTcpSocket socket; QIODevice *dev; QByteArray result; const char *lineResult; if (i == 0) { dev = &buffer; result = QByteArray("ZXCV"); lineResult = "ZXCV"; } else { socket.connectToHost(QtNetworkSettings::serverName(), 80); socket.write("GET / HTTP/1.0\r\n\r\n"); QVERIFY(socket.waitForReadyRead()); dev = &socket; result = QByteArray("HTTP"); lineResult = "Date"; } char ch, ch2; dev->seek(0); dev->getChar(&ch); dev->ungetChar(ch); QCOMPARE(dev->peek(4), result); dev->getChar(&ch); dev->getChar(&ch2); dev->ungetChar(ch2); dev->ungetChar(ch); QCOMPARE(dev->read(1), result.left(1)); QCOMPARE(dev->read(3), result.right(3)); if (i == 0) dev->seek(0); else dev->readLine(); dev->getChar(&ch); dev->ungetChar(ch); dev->readLine(buf, 5); QCOMPARE(static_cast<const char*>(buf), lineResult); if (i == 1) socket.close(); } }
void Server::riceviMessaggio() { QTcpSocket* socket; QBuffer* buffer; QByteArray line; socket = (QTcpSocket*)(sender()); buffer = buffers.value(socket); qint64 bytes = buffer->write(socket->readAll()); //Per la ricezione del messaggio. buffer->seek(buffer->pos() - bytes); while (buffer->canReadLine()) //Leggo fino a quando sono presenti linee di testo. { line = buffer->readLine(); if(line.startsWith('#')) //Richiesta di autenticazione. { db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("./users.sqldb"); if (!db.open()) { socket->write("#false"); } QSqlQuery s; QString nome; QString password; QList<QByteArray> nomepassword; nomepassword = line.split('/'); nome = nomepassword[1]; password = nomepassword[2]; password = password.remove("\n"); s.prepare("SELECT Username FROM Utenti WHERE Username = '******' AND Password = '******'"); s.exec(); s.next(); QString username = s.value(0).toString(); if(username != "") { socket->write("#true\n"); } else { socket->write("#false\n"); } db.close(); } else if(line.startsWith('!')) //Richiesta di iscrizione. { QString nome; QString password; QList<QByteArray> nomepassword = line.split('/'); db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("./users.sqldb"); db.open(); QSqlQuery s; nome = nomepassword[1]; password = nomepassword[2]; password = password.remove("\n"); s.prepare("INSERT INTO Utenti VALUES ('" + nome + "', '" + password + "')"); s.exec(); db.close(); } else foreach (QTcpSocket* connection, connections) { connection->write(line); //Invio il testo ricevuto a un'altra connessione. } }