PDA

View Full Version : QTcpSocket no more data only for some sites



giusepped
1st August 2011, 08:30
I develped a proxy in Qt.
It works. But just for a site, it stucks at some point during communication.
If I delete all Internet data (IExplorer's panel), I can get a little bit more data, but never the all the data.
Before posting code, there is something I have to check?

giusepped
1st August 2011, 16:14
Nobody?
I post the code.


/*

*/

#include "webproxy.h"
#include <QtNetwork>
#include <QMessageBox>
#include <QtGui>
#include <QHash>
//#define DEBUG

WebProxy::WebProxy(QObject *parent,int port): QObject(parent)

{
qDebug()<<" Listen...";
authMethod = "";
QTcpServer *proxyServer = new QTcpServer(this);
if (!proxyServer->listen(QHostAddress::Any, port)) {
emit error(1);

return;
}

connect(proxyServer, SIGNAL(newConnection()), this, SLOT(manageQuery()));
qDebug() << "Proxy server running at port" << proxyServer->serverPort();


}


void WebProxy::setAddress(const QHostAddress &a, int port)
{
proxyAddress = a;
proxyPort = port;
port = port < 0 ? 8081 : port;


}

void WebProxy::manageQuery() {
QTcpServer *proxyServer = qobject_cast<QTcpServer*>(sender());
QTcpSocket *socket = proxyServer->nextPendingConnection();
connect(socket, SIGNAL(readyRead()), this, SLOT(processQuery()));
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));

qDebug()<<"New connection started..."<<socket->peerAddress();
}
QUrl WebProxy::getUrl(QList<QByteArray > &entries)
{

QByteArray method = entries.value(0);
QByteArray address = entries.value(1);
QByteArray version = entries.value(2);

qDebug()<<method;
qDebug()<<address;
qDebug()<<version;
QUrl url = QUrl::fromEncoded(address);
if (!url.isValid()) {

qWarning() << "Invalid URL:" << url;

return QString();
}


return url;
}

void WebProxy::processQuery() {


QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
QByteArray requestData = socket->readAll();

qDebug()<<"Request "<<requestData;

int pos = requestData.indexOf("\r\n");


QByteArray requestLine = requestData.left(pos);
requestData.remove(0, pos + 2);

QList<QByteArray> entries = requestLine.split(' ');
QByteArray method = entries.value(0);
QByteArray address = entries.value(1);
QByteArray version = entries.value(2);


QUrl url = QUrl::fromEncoded(address);
if (!url.isValid()) {
qWarning() << "Invalid URL:" << url;
socket->disconnectFromHost();
return;
}

QString host = url.host();


}

int port = (url.port() <= 0) ? 80 : url.port();
QByteArray req = url.encodedPath();
if (url.hasQuery())
req.append('?').append(url.encodedQuery());

requestLine = method + " " + req + " " + version + "\r\n";
if (!authMethod.isEmpty())
{
requestLine.append(requestLine);
requestLine.append(authMethod);
requestLine.append("\r\n");
}

requestData.prepend(requestLine);
qDebug()<<"REQUESTE DATA.........."<<requestData;


QString key = host + ':' + QString::number(port);
QTcpSocket *proxySocket = socket->findChild<QTcpSocket*>(key);

if (proxySocket) {
proxySocket->setObjectName(key);
proxySocket->setProperty("url", url);
proxySocket->setProperty("requestData", requestData);
proxySocket->write(requestData);

} else {
proxySocket = new QTcpSocket(socket);
proxySocket->setObjectName(key);
proxySocket->setProperty("url", url);
proxySocket->setProperty("requestData", requestData);
connect(proxySocket, SIGNAL(connected()), this, SLOT(sendRequest()));
connect(proxySocket, SIGNAL(readyRead()), this, SLOT(transferData()));
connect(proxySocket, SIGNAL(disconnected()), this, SLOT(closeConnection()));
connect(proxySocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(closeConnection()));
proxySocket->connectToHost(host, port);
}
}

void WebProxy::sendRequest() {
QTcpSocket *proxySocket = qobject_cast<QTcpSocket*>(sender());
QByteArray requestData = proxySocket->property("requestData").toByteArray();
proxySocket->write(requestData);

void WebProxy::transferData() {


QTcpSocket *proxySocket = qobject_cast<QTcpSocket*>(sender());

QByteArray data = proxySocket->readAll();
QString host = proxySocket->peerAddress().toString();
QByteArray filtered(data);



QTcpSocket *socket = qobject_cast<QTcpSocket*>(proxySocket->parent());
qDebug()<<"WP socket write"<<filtered;
if (!data.trimmed().isEmpty())
if (socket->write(filtered)==-1)
qDebug()<<"WP error";


qDebug()<<"WP socket write"<<filtered;
}

void WebProxy::closeConnection() {

QTcpSocket *proxySocket = qobject_cast<QTcpSocket*>(sender());
if (proxySocket) {
QTcpSocket *socket = qobject_cast<QTcpSocket*>(proxySocket->parent());
if (socket)
socket->disconnectFromHost();
if (proxySocket->error() != QTcpSocket::RemoteHostClosedError)
qWarning() << "Error for:" << proxySocket->property("url").toUrl()
<< proxySocket->errorString();
proxySocket->deleteLater();;
}
}





Sometimes, in the output debug I gat strange things...expecially many Http 304 Not modified errors.
Try with this IP plaza ip: 87.22.235.24 which is a public DVR.
For other everythings is ok. But only for this I cannot get the response from the server....

vallidor
3rd August 2011, 08:15
have you ensured that the result of proxySocket->write(requestData); equals requestData.size()?

giusepped
10th August 2011, 11:10
Yes. I checked the size() method on requestData and the result of the write and always they are the same...
G

Added after 1 41 minutes:

I checked the webpage of the video server.
In Linux, from the command shell, If I make a simple
GET http://87.22.235.24/ HTTP/1.1 I get all the content correctly.
But with the code of above, it stucks at downloading all the scripts.
There is something to do, like flush, close, reserve memory...
G