source: ntrip/trunk/BNC/src/bncnetqueryv1.cpp @ 8203

Last change on this file since 8203 was 8203, checked in by stoecker, 18 months ago

see #105 - some changes for Qt5

File size: 7.9 KB
Line 
1/* -------------------------------------------------------------------------
2 * BKG NTRIP Client
3 * -------------------------------------------------------------------------
4 *
5 * Class:      bncNetQueryV1
6 *
7 * Purpose:    Blocking Network Requests (NTRIP Version 1)
8 *
9 * Author:     L. Mervart
10 *
11 * Created:    27-Dec-2008
12 *
13 * Changes:   
14 *
15 * -----------------------------------------------------------------------*/
16
17#include <iostream>
18#include <iomanip>
19
20#include "bncnetqueryv1.h"
21#include "bncsettings.h"
22#include "bncversion.h"
23
24using namespace std;
25
26// Constructor
27////////////////////////////////////////////////////////////////////////////
28bncNetQueryV1::bncNetQueryV1() {
29  _socket    = 0;
30  _eventLoop = new QEventLoop(this);
31  _timeOut   = 20000;
32}
33
34// Destructor
35////////////////////////////////////////////////////////////////////////////
36bncNetQueryV1::~bncNetQueryV1() {
37  delete _socket;
38  delete _eventLoop;
39}
40
41//
42////////////////////////////////////////////////////////////////////////////
43void bncNetQueryV1::stop() {
44  _eventLoop->quit();
45#ifndef sparc
46  if (_socket) {
47    _socket->abort();
48  }
49#endif
50  _status = finished;
51}
52
53//
54////////////////////////////////////////////////////////////////////////////
55void bncNetQueryV1::waitForRequestResult(const QUrl& url, QByteArray& outData){
56
57  delete _socket;
58  _socket = new QTcpSocket();
59
60  connect(_socket, SIGNAL(disconnected()), _eventLoop, SLOT(quit()));
61
62  startRequestPrivate(url, "", true);
63
64  QTimer::singleShot(10000, _eventLoop, SLOT(quit()));
65
66  _eventLoop->exec();
67
68  if (_socket) {
69    outData = _socket->readAll();
70    delete _socket; _socket = 0;
71    _status = finished;
72  }
73}
74
75//
76////////////////////////////////////////////////////////////////////////////
77void bncNetQueryV1::waitForReadyRead(QByteArray& outData) {
78  if (_socket && _socket->state() == QAbstractSocket::ConnectedState) {
79    while (true) {
80      int nBytes = _socket->bytesAvailable();
81      if (nBytes > 0) {
82        outData = _socket->readAll();
83        return;
84      }
85      else if (!_socket->waitForReadyRead(_timeOut)) {
86        QString errStr = _socket->errorString();
87        if (errStr.isEmpty()) {
88          errStr = "Read timeout";
89        }
90        delete _socket;
91        _socket = 0;
92        _status = error;
93        emit newMessage(_url.path().toLatin1().replace(0,1,"")
94                        + ": " + errStr.toLatin1(), true);
95        return;
96      }
97    }
98  }
99}
100
101// Connect to Caster, send the Request
102////////////////////////////////////////////////////////////////////////////
103void bncNetQueryV1::startRequest(const QUrl& url, const QByteArray& gga) {
104  startRequestPrivate(url, gga, false);
105}
106
107
108// Already connected to Caster, send another Request
109////////////////////////////////////////////////////////////////////////////
110void bncNetQueryV1::keepAliveRequest(const QUrl& url, const QByteArray& gga) {
111
112  _status = running;
113
114  // Default scheme and path
115  // -----------------------
116  _url = url;
117  if (_url.scheme().isEmpty()) {
118    _url.setScheme("http");
119  }
120  if (_url.path().isEmpty()) {
121    _url.setPath("/");
122  }
123
124  // Connect the Socket
125  // ------------------
126  bncSettings settings;
127  QString proxyHost = settings.value("proxyHost").toString();
128  int     proxyPort = settings.value("proxyPort").toInt();
129
130  if ( proxyHost.isEmpty() ) {
131    _socket->connectToHost(_url.host(), _url.port());
132  }
133  else {
134    _socket->connectToHost(proxyHost, proxyPort);
135  }
136  if (!_socket->waitForConnected(_timeOut)) {
137    delete _socket;
138    _socket = 0;
139    _status = error;
140    return;
141  }
142
143  // Send Request
144  // ------------
145   QByteArray reqStr;
146
147   // NMEA string to handle VRS stream
148   // --------------------------------
149   if (!gga.isEmpty()) {
150     reqStr += gga + "\r\n";
151   }
152
153   _socket->write(reqStr, reqStr.length());
154
155   if (!_socket->waitForBytesWritten(_timeOut)) {
156     delete _socket;
157     _socket = 0;
158     _status = error;
159     emit newMessage(_url.path().toLatin1().replace(0,1,"")
160                     + ": Write timeout", true);
161     return;
162   }
163
164}
165
166// Connect to Caster, send the Request
167////////////////////////////////////////////////////////////////////////////
168void bncNetQueryV1::startRequestPrivate(const QUrl& url, 
169                                        const QByteArray& gga, 
170                                        bool sendRequestOnly) {
171
172  _status = running;
173
174  if (!sendRequestOnly) {
175    delete _socket;
176    _socket = new QTcpSocket();
177  }
178
179  // Default scheme and path
180  // -----------------------
181  _url = url;
182  if (_url.scheme().isEmpty()) {
183    _url.setScheme("http");
184  }
185  if (_url.path().isEmpty()) {
186    _url.setPath("/");
187  }
188
189  // Connect the Socket
190  // ------------------
191  bncSettings settings;
192  QString proxyHost = settings.value("proxyHost").toString();
193  int     proxyPort = settings.value("proxyPort").toInt();
194 
195  if ( proxyHost.isEmpty() ) {
196    _socket->connectToHost(_url.host(), _url.port());
197  }
198  else {
199    _socket->connectToHost(proxyHost, proxyPort);
200  }
201  if (!_socket->waitForConnected(_timeOut)) {
202    delete _socket; 
203    _socket = 0;
204    _status = error;
205    return;
206  }
207
208  // Send Request
209  // ------------
210  QString uName = QUrl::fromPercentEncoding(_url.userName().toLatin1());
211  QString passW = QUrl::fromPercentEncoding(_url.password().toLatin1());
212  QByteArray userAndPwd;
213
214  if(!uName.isEmpty() || !passW.isEmpty()) {
215    userAndPwd = "Authorization: Basic " + (uName.toLatin1() + ":" +
216    passW.toLatin1()).toBase64() + "\r\n";
217  }
218
219  QByteArray reqStr;
220  if ( proxyHost.isEmpty() ) {
221    if (_url.path().indexOf("/") != 0) _url.setPath("/");
222    reqStr = "GET " + _url.path().toLatin1() + " HTTP/1.0\r\n"
223             + "User-Agent: NTRIP BNC/" BNCVERSION " (" BNC_OS ")\r\n"
224             + "Host: " + _url.host().toLatin1() + "\r\n"
225             + userAndPwd + "\r\n";
226  } else {
227    reqStr = "GET " + _url.toEncoded() + " HTTP/1.0\r\n"
228             + "User-Agent: NTRIP BNC/" BNCVERSION " (" BNC_OS ")\r\n"
229             + "Host: " + _url.host().toLatin1() + "\r\n"
230             + userAndPwd + "\r\n";
231  }
232
233  // NMEA string to handle VRS stream
234  // --------------------------------
235  if (!gga.isEmpty()) {
236    reqStr += gga + "\r\n";
237  }
238
239  _socket->write(reqStr, reqStr.length());
240
241  if (!_socket->waitForBytesWritten(_timeOut)) {
242    delete _socket;
243    _socket = 0;
244    _status = error;
245    emit newMessage(_url.path().toLatin1().replace(0,1,"")
246                    + ": Write timeout", true);
247    return;
248  }
249
250  // Read Caster Response
251  // --------------------
252  if (!sendRequestOnly) {
253    bool proxyResponse = false;
254    QStringList response;
255    while (true) {
256      if (_socket->canReadLine()) {
257        QString line = _socket->readLine();
258   
259        if (line.indexOf("ICY 200 OK") == -1 && 
260            line.indexOf("HTTP")       != -1 && 
261            line.indexOf("200 OK")     != -1 ) {
262          proxyResponse = true;
263        }
264   
265        if (!proxyResponse && !line.trimmed().isEmpty()) {
266          response.push_back(line);
267        }
268   
269        if (line.trimmed().isEmpty()) {
270          if (proxyResponse) {
271            proxyResponse = false;
272        }
273        else {
274            break;
275        }
276        }
277   
278        if (line.indexOf("Unauthorized") != -1) {
279          break;
280        }
281   
282        if (!proxyResponse                    &&
283            line.indexOf("200 OK")      != -1 &&
284            line.indexOf("SOURCETABLE") == -1) {
285          response.clear();
286          if (_socket->canReadLine()) {
287            _socket->readLine();
288        }
289        break;
290        }
291      }
292      else if (!_socket->waitForReadyRead(_timeOut)) {
293        delete _socket;
294        _socket = 0;
295        _status = error;
296        emit newMessage(_url.path().toLatin1().replace(0,1,"") 
297                        + ": Response timeout", true);
298        return;
299      }
300    }
301    if (response.size() > 0) {
302      delete _socket;
303      _socket = 0;
304      _status = error;
305      emit newMessage(_url.path().toLatin1().replace(0,1,"") 
306                      + ": Wrong caster response\n" 
307                      + response.join("").toLatin1(), true);
308    }
309  }
310}
311
Note: See TracBrowser for help on using the repository browser.