AOSharedServiceLibrary
base_http_client.h
1 /*
2 MIT License Block
3 
4 Copyright (c) 2016 Alex Barry
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 */
24 
25 #include <string>
26 
27 #include "aossl/core/include/buffers.h"
28 
29 #include "Poco/StreamCopier.h"
30 #include "Poco/URI.h"
31 #include "Poco/Net/Context.h"
32 #include "Poco/Net/HTTPRequest.h"
33 #include "Poco/Net/HTTPSClientSession.h"
34 #include "Poco/Net/HTTPResponse.h"
35 #include "Poco/Net/SSLException.h"
36 
37 #ifndef AOSSL_CORE_INCLUDE_BASE_HTTP_CLIENT_H_
38 #define AOSSL_CORE_INCLUDE_BASE_HTTP_CLIENT_H_
39 
40 namespace AOSSL {
41 
43 
47  int timeout;
48  bool secured = false;
49  bool use_acl = false;
50  std::string cert_location;
51  std::string http_addr;
52  std::string acl_token;
53  std::string acl_token_name;
54  inline void init(std::string& vaddr, int tout) {
55  timeout=tout;
56  http_addr.assign(vaddr);
57  }
58  inline void get_http_response(Poco::Net::HTTPClientSession& session, \
59  AOSSL::StringBuffer& ret_buffer) {
60  Poco::Net::HTTPResponse res;
61  std::istream& rs = session.receiveResponse(res);
62  if (res.getStatus() > Poco::Net::HTTPResponse::HTTP_PARTIAL_CONTENT) {
63  ret_buffer.success = false;
64  ret_buffer.err_msg.assign("Error sending message to Vault: " + res.getReason());
65  } else {
66  std::istreambuf_iterator<char> eos;
67  std::string resp(std::istreambuf_iterator<char>(rs), eos);
68  ret_buffer.success = true;
69  ret_buffer.val.assign(resp);
70  }
71  }
72  inline void send_http_request(Poco::Net::HTTPClientSession& session, \
73  Poco::Net::HTTPRequest& req, AOSSL::StringBuffer& ret_buffer) {
74  session.sendRequest(req);
75  get_http_response(session, ret_buffer);
76  }
77  inline void send_http_request(Poco::Net::HTTPClientSession& session, \
78  Poco::Net::HTTPRequest& req, std::string& body, AOSSL::StringBuffer& ret_buffer) {
79  req.setContentLength(body.length());
80  session.sendRequest(req) << body;
81  get_http_response(session, ret_buffer);
82  }
83  inline void create_and_send_request(std::string& req_type, bool use_body, \
84  std::string& query_url, std::string& body, AOSSL::StringBuffer& ret_buffer) {
85  ret_buffer.success = false;
86  try {
87  // Build the base HTTP Request
88  const Poco::URI uri( http_addr );
89  Poco::Net::HTTPRequest req(req_type, query_url );
90  // Add the acl token if it's been added
91  if (use_acl) {
92  req.add(acl_token_name, acl_token);
93  }
94  // Send the request over a secured/unsecured socket based on config
95  if (secured) {
96  const Poco::Net::Context::Ptr context( new Poco::Net::Context( \
97  Poco::Net::Context::CLIENT_USE, "", cert_location, "", \
98  Poco::Net::Context::VerificationMode::VERIFY_NONE ) );
99  Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), context );
100  if (use_body) {
101  send_http_request(session, req, body, ret_buffer);
102  } else {
103  send_http_request(session, req, ret_buffer);
104  }
105  } else {
106  Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
107  if (use_body) {
108  send_http_request(session, req, body, ret_buffer);
109  } else {
110  send_http_request(session, req, ret_buffer);
111  }
112  }
113  } catch( const Poco::Net::SSLException& e ) {
114  ret_buffer.success = false;
115  ret_buffer.err_msg.assign(e.message());
116  } catch( const std::exception& e ) {
117  ret_buffer.success = false;
118  ret_buffer.err_msg.assign(e.what());
119  }
120  }
121  public:
123  BaseHttpClient(std::string& vaddr, int tout, std::string& cert) \
124  {init(vaddr, tout);secured=true;cert_location.assign(cert);}
126  BaseHttpClient(std::string& vaddr, int tout) \
127  {init(vaddr, tout);}
128  ~BaseHttpClient() {}
129 
130  // View configuration elements
131  std::string get_address() {return http_addr;}
132  std::string get_ssl_cert() {return cert_location;}
133  std::string get_acl_token() {return acl_token;}
134 
136  inline void put_by_reference(std::string& query_url, std::string& body, \
137  AOSSL::StringBuffer& ret_buffer) {
138  std::string req_type = Poco::Net::HTTPRequest::HTTP_PUT;
139  create_and_send_request(req_type, true, query_url, body, ret_buffer);
140  }
142  inline void post_by_reference(std::string& query_url, std::string& body, \
143  AOSSL::StringBuffer& ret_buffer) {
144  std::string req_type = Poco::Net::HTTPRequest::HTTP_POST;
145  create_and_send_request(req_type, true, query_url, body, ret_buffer);
146  }
148  inline void get_by_reference(std::string& query_url, AOSSL::StringBuffer& ret_buffer) {
149  std::string body = "";
150  std::string req_type = Poco::Net::HTTPRequest::HTTP_GET;
151  create_and_send_request(req_type, false, query_url, body, ret_buffer);
152  }
154  inline void delete_by_reference(std::string& query_url, AOSSL::StringBuffer& ret_buffer) {
155  std::string body = "";
156  std::string req_type = Poco::Net::HTTPRequest::HTTP_DELETE;
157  create_and_send_request(req_type, false, query_url, body, ret_buffer);
158  }
160  inline void set_acl_token(std::string token_name, std::string new_token) {
161  acl_token.assign(new_token);
162  acl_token_name.assign(token_name);
163  use_acl = true;
164  }
165 };
166 
167 } // namespace AOSSL
168 
169 #endif // AOSSL_CORE_INCLUDE_BASE_HTTP_CLIENT_H_
A Structure for holding a single value.
Definition: buffers.h:42
std::string val
Value stored.
Definition: buffers.h:44
void post_by_reference(std::string &query_url, std::string &body, AOSSL::StringBuffer &ret_buffer)
Execute a Post query.
Definition: base_http_client.h:142
void delete_by_reference(std::string &query_url, AOSSL::StringBuffer &ret_buffer)
Execute a Delete query.
Definition: base_http_client.h:154
BaseHttpClient(std::string &vaddr, int tout, std::string &cert)
Construct a secured HTTP Client.
Definition: base_http_client.h:123
BaseHttpClient(std::string &vaddr, int tout)
Construct an unsecured HTTP Client.
Definition: base_http_client.h:126
void set_acl_token(std::string token_name, std::string new_token)
Add an ACL Token.
Definition: base_http_client.h:160
bool success
Success flag.
Definition: buffers.h:35
void put_by_reference(std::string &query_url, std::string &body, AOSSL::StringBuffer &ret_buffer)
Execute a Put query.
Definition: base_http_client.h:136
void get_by_reference(std::string &query_url, AOSSL::StringBuffer &ret_buffer)
Execute a Get query.
Definition: base_http_client.h:148
std::string err_msg
Error Message.
Definition: buffers.h:38
Base HTTP Client.
Definition: base_http_client.h:46
Definition: cli.h:35