Elma
An event loop manager for embedded systems
 All Classes Files Functions Enumerations
client.cc
1 #define CPPHTTPLIB_OPENSSL_SUPPORT
2 #include "httplib/httplib.h"
3 #include "elma.h"
4 #include <thread>
5 #include <tuple>
6 #include <iostream>
7 
8 namespace elma {
9 
10  std::pair<std::string,std::string> Client::url_parts(std::string url) {
11 
12  std::string protocol = url.substr(0,url.find("://"));
13  if ( protocol == "http" ) {
14  _use_ssl = false;
15  } else if ( protocol == "https" ) {
16  _use_ssl = true;
17  } else {
18  throw Exception("Protocol " + protocol + " not implemented in Client.");
19  }
20 
21  std::string rest = url.substr(protocol.length() + 3),
22  addr = rest.substr(0, rest.find("/")),
23  path = rest.substr(addr.length());
24 
25  if ( path == "" ) {
26  path = "/";
27  }
28 
29  return std::make_pair(addr,path);
30 
31  }
32 
33  Client& Client::get(std::string url, std::function<void(json&)> handler) {
34  std::thread t(&Client::_get_thread,this,url,handler);
35  t.detach(); // detaching means we don't have to join later
36  }
37 
39 
40  _mtx.lock();
41 
42  for(auto response : _responses ) {
43  std::get<1>(response)(std::get<0>(response));
44  }
45 
46  _responses.clear();
47 
48  _mtx.unlock();
49 
50  return *this;
51 
52  }
53 
54  const std::shared_ptr<httplib::Response> Client::_get_aux(std::string url) {
55  auto parts = url_parts(url);
56  if ( _use_ssl ) {
57  httplib::SSLClient cli(parts.first.c_str(), 443);
58  return cli.Get(parts.second.c_str());
59  } else {
60  httplib::Client cli(parts.first.c_str(), 80);
61  return cli.Get(parts.second.c_str());
62  }
63  }
64 
65  void Client::_get_thread(std::string url, std::function<void(json&)> handler) {
66 
67  json json_response;
68 
69  try {
70 
71  auto response = _get_aux(url);
72 
73  if (response && response->status == 200) {
74  json_response = json::parse(response->body);
75  } else if ( response ) {
76  std::cout << "Warning:: Elma client connected to a server that returned Error: "
77  << response->status
78  << std::endl;
79  } else {
80  std::cout << "Warning:: Elma client returned no result"
81  << std::endl;
82  }
83 
84  } catch (const httplib::Exception& e) {
85  std::cout << "Warning: Elma client failed: "
86  << e.what()
87  << "\n";
88  } catch(const json::exception& e ) {
89  std::cout << "Warning: Elma client could not parse response: "
90  << e.what()
91  << "\n";
92  } catch (...) {
93  std::cout << "Warning: Elma client failed with no message\n";
94  }
95 
96  _mtx.lock();
97  _responses.push_back(std::make_tuple(json_response, handler));
98  _mtx.unlock();
99 
100  }
101 
102 };
std::pair< std::string, std::string > url_parts(std::string url)
Definition: client.cc:10
An HTTP client for connecting to json services.
Definition: client.h:34
An exception class for Elma.
Definition: exceptions.h:13
Client & get(std::string url, std::function< void(json &)> handler)
Definition: client.cc:33
Definition: manager.h:11
Client & process_responses()
Definition: client.cc:38