Я пытаюсь подключиться к веб-сайту через прокси. Я реализовал QTcpServer и QTcpSocket.
Сервер передает соединение в сокет.
Это работает хорошо, но для некоторых сайтов, особенно для тех, которые динамически создавали javascript, сокет зависает в какой-то момент, и в навигаторе ничего не отображается.
Прикрепите код, надеюсь, очистите.
#include "webproxy.h"
#include <QtNetwork>
#include <QMessageBox>
#include <QtGui>
#include <QHash>
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::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() {
int wSize = 0;
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);
QByteArray auth;
QByteArray authMethod;
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");
}
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);
wSize = 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();
int wSize = 0;
wSize = proxySocket->write(requestData);
}
void WebProxy::transferData() {
QTcpSocket *proxySocket = qobject_cast<QTcpSocket*>(sender());
QByteArray data = proxySocket->readAll();
qDebug()<<"READ TRANSFER SIZE..."<<data.size();
QString host = proxySocket->peerAddress().toString();
QByteArray filtered(data);
QTcpSocket *socket = qobject_cast<QTcpSocket*>(proxySocket->parent());
int wSize = 0;
if (!data.trimmed().isEmpty())
{
wSize = socket->write(filtered);
if (wSize==-1)
qDebug()<<"WP error";
else
qDebug()<<"TRANSFER WRITE SIZE = "<<wSize<<" READ SIZE"<<filtered.size();
}
}
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();;
}
}