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

Last change on this file since 7704 was 7704, checked in by stuerze, 4 years ago

minor changes to interrupt the connection to the caster completely if stop button is pressed

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  outData = _reply->readAll();
189}
190
191// Wait for next data
192////////////////////////////////////////////////////////////////////////////
193void bncNetQueryV2::waitForReadyRead(QByteArray& outData) {
194
195  // Wait Loop
196  // ---------
197  if (!_reply->bytesAvailable()) {
198    _eventLoop->exec();
199  }
200
201  // Check NTRIPv2 error code
202  // ------------------------
203  if (_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
204    _reply->abort();
205  }
206
207  // Append Data
208  // -----------
209  else {
210    outData.append(_reply->readAll());
211  }
212}
213
214// TSL/SSL
215////////////////////////////////////////////////////////////////////////////
216void bncNetQueryV2::slotSslErrors(QList<QSslError> errors) {
217
218  QString msg = "SSL Error\n";
219  QSslCertificate cert = _reply->sslConfiguration().peerCertificate();
220  if (!cert.isNull()) {
221    msg += QString("Server Certificate Issued by:\n"
222                   "%1\n%2\nCannot be verified\n")
223           .arg(cert.issuerInfo(QSslCertificate::OrganizationalUnitName))
224           .arg(cert.issuerInfo(QSslCertificate::Organization));
225  }
226  QListIterator<QSslError> it(errors);
227  while (it.hasNext()) {
228    const QSslError& err = it.next();
229    msg += "\n" + err.errorString();
230  }
231
232  BNC_CORE->slotMessage(msg.toAscii(), true);
233
234  if (_sslIgnoreErrors) {
235    _reply->ignoreSslErrors();
236  }
237  else {
238    stop();
239  }
240}
Note: See TracBrowser for help on using the repository browser.