fw4spl
ClientQt.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwNetworkIO/http/ClientQt.hpp"
8 
9 #include <fwGui/dialog/MessageDialog.hpp>
10 
11 #include <fwTools/System.hpp>
12 #include <fwTools/UUID.hpp>
13 
14 #include <boost/filesystem/operations.hpp>
15 
16 #include <QList>
17 #include <QtNetwork>
18 
19 namespace fwNetworkIO
20 {
21 namespace http
22 {
23 
25 {
26 }
27 
28 //-----------------------------------------------------------------------------
29 
31 {
32 }
33 
34 //-----------------------------------------------------------------------------
35 
36 QByteArray ClientQt::get(Request::sptr request)
37 {
38  QNetworkAccessManager networkManager;
39  const QUrl qtUrl(QString::fromStdString(request->getUrl()));
40  QNetworkRequest qtRequest(qtUrl);
41 
42  this->computeHeaders(qtRequest, request->getHeaders());
43 
44  QNetworkReply* reply = networkManager.get(qtRequest);
45  QEventLoop loop;
46  QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
47  QObject::connect(reply, QOverload<QNetworkReply::NetworkError>::of(
48  &QNetworkReply::error), this, &ClientQt::processError);
49 
50  loop.exec();
51  QByteArray data = reply->readAll();
52  reply->deleteLater();
53  return data;
54 }
55 
56 //-----------------------------------------------------------------------------
57 
58 std::string ClientQt::getFile(Request::sptr request)
59 {
60  QNetworkAccessManager networkManager;
61  const QUrl qtUrl(QString::fromStdString(request->getUrl()));
62  QNetworkRequest qtRequest(qtUrl);
63 
64  this->computeHeaders(qtRequest, request->getHeaders());
65 
66  QNetworkReply* reply = networkManager.get(qtRequest);
67  QEventLoop loop;
68  QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
69  QObject::connect(reply, QOverload<QNetworkReply::NetworkError>::of(
70  &QNetworkReply::error), this, &ClientQt::processError);
71 
72  ::boost::filesystem::path folderPath = ::fwTools::System::getTemporaryFolder();
73  ::boost::filesystem::path filePath = folderPath / ::fwTools::UUID::generateUUID();
74 
75  QFile file(filePath.string().c_str());
76 
77  while(file.exists())
78  {
79  filePath = folderPath / ::fwTools::UUID::generateUUID();
80  file.setFileName(filePath.string().c_str());
81  }
82 
83  if (!file.open(QIODevice::WriteOnly))
84  {
85  throw ("Could not create a temporary file");
86  }
87 
88  QObject::connect(reply, &QNetworkReply::readyRead, [&] { file.write(reply->readAll()); } );
89 
90  loop.exec();
91  file.write(reply->readAll());
92  reply->deleteLater();
93 
94  return filePath.string();
95 }
96 
97 //-----------------------------------------------------------------------------
98 
99 void ClientQt::processError(QNetworkReply::NetworkError errorCode)
100 {
101  QMetaObject metaObject = QNetworkReply::staticMetaObject;
102  QMetaEnum metaEnum = metaObject.enumerator(metaObject.indexOfEnumerator("NetworkError"));
103  const char* desc = metaEnum.valueToKey(errorCode);
104 
105  switch(errorCode)
106  {
107  case QNetworkReply::ConnectionRefusedError:
108  throw ::fwNetworkIO::exceptions::ConnectionRefused(desc);
109  break;
110  case QNetworkReply::HostNotFoundError:
111  throw ::fwNetworkIO::exceptions::HostNotFound(desc);
112  break;
113  case QNetworkReply::ContentNotFoundError:
114  throw ::fwNetworkIO::exceptions::ContentNotFound(desc);
115  break;
116  default:
117  throw ::fwNetworkIO::exceptions::Base(desc);
118  break;
119  }
120 }
121 
122 //-----------------------------------------------------------------------------
123 
124 QByteArray ClientQt::post(Request::sptr request, const QByteArray& body)
125 {
126  QNetworkAccessManager networkManager;
127  const QUrl qtUrl(QString::fromStdString(request->getUrl()));
128  QNetworkRequest qtRequest(qtUrl);
129 
130  qtRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
131 
132  this->computeHeaders(qtRequest, request->getHeaders());
133 
134  QNetworkReply* reply = networkManager.post(qtRequest, body);
135  QEventLoop loop;
136  QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
137  QObject::connect(reply, QOverload<QNetworkReply::NetworkError>::of(
138  &QNetworkReply::error), this, &ClientQt::processError);
139  loop.exec();
140  QByteArray data = reply->readAll();
141  reply->deleteLater();
142  return data;
143 }
144 
145 //-----------------------------------------------------------------------------
146 
147 void ClientQt::computeHeaders(QNetworkRequest& request, const Request::HeadersType& headers)
148 {
149  Request::HeadersType::const_iterator cIt = headers.begin();
150  for(; cIt != headers.end(); ++cIt)
151  {
152  request.setRawHeader(cIt->first.c_str(), cIt->second.c_str());
153  }
154 }
155 
156 //-----------------------------------------------------------------------------
157 
158 Request::HeadersType ClientQt::head(Request::sptr request)
159 {
160  QNetworkAccessManager networkManager;
161  Request::HeadersType headers;
162 
163  const QUrl qtUrl(QString::fromStdString(request->getUrl()));
164  QNetworkRequest qtRequest(qtUrl);
165 
166  this->computeHeaders(qtRequest, request->getHeaders());
167 
168  QNetworkReply* reply = networkManager.head(qtRequest);
169  QEventLoop loop;
170  QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
171  loop.exec();
172 
173  const QList< QNetworkReply::RawHeaderPair>& rawHeaders = reply->rawHeaderPairs();
174 
175  QList< QNetworkReply::RawHeaderPair>::const_iterator cIt = rawHeaders.begin();
176 
177  for(; cIt != rawHeaders.end(); ++cIt)
178  {
179  headers[cIt->first.data()] = cIt->second.data();
180  }
181  reply->deleteLater();
182  return headers;
183 }
184 
185 //-----------------------------------------------------------------------------
186 
187 } // namespace http
188 
189 } // namespace fwNetworkIO
FWNETWORKIO_API QByteArray post(Request::sptr request, const QByteArray &body)
Performs POST request.
Definition: ClientQt.cpp:124
FWNETWORKIO_API ClientQt()
Definition: ClientQt.cpp:24
FWNETWORKIO_API std::string getFile(Request::sptr request)
Retrieves data over network.
Definition: ClientQt.cpp:58
The namespace fwNetworkIO contains the primary methods to access network.
FWNETWORKIO_API QByteArray get(Request::sptr request)
Retrieves data over network.
Definition: ClientQt.cpp:36
virtual FWNETWORKIO_API ~ClientQt()
Definition: ClientQt.cpp:30
static FWTOOLS_APIconst::boost::filesystem::path getTemporaryFolder(const std::string &subFolderPrefix="") noexcept
Returns a unique per-process temporary folder. The top level temporary folder will be automatically d...
Definition: System.cpp:148
void processError(QNetworkReply::NetworkError errorCode)
Slot triggered when an error occurs.
Definition: ClientQt.cpp:99
std::map< std::string, std::string > HeadersType
Maps header name to its value.
Definition: Request.hpp:29
FWNETWORKIO_API Request::HeadersType head(Request::sptr request)
Performs head request.
Definition: ClientQt.cpp:158
static FWTOOLS_API UUIDType generateUUID()
Return a new extended UUID;.
Definition: UUID.cpp:114