Qt4 QSslSocket запускает ответ HTTP 406

#qt #ssl

#qt #ssl

Вопрос:

У меня есть приложение, которое работает как прокси, используя QTcpSocket для перехвата HTTP-запросов. Я пытаюсь расширить это, чтобы оно работало и для HTTPS, но, похоже, это работает не так, как я ожидал. Использование QHttp для меня невозможно из-за уникальности приложения.

В настоящее время у меня есть что-то вроде следующего:

 serverConnection = new QTcpSocket();
serverConnection->setProxy(proxy);
serverConnection->connectToHost(url_hostname, url_port);
serverConnection->write(request.toAscii());
connect(serverConnection, SIGNAL(readyRead()), this, SLOT(readServerData()), Qt::DirectConnection);
  

Я пытался сделать что-то очень похожее, используя QSslSocket, но, к сожалению, результат не такой, как я ожидал.

 serverSConnection = new QSslSocket();
serverSConnection->connectToHostEncrypted(url_hostname, url_port);
if (!serverSConnection->waitForEncrypted()) {
    qDebug() << "waitForEncrypted failed";
}
serverSConnection->write(request.toAscii());
connect(serverSConnection, SIGNAL(readyRead()), this, SLOT(readSServerData()), Qt::DirectConnection);
  

Использование QSslSocket для выполнения запроса, по-видимому, запускает:
HTTP/1.1 406 неприемлемо

Запрос, который я отправляю, выглядит примерно следующим образом:

 Received Request:  "CONNECT www.somesslhost.com:443 HTTP/1.1
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.13) Gecko/2009080315 Ubuntu/9.04 (jaunty) Firefox/3.0.13
Proxy-Connection: keep-alive
Host: www.somesslhost.com
  

Есть ли что-то особенное в отправке HTTPS-запроса через мое приложение с использованием QSslSocket, чего мне не хватает?

Комментарии:

1. Является ли последний фрагмент запроса, который ваше приложение отправляет на сервер назначения, или тот, который ваш браузер отправляет приложению?

2. Последний фрагмент — это запрос, который я отправляю на сервер назначения.

Ответ №1:

Располагая текущей информацией, я могу только предположить, что вы делаете это неправильно.

Ваш метод подходит, если предполагается, что ваш клиент отправляет простые HTTP-запросы вашему приложению, и оно будет пересылать их на HTTPS-сервер.

Если ваш клиент вместо этого способен использовать HTTPS и использует ваше приложение в качестве стандартного прокси-сервера, вы не должны подключаться к серверу таким образом. Вы получаете 406, потому что пытаетесь убедить конечный сервер действовать как прокси-сервер между вами и самим собой.

Я думаю, вы можете взглянуть на туннелирование SSL через WWW прокси. В принципе, вы должны проанализировать входящий запрос, установить ‘необработанное’ соединение с сервером, ответить клиенту подтверждением установления, а затем просто пересылать пакеты вперед и обратно.

Все согласование SSL должно выполняться между вашим клиентом и сервером назначения, прокси-сервер должен пересылать только зашифрованные пакеты, не имея возможности их расшифровать.

Комментарии:

1. При использовании QSslSocket нужно ли мне вручную извлекать сертификат однорангового узла или это обрабатывается автоматически?

Ответ №2:

Я в замешательстве — вы говорите:

У меня есть приложение, которое работает как прокси, используя QTcpSocket для перехвата HTTP-запросов.

Что вы подразумеваете под «перехватом»? Вы пытаетесь написать приложение HTTP-прокси? Пожалуйста, выражайтесь более ясно и конкретно, и мы, вероятно, сможем вам помочь.

Комментарии:

1. Извините, это было действительно плохо сформулировано. Полностью игнорируйте прокси. Я просто пытаюсь создать стандартное соединение с сокетом SSL, которое действительно работает. Когда я настраиваю свое приложение для связи по протоколу SSL, кажется, что SSL-квитирование не работает должным образом.