source: ntrip/trunk/BNC/src/bncnetqueryv2.cpp @ 7813

Last change on this file since 7813 was 7813, checked in by stuerze, 3 years ago

minor changes to prevent crash in case of ssl errors

File size: 6.9 KB
Line 
1/* -------------------------------------------------------------------------
2 * BKG NTRIP Client
3 * -------------------------------------------------------------------------
4 *
5 * Class:      bncNetQueryV2
6 *
7 * Purpose:    Blocking Network Requests (NTRIP Version 2)
8 *
9 * Author:     L. Mervart
10 *
11 * Created:    27-Dec-2008
12 *
13 * Changes:
14 *
15 * -----------------------------------------------------------------------*/
16
17#include <iostream>
18
19#include "bncnetqueryv2.h"
20#include "bncsettings.h"
21#include "bncversion.h"
22#include "bncsslconfig.h"
23#include "bncsettings.h"
24
25// Constructor
26////////////////////////////////////////////////////////////////////////////
27bncNetQueryV2::bncNetQueryV2(bool secure) {
28  _secure    = secure;
29  _manager   = new QNetworkAccessManager(this);
30  connect(_manager, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&,
31                                                       QAuthenticator*)),
32          this, SLOT(slotProxyAuthenticationRequired(const QNetworkProxy&,
33                                                     QAuthenticator*)));
34  _reply     = 0;
35  _eventLoop = new QEventLoop(this);
36  _firstData = true;
37  _status    = init;
38
39  bncSettings settings;
40  _sslIgnoreErrors =
41     (Qt::CheckState(settings.value("sslIgnoreErrors").toInt()) == Qt::Checked);
42
43  if (_secure && !QSslSocket::supportsSsl()) {
44    BNC_CORE->slotMessage("No SSL support, install OpenSSL run-time libraries", true);
45    stop();
46  }
47}
48
49// Destructor
50////////////////////////////////////////////////////////////////////////////
51bncNetQueryV2::~bncNetQueryV2() {
52  delete _eventLoop;
53  if (_reply) {
54    _reply->abort();
55    delete _reply;
56  }
57  delete _manager;
58}
59
60// Stop (quit event loop)
61////////////////////////////////////////////////////////////////////////////
62void bncNetQueryV2::stop() {
63  if (_reply) {
64    _reply->abort();
65    delete _reply;
66    _reply = 0;
67  }
68  _eventLoop->quit();
69  _status = finished;
70}
71
72// End of Request
73////////////////////////////////////////////////////////////////////////////
74void bncNetQueryV2::slotFinished() {
75  _eventLoop->quit();
76  if (_reply && _reply->error() != QNetworkReply::NoError) {
77    _status = error;
78    emit newMessage(_url.path().toAscii().replace(0,1,"")  +
79                    ": NetQueryV2: server replied: " +
80                    _reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray(),
81                    true);
82  }
83  else {
84    _status = finished;
85  }
86}
87
88//
89////////////////////////////////////////////////////////////////////////////
90void bncNetQueryV2::slotProxyAuthenticationRequired(const QNetworkProxy&,
91                                                    QAuthenticator*) {
92  emit newMessage("slotProxyAuthenticationRequired", true);
93}
94
95// Start request, block till the next read
96////////////////////////////////////////////////////////////////////////////
97void bncNetQueryV2::startRequest(const QUrl& url, const QByteArray& gga) {
98  startRequestPrivate(url, gga, false);
99}
100
101// Start request, block till the next read
102////////////////////////////////////////////////////////////////////////////
103void bncNetQueryV2::keepAliveRequest(const QUrl& url, const QByteArray& gga) {
104  startRequestPrivate(url, gga, false);
105}
106
107// Start Request (Private Method)
108////////////////////////////////////////////////////////////////////////////
109void bncNetQueryV2::startRequestPrivate(const QUrl& url, const QByteArray& gga,
110                                        bool full) {
111
112  _status = running;
113
114  // Default scheme and path
115  // -----------------------
116  _url = url;
117  if (_url.scheme().isEmpty()) {
118    if (_secure) {
119      _url.setScheme("https");
120    }
121    else {
122      _url.setScheme("http");
123    }
124  }
125  if (_url.path().isEmpty()) {
126    _url.setPath("/");
127  }
128
129  // Proxy Settings
130  // --------------
131  bncSettings settings;
132  QString proxyHost = settings.value("proxyHost").toString();
133  int     proxyPort = settings.value("proxyPort").toInt();
134
135  if (!proxyHost.isEmpty()) {
136    QNetworkProxy proxy(QNetworkProxy::HttpProxy, proxyHost, proxyPort);
137    _manager->setProxy(proxy);
138  }
139
140  // Network Request
141  // ---------------
142  QNetworkRequest request;
143  bncSslConfig sslConfig;
144  request.setSslConfiguration(sslConfig);
145  request.setUrl(_url);
146  request.setRawHeader("Host"         , _url.host().toAscii());
147  request.setRawHeader("Ntrip-Version", "Ntrip/2.0");
148  request.setRawHeader("User-Agent"   , "NTRIP BNC/"BNCVERSION" ("BNC_OS")");
149  if (!_url.userName().isEmpty()) {
150    QString uName = QUrl::fromPercentEncoding(_url.userName().toAscii());
151    QString passW = QUrl::fromPercentEncoding(_url.password().toAscii());
152    request.setRawHeader("Authorization", "Basic " +
153                         (uName + ":" + passW).toAscii().toBase64());
154  }
155  if (!gga.isEmpty()) {
156    request.setRawHeader("Ntrip-GGA", gga);
157  }
158  request.setRawHeader("Connection"   , "close");
159
160  delete _reply;
161  _reply = _manager->get(request);
162
163  // Connect Signals
164  // ---------------
165  connect(_reply, SIGNAL(finished()), this, SLOT(slotFinished()));
166  connect(_reply, SIGNAL(finished()), _eventLoop, SLOT(quit()));
167  connect(_reply, SIGNAL(sslErrors(QList<QSslError>)),
168          this, SLOT(slotSslErrors(QList<QSslError>)));
169  if (!full) {
170    connect(_reply, SIGNAL(readyRead()), _eventLoop, SLOT(quit()));
171  }
172}
173
174// Start Request, wait for its completion
175////////////////////////////////////////////////////////////////////////////
176void bncNetQueryV2::waitForRequestResult(const QUrl& url, QByteArray& outData) {
177
178  // Send Request
179  // ------------
180  startRequestPrivate(url, "", true);
181
182  // Wait Loop
183  // ---------
184  _eventLoop->exec();
185
186  // Copy Data and Return
187  // --------------------
188  if (_reply) {
189    outData = _reply->readAll();
190  }
191}
192
193// Wait for next data
194////////////////////////////////////////////////////////////////////////////
195void bncNetQueryV2::waitForReadyRead(QByteArray& outData) {
196
197  // Wait Loop
198  // ---------
199  if (!_reply->bytesAvailable()) {
200    _eventLoop->exec();
201  }
202
203  // Check NTRIPv2 error code
204  // ------------------------
205  if (_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
206    _reply->abort();
207  }
208
209  // Append Data
210  // -----------
211  else {
212    outData.append(_reply->readAll());
213  }
214}
215
216// TSL/SSL
217////////////////////////////////////////////////////////////////////////////
218void bncNetQueryV2::slotSslErrors(QList<QSslError> errors) {
219
220  QString msg = "SSL Error\n";
221  QSslCertificate cert = _reply->sslConfiguration().peerCertificate();
222  if (!cert.isNull()) {
223    msg += QString("Server Certificate Issued by:\n"
224                   "%1\n%2\nCannot be verified\n")
225           .arg(cert.issuerInfo(QSslCertificate::OrganizationalUnitName))
226           .arg(cert.issuerInfo(QSslCertificate::Organization));
227  }
228  QListIterator<QSslError> it(errors);
229  while (it.hasNext()) {
230    const QSslError& err = it.next();
231    msg += "\n" + err.errorString();
232  }
233
234  BNC_CORE->slotMessage(msg.toAscii(), true);
235
236  if (_sslIgnoreErrors) {
237    _reply->ignoreSslErrors();
238  }
239  else {
240    stop();
241  }
242}
Note: See TracBrowser for help on using the repository browser.