Elma
An event loop manager for embedded systems
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  return *this;
37  }
38 
40 
41  _mtx.lock();
42 
43  for(auto response : _responses ) {
44  std::get<1>(response)(std::get<0>(response));
45  }
46 
47  _responses.clear();
48 
49  _mtx.unlock();
50 
51  return *this;
52 
53  }
54 
55  const std::shared_ptr<httplib::Response> Client::_get_aux(std::string url) {
56  auto parts = url_parts(url);
57 #if CPPHTTPLIB_OPENSSL_SUPPORT
58  if ( _use_ssl ) {
59 
60  httplib::SSLClient cli(parts.first.c_str(), 443);
61  return cli.Get(parts.second.c_str());
62 
63  } else {
64 #endif
65  httplib::Client cli(parts.first.c_str(), 80);
66  return cli.Get(parts.second.c_str());
67 #if CPPHTTPLIB_OPENSSL_SUPPORT
68  }
69 #endif
70  }
71 
72  void Client::_get_thread(std::string url, std::function<void(json&)> handler) {
73 
74  json json_response;
75 
76  try {
77 
78  auto response = _get_aux(url);
79 
80  if (response && response->status == 200) {
81  json_response = json::parse(response->body);
82  } else if ( response ) {
83  std::cout << "Warning:: Elma client connected to "
84  << url
85  << ", which returned Error: "
86  << response->status
87  << std::endl;
88  } else {
89  std::cout << "Warning:: Elma client returned no result"
90  << std::endl;
91  }
92 
93  } catch (const httplib::Exception& e) {
94  std::cout << "Warning: Elma client failed: "
95  << e.what()
96  << "\n";
97  } catch(const json::exception& e ) {
98  std::cout << "Warning: Elma client could not parse response: "
99  << e.what()
100  << "\n";
101  } catch (...) {
102  std::cout << "Warning: Elma client failed with no message\n";
103  }
104 
105  _mtx.lock();
106  _responses.push_back(std::make_tuple(json_response, handler));
107  _mtx.unlock();
108 
109  }
110 
111 };
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: channel.cc:5
Client & process_responses()
Definition: client.cc:39