URL.h
Go to the documentation of this file.
1 
20 #ifndef URL_H_9DAEGSMV
21 #define URL_H_9DAEGSMV
22 
23 #include "uscxml/Common.h"
24 #include "uscxml/messages/Event.h"
25 
26 #include <string>
27 #include <sstream>
28 #include <map>
29 #include <set>
30 #include <list>
31 #include <thread>
32 #include <condition_variable>
33 #include <mutex>
34 namespace uscxml {
35 
36 class URL;
37 
38 class USCXML_API URLMonitor {
39 public:
40  virtual void downloadStarted(const URL& url) {};
41  virtual void downloadCompleted(const URL& url) {};
42  virtual void downloadFailed(const URL& url, int errorCode) {};
43  virtual void headerChunkReceived(const URL& url, const std::string& headerChunk) {};
44  virtual void contentChunkReceived(const URL& url, const std::string& contentChunk) {};
45 };
46 
47 enum URLRequestType {
48  POST,
49  GET
50 };
51 
52 class USCXML_API URLImpl : public std::enable_shared_from_this<URLImpl> {
53 public:
54  URLImpl(const std::string& url);
55  ~URLImpl();
56 
57  bool isAbsolute() const;
58  std::string scheme() const;
59  std::string userInfo() const;
60  std::string host() const;
61  std::string port() const;
62  std::string fragment() const;
63  std::map<std::string, std::string> query() const;
64  std::string path() const;
65  std::list<std::string> pathComponents() const;
66 
67  void normalize();
68 
69  static URL resolve(URLImpl* relativeURL, URLImpl* absoluteURL);
70  static URL resolveWithCWD(URLImpl* relativeURL);
71  static URL refer(URLImpl* absoluteSource, URLImpl* absoluteBase);
72 
73  void addMonitor(URLMonitor* monitor) {
74  _monitors.insert(monitor);
75  }
76  void removeMonitor(URLMonitor* monitor) {
77  _monitors.erase(monitor);
78  }
79 
80  // downloading / uploading
81  void addOutHeader(const std::string& key, const std::string& value);
82  void setOutContent(const std::string& content);
83  void setRequestType(URLRequestType requestType);
84  const std::map<std::string, std::string> getInHeaderFields();
85  const std::string getInHeaderField(const std::string& key);
86 
87  const std::string getStatusCode() const;
88  const std::string getStatusMessage() const;
89  const std::string getInContent(bool forceReload = false);
90  const void download(bool blocking = false);
91 
92  operator Data() const;
93  operator std::string() const;
94 
95 protected:
96  URLImpl();
97  void* _uri = NULL;
98  std::string _orig;
99 
100  void* getCurlHandle();
101  static size_t writeHandler(void *ptr, size_t size, size_t nmemb, void *userdata);
102  static size_t headerHandler(void *ptr, size_t size, size_t nmemb, void *userdata);
103 
104  void downloadStarted();
105  void downloadCompleted();
106  void downloadFailed(int errorCode);
107 
108  static void prepareException(ErrorEvent& exception, int errorCode, const std::string& origUri, void* parser);
109 
110  void* _handle = NULL;
111  std::stringstream _rawInContent;
112  std::stringstream _rawInHeader;
113  std::map<std::string, std::string> _inHeaders;
114 
115  std::string _outContent;
116  std::map<std::string, std::string> _outHeader;
117  URLRequestType _requestType;
118 
119  std::string _statusCode;
120  std::string _statusMsg;
121  bool _isDownloaded = false;
122  bool _hasFailed = false;
123  std::string _error;
124 
125  std::condition_variable_any _condVar;
126  std::recursive_mutex _mutex;
127 
128  std::set<URLMonitor*> _monitors;
129 
130  friend class URLFetcher;
131 };
132 
133 class USCXML_API URL {
134 public:
136 
137  URL(const std::string url) : _impl(new URLImpl(url)) {}
138 
143  static std::string getResourceDir();
144 
150  static std::string getTempDir(bool shared = true);
151 
152  bool isAbsolute() {
153  return _impl->isAbsolute();
154  }
155 
156  std::string scheme() {
157  return _impl->scheme();
158  }
159 
160  std::string userInfo() {
161  return _impl->userInfo();
162  }
163 
164  std::string host() {
165  return _impl->host();
166  }
167 
168  std::string port() {
169  return _impl->port();
170  }
171 
172  std::string fragment() {
173  return _impl->fragment();
174  }
175 
176  std::map<std::string, std::string> query() {
177  return _impl->query();
178  }
179 
180  std::string path() {
181  return _impl->path();
182  }
183 
184  std::list<std::string> pathComponents() {
185  return _impl->pathComponents();
186  }
187 
188  void normalize() {
189  return _impl->normalize();
190  }
191 
192  static URL resolve(URL relativeURL, URL absoluteURL) {
193  return URLImpl::resolve(relativeURL._impl.get(), absoluteURL._impl.get());
194  }
195 
196  static URL resolveWithCWD(URL relativeURL) {
197  return URLImpl::resolveWithCWD(relativeURL._impl.get());
198  }
199 
200  static URL refer(URL absoluteSource, URL absoluteBase) {
201  return URLImpl::refer(absoluteSource._impl.get(), absoluteBase._impl.get());
202  }
203 
204  void addOutHeader(const std::string& key, const std::string& value) {
205  return _impl->addOutHeader(key, value);
206  }
207 
208  void setOutContent(const std::string& content) {
209  return _impl->setOutContent(content);
210  }
211  void setRequestType(URLRequestType requestType) {
212  return _impl->setRequestType(requestType);
213  }
214 
215  const std::map<std::string, std::string> getInHeaderFields() {
216  return _impl->getInHeaderFields();
217  }
218 
219  const std::string getInHeaderField(const std::string& key) {
220  return _impl->getInHeaderField(key);
221  }
222 
223  const std::string getStatusCode() const {
224  return _impl->getStatusCode();
225  }
226 
227  const std::string getStatusMessage() const {
228  return _impl->getStatusMessage();
229  }
230 
231  const std::string getInContent(bool forceReload = false) {
232  return _impl->getInContent(forceReload);
233  }
234 
235  const void download(bool blocking = false) const {
236  return _impl->download(blocking);
237  }
238 
239  void addMonitor(URLMonitor* monitor) {
240  return _impl->addMonitor(monitor);
241  }
242  void removeMonitor(URLMonitor* monitor) {
243  return _impl->removeMonitor(monitor);
244  }
245 
246  operator Data() const {
247  return _impl->operator Data();
248  }
249 
250  operator std::string() {
251  return (*_impl.get());
252  }
253 
254 protected:
255  std::shared_ptr<URLImpl> _impl;
256  friend class URLFetcher;
257  static std::string currTmpDir;
258 
259 };
260 
261 class USCXML_API URLFetcher {
262 public:
263  static void fetchURL(URL& url);
264  static void breakURL(URL& url);
265 
266  void start();
267  void stop();
268 
269 protected:
270  URLFetcher();
271  ~URLFetcher();
272 
273  static URLFetcher* _instance;
274  static URLFetcher* getInstance();
275 
276  static void run(void* instance);
277  void perform();
278 
279  std::thread* _thread;
280  std::condition_variable_any _condVar;
281  std::recursive_mutex _mutex;
282  bool _isStarted;
283 
284  std::map<void*, URL> _handlesToURLs;
285  std::map<void*, void*> _handlesToHeaders;
286  void* _multiHandle = NULL;
287  char* _envProxy = NULL;
288 
289 };
290 
291 }
292 
293 #endif /* end of include guard: URL_H_9DAEGSMV */
Definition: URL.h:38
Definition: Breakpoint.cpp:26
Definition: Event.h:211
#define PIMPL_OPERATORS(type)
The usual operators as required for the PIMPL pattern.
Definition: Common.h:68
Definition: URL.h:261
Definition: URL.h:133
Definition: Data.h:44
Definition: URL.h:52