source: ntrip/trunk/BNC/bncnetqueryv1.cpp@ 1849

Last change on this file since 1849 was 1849, checked in by mervart, 15 years ago

* empty log message *

File size: 6.7 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
23using namespace std;
24
25#define BNCVERSION "1.7"
26
27// Constructor
28////////////////////////////////////////////////////////////////////////////
29bncNetQueryV1::bncNetQueryV1() {
30 _socket = 0;
31 _eventLoop = new QEventLoop(this);
32 _timeOut = 20000;
33}
34
35// Destructor
36////////////////////////////////////////////////////////////////////////////
37bncNetQueryV1::~bncNetQueryV1() {
38 delete _socket;
39 delete _eventLoop;
40}
41
42//
43////////////////////////////////////////////////////////////////////////////
44void bncNetQueryV1::stop() {
45 _eventLoop->quit();
46#ifndef sparc
47 if (_socket) {
48 _socket->abort();
49 }
50#endif
51 _status = finished;
52}
53
54// End of Request
55////////////////////////////////////////////////////////////////////////////
56void bncNetQueryV1::slotFinished() {
57 _eventLoop->quit();
58 if (_socket) {
59 _outData = _socket->readAll();
60 _status = finished;
61 }
62}
63
64//
65////////////////////////////////////////////////////////////////////////////
66void bncNetQueryV1::waitForRequestResult(const QUrl& url, QByteArray& outData){
67
68 delete _socket;
69 _socket = new QTcpSocket();
70
71 connect(_socket, SIGNAL(disconnected()), this, SLOT(slotFinished()));
72
73 startRequestPrivate(url, "", true);
74
75 QTimer::singleShot(10000, this, SLOT(slotFinished()));
76
77 _eventLoop->exec();
78
79 delete _socket; _socket = 0;
80
81 outData = _outData;
82 _outData.clear();
83}
84
85//
86////////////////////////////////////////////////////////////////////////////
87void bncNetQueryV1::waitForReadyRead(QByteArray& outData) {
88 if (_socket && _socket->state() == QAbstractSocket::ConnectedState) {
89 while (true) {
90 int nBytes = _socket->bytesAvailable();
91 if (nBytes > 0) {
92 outData = _socket->readAll();
93 return;
94 }
95 else if (!_socket->waitForReadyRead(_timeOut)) {
96 QString errStr = _socket->errorString();
97 if (errStr.isEmpty()) {
98 errStr = "Read timeout";
99 }
100 delete _socket;
101 _socket = 0;
102 _status = error;
103 emit newMessage(_url.path().toAscii().replace(0,1,"")
104 + ": " + errStr.toAscii(), true);
105 return;
106 }
107 }
108 }
109}
110
111// Connect to Caster, send the Request
112////////////////////////////////////////////////////////////////////////////
113void bncNetQueryV1::startRequest(const QUrl& url, const QByteArray& gga) {
114 startRequestPrivate(url, gga, false);
115}
116
117// Connect to Caster, send the Request
118////////////////////////////////////////////////////////////////////////////
119void bncNetQueryV1::startRequestPrivate(const QUrl& url,
120 const QByteArray& gga,
121 bool sendRequestOnly) {
122
123 _status = running;
124
125 if (!sendRequestOnly) {
126 delete _socket;
127 _socket = new QTcpSocket();
128 }
129
130 // Default scheme and path
131 // -----------------------
132 _url = url;
133 if (_url.scheme().isEmpty()) {
134 _url.setScheme("http");
135 }
136 if (_url.path().isEmpty()) {
137 _url.setPath("/");
138 }
139
140 // Connect the Socket
141 // ------------------
142 bncSettings settings;
143 QString proxyHost = settings.value("proxyHost").toString();
144 int proxyPort = settings.value("proxyPort").toInt();
145
146 if ( proxyHost.isEmpty() ) {
147 _socket->connectToHost(_url.host(), _url.port());
148 }
149 else {
150 _socket->connectToHost(proxyHost, proxyPort);
151 }
152 if (!_socket->waitForConnected(_timeOut)) {
153 delete _socket;
154 _socket = 0;
155 _status = error;
156 return;
157 }
158
159 // Send Request
160 // ------------
161 QString uName = QUrl::fromPercentEncoding(_url.userName().toAscii());
162 QString passW = QUrl::fromPercentEncoding(_url.password().toAscii());
163 QByteArray userAndPwd;
164
165 if(!uName.isEmpty() || !passW.isEmpty()) {
166 userAndPwd = "Authorization: Basic " + (uName.toAscii() + ":" +
167 passW.toAscii()).toBase64() + "\r\n";
168 }
169
170 QByteArray reqStr;
171 if ( proxyHost.isEmpty() ) {
172 if (_url.path().indexOf("/") != 0) _url.setPath("/");
173 reqStr = "GET " + _url.path().toAscii() + " HTTP/1.0\r\n"
174 + "User-Agent: NTRIP BNC/" BNCVERSION "\r\n"
175 + userAndPwd + "\r\n";
176 } else {
177 reqStr = "GET " + _url.toEncoded() + " HTTP/1.0\r\n"
178 + "User-Agent: NTRIP BNC/" BNCVERSION "\r\n"
179 + "Host: " + _url.host().toAscii() + "\r\n"
180 + userAndPwd + "\r\n";
181 }
182
183 // NMEA string to handle VRS stream
184 // --------------------------------
185 if (!gga.isEmpty()) {
186 reqStr += gga + "\r\n";
187 }
188
189 _socket->write(reqStr, reqStr.length());
190
191 if (!_socket->waitForBytesWritten(_timeOut)) {
192 delete _socket;
193 _socket = 0;
194 _status = error;
195 emit newMessage(_url.path().toAscii().replace(0,1,"")
196 + ": Write timeout", true);
197 return;
198 }
199
200 // Read Caster Response
201 // --------------------
202 if (!sendRequestOnly) {
203 bool proxyResponse = false;
204 QStringList response;
205 while (true) {
206 if (_socket->canReadLine()) {
207 QString line = _socket->readLine();
208
209 if (line.indexOf("ICY 200 OK") == -1 &&
210 line.indexOf("HTTP") != -1 &&
211 line.indexOf("200 OK") != -1 ) {
212 proxyResponse = true;
213 }
214
215 if (!proxyResponse && !line.trimmed().isEmpty()) {
216 response.push_back(line);
217 }
218
219 if (line.trimmed().isEmpty()) {
220 if (proxyResponse) {
221 proxyResponse = false;
222 }
223 else {
224 break;
225 }
226 }
227
228 if (line.indexOf("Unauthorized") != -1) {
229 break;
230 }
231
232 if (!proxyResponse &&
233 line.indexOf("200 OK") != -1 &&
234 line.indexOf("SOURCETABLE") == -1) {
235 response.clear();
236 if (_socket->canReadLine()) {
237 _socket->readLine();
238 }
239 break;
240 }
241 }
242 else if (!_socket->waitForReadyRead(_timeOut)) {
243 delete _socket;
244 _socket = 0;
245 _status = error;
246 emit newMessage(_url.path().toAscii().replace(0,1,"")
247 + ": Response timeout", true);
248 return;
249 }
250 }
251 if (response.size() > 0) {
252 delete _socket;
253 _socket = 0;
254 _status = error;
255 emit newMessage(_url.path().toAscii().replace(0,1,"")
256 + ": Wrong caster response\n"
257 + response.join("").toAscii(), true);
258 }
259 }
260}
261
Note: See TracBrowser for help on using the repository browser.