Skip to content

Commit 3651b94

Browse files
committed
push incomplete, semi-working, wip code
1 parent 3436d0e commit 3651b94

File tree

14 files changed

+525
-2
lines changed

14 files changed

+525
-2
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,8 @@ target_include_directories(mochios
3333
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib/logger/include>
3434
$<INSTALL_INTERFACE:lib/brewtils/include>
3535
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib/brewtils/include>
36+
$<INSTALL_INTERFACE:lib/brewtils/include>
37+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib/nexus/include>
38+
$<INSTALL_INTERFACE:lib/brewtils/include>
39+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib/json/include>
3640
)

example/main.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1-
#include <logger/log.h>
1+
#include <mochios/client.h>
22

33
int main(int argc, char **argv) {
4-
logger::success("Hello, World!");
4+
mochios::Client client("api.nasa.gov", 443);
5+
mochios::Request request;
6+
request.path = "/planetary/apod";
7+
request.queries["api_key"] = "DEMO_KEY";
8+
9+
mochios::Response response;
10+
client.get(request, response);
11+
12+
std::cout << response.body.dumps(2) << std::endl;
13+
514
return EXIT_SUCCESS;
615
}

include/mochios/client.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#pragma once
2+
3+
#include <arpa/inet.h>
4+
#include <csignal>
5+
#include <functional>
6+
#include <netdb.h>
7+
#include <netinet/in.h>
8+
9+
#include <brewtils/sys.h>
10+
#include <logger/log.h>
11+
#include <nexus/async.h>
12+
13+
#include <mochios/request.h>
14+
#include <mochios/response.h>
15+
#include <mochios/verbs.h>
16+
17+
namespace mochios {
18+
19+
class Client {
20+
private:
21+
int socket;
22+
struct sockaddr_in address;
23+
24+
void send(const std::string &verb, mochios::Request &request,
25+
mochios::Response &response,
26+
std::function<void(mochios::Response &)> callback =
27+
nullptr) noexcept(false);
28+
29+
public:
30+
Client(const std::string &host, const unsigned short &port) noexcept(false);
31+
~Client();
32+
33+
void get(mochios::Request &request, mochios::Response &response,
34+
std::function<void(mochios::Response &)> callback =
35+
nullptr) noexcept(false);
36+
void post(mochios::Request &request, mochios::Response &response,
37+
std::function<void(mochios::Response &)> callback =
38+
nullptr) noexcept(false);
39+
void put(mochios::Request &request, mochios::Response &response,
40+
std::function<void(mochios::Response &)> callback =
41+
nullptr) noexcept(false);
42+
void del(mochios::Request &request, mochios::Response &response,
43+
std::function<void(mochios::Response &)> callback =
44+
nullptr) noexcept(false);
45+
void patch(mochios::Request &request, mochios::Response &response,
46+
std::function<void(mochios::Response &)> callback =
47+
nullptr) noexcept(false);
48+
void options(mochios::Request &request, mochios::Response &response,
49+
std::function<void(mochios::Response &)> callback =
50+
nullptr) noexcept(false);
51+
void head(mochios::Request &request, mochios::Response &response,
52+
std::function<void(mochios::Response &)> callback =
53+
nullptr) noexcept(false);
54+
};
55+
56+
} // namespace mochios

include/mochios/cookie.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
3+
#include <string>
4+
5+
#include <brewtils/url.h>
6+
7+
namespace mochios {
8+
9+
class Cookie {
10+
public:
11+
bool secure;
12+
bool httpOnly;
13+
bool partitioned;
14+
15+
std::string name;
16+
std::string value;
17+
std::string domain;
18+
std::string path;
19+
std::string expires;
20+
std::string maxAge;
21+
std::string sameSite;
22+
23+
Cookie();
24+
~Cookie();
25+
26+
std::string serialize();
27+
};
28+
29+
} // namespace mochios

include/mochios/message.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include <unordered_map>
4+
5+
#include <brewtils/string.h>
6+
#include <json/parse.h>
7+
8+
#include <mochios/cookie.h>
9+
10+
namespace mochios {
11+
12+
class Message {
13+
private:
14+
void parsePath();
15+
void parseHeaders(const std::string &message);
16+
void parseQueries();
17+
void parseBody(const std::string &message);
18+
19+
protected:
20+
std::vector<mochios::Cookie *> cookies;
21+
std::unordered_map<std::string, std::string> headers;
22+
23+
public:
24+
Message();
25+
Message(const std::string &message);
26+
~Message();
27+
28+
std::string path;
29+
json::object body;
30+
std::unordered_map<std::string, std::string> queries;
31+
32+
void set(const std::string &key, const std::string &value);
33+
std::string get(const std::string &key);
34+
35+
std::string stringify();
36+
};
37+
38+
} // namespace mochios

include/mochios/network.h

Whitespace-only changes.

include/mochios/request.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
#include <mochios/message.h>
4+
5+
namespace mochios {
6+
7+
class Request : public Message {
8+
public:
9+
Request();
10+
Request(const std::string &message);
11+
~Request();
12+
};
13+
14+
} // namespace mochios

include/mochios/response.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
#include <mochios/message.h>
4+
5+
namespace mochios {
6+
7+
class Response : public Message {
8+
public:
9+
Response();
10+
Response(const std::string &message);
11+
~Response();
12+
};
13+
14+
} // namespace mochios

include/mochios/verbs.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#pragma once
2+
3+
#include <string>
4+
5+
namespace mochios {
6+
7+
namespace verbs {
8+
9+
static const std::string GET = "GET";
10+
static const std::string POST = "POST";
11+
static const std::string PUT = "PUT";
12+
static const std::string DELETE = "DELETE";
13+
static const std::string PATCH = "PATCH";
14+
static const std::string OPTIONS = "OPTIONS";
15+
static const std::string HEAD = "HEAD";
16+
17+
} // namespace verbs
18+
19+
} // namespace mochios

src/client.cpp

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
#include <mochios/client.h>
2+
3+
void sendHelper(const std::string &verb, mochios::Request &request,
4+
mochios::Response &response, int socket,
5+
std::function<void(mochios::Response &)> callback = nullptr);
6+
7+
mochios::Client::Client(const std::string &host,
8+
const unsigned short &port) noexcept(false) {
9+
signal(SIGPIPE, SIG_IGN);
10+
this->socket = brewtils::sys::socket(AF_INET, SOCK_STREAM, 0);
11+
if (this->socket < 0) {
12+
logger::error("Socket not created!",
13+
"mochios::Client::Client(const std::string &host, const "
14+
"unsigned short &port)");
15+
}
16+
17+
struct addrinfo hints, *result;
18+
memset(&hints, 0, sizeof(hints));
19+
hints.ai_family = AF_INET;
20+
hints.ai_socktype = SOCK_STREAM;
21+
22+
int err = getaddrinfo(host.c_str(), NULL, &hints, &result);
23+
if (err != 0) {
24+
logger::error("DNS lookup failed!",
25+
"mochios::Client::Client(const std::string &host, const "
26+
"unsigned short &port)");
27+
}
28+
29+
// struct sockaddr_in *address = (struct sockaddr_in *)result->ai_addr;
30+
// address->sin_port = htons(port);
31+
32+
struct sockaddr_in *ipv4 = (struct sockaddr_in *)result->ai_addr;
33+
char ipStr[INET_ADDRSTRLEN] = {'\0'};
34+
inet_ntop(result->ai_family, &(ipv4->sin_addr), ipStr, sizeof(ipStr));
35+
36+
logger::info("IP address is: " + std::string(ipStr),
37+
"mochios::Client::Client(const std::string &host, const "
38+
"unsigned short &port)");
39+
40+
this->address.sin_family = AF_INET;
41+
this->address.sin_port = htons(port);
42+
this->address.sin_addr = ipv4->sin_addr;
43+
return;
44+
}
45+
46+
mochios::Client::~Client() { return; }
47+
48+
void mochios::Client::get(
49+
mochios::Request &request, mochios::Response &response,
50+
std::function<void(mochios::Response &)> callback) noexcept(false) {
51+
return this->send(mochios::verbs::GET, request, response, callback);
52+
};
53+
54+
void mochios::Client::post(
55+
mochios::Request &request, mochios::Response &response,
56+
std::function<void(mochios::Response &)> callback) noexcept(false) {
57+
return this->send(mochios::verbs::GET, request, response, callback);
58+
};
59+
60+
void mochios::Client::put(
61+
mochios::Request &request, mochios::Response &response,
62+
std::function<void(mochios::Response &)> callback) noexcept(false) {
63+
return this->send(mochios::verbs::GET, request, response, callback);
64+
};
65+
66+
void mochios::Client::del(
67+
mochios::Request &request, mochios::Response &response,
68+
std::function<void(mochios::Response &)> callback) noexcept(false) {
69+
return this->send(mochios::verbs::GET, request, response, callback);
70+
};
71+
72+
void mochios::Client::patch(
73+
mochios::Request &request, mochios::Response &response,
74+
std::function<void(mochios::Response &)> callback) noexcept(false) {
75+
return this->send(mochios::verbs::GET, request, response, callback);
76+
};
77+
78+
void mochios::Client::options(
79+
mochios::Request &request, mochios::Response &response,
80+
std::function<void(mochios::Response &)> callback) noexcept(false) {
81+
return this->send(mochios::verbs::GET, request, response, callback);
82+
};
83+
84+
void mochios::Client::head(
85+
mochios::Request &request, mochios::Response &response,
86+
std::function<void(mochios::Response &)> callback) noexcept(false) {
87+
return this->send(mochios::verbs::GET, request, response, callback);
88+
};
89+
90+
void mochios::Client::send(
91+
const std::string &verb, mochios::Request &request,
92+
mochios::Response &response,
93+
std::function<void(mochios::Response &)> callback) noexcept(false) {
94+
if (::connect(this->socket, (struct sockaddr *)&this->address,
95+
sizeof(this->address)) < 0) {
96+
logger::error("Connection failed!",
97+
"mochios::Client::send(const std::string &verb, "
98+
"mochios::Request &request, mochios::Response &response, "
99+
"std::function<void(mochios::Response &)> callback)");
100+
}
101+
102+
if (callback == nullptr) {
103+
sendHelper(verb, request, response, this->socket);
104+
} else {
105+
nexus::async(sendHelper, verb, std::ref(request), std::ref(response),
106+
this->socket, callback);
107+
}
108+
return;
109+
}
110+
111+
void sendHelper(const std::string &verb, mochios::Request &request,
112+
mochios::Response &response, int socket,
113+
std::function<void(mochios::Response &)> callback) {
114+
std::string headers = verb + " " + request.path + " HTTP/1.1\r\n";
115+
headers += request.stringify();
116+
std::string body = request.body.dumps(0);
117+
118+
if (brewtils::sys::send(socket, headers.c_str(), headers.size(), 0) < 0) {
119+
logger::error(
120+
"Send failed!",
121+
"mochios::Client::sendHelper(const std::string &verb, mochios::Request "
122+
"&request, mochios::Response &response, int socket, "
123+
"std::function<void(mochios::Response "
124+
"&)> callback)");
125+
}
126+
if (brewtils::sys::send(socket, body.c_str(), body.size(), 0) < 0) {
127+
logger::error(
128+
"Send failed!",
129+
"mochios::Client::sendHelper(const std::string &verb, mochios::Request "
130+
"&request, mochios::Response &response, int socket, "
131+
"std::function<void(mochios::Response "
132+
"&)> callback)");
133+
}
134+
135+
char buffer[4096] = {0};
136+
if (brewtils::sys::recv(socket, buffer, 4096, 0) < 0) {
137+
logger::error(
138+
"Receive failed!",
139+
"mochios::Client::sendHelper(const std::string &verb, mochios::Request "
140+
"&request, mochios::Response &response, int socket, "
141+
"std::function<void(mochios::Response "
142+
"&)> callback)");
143+
}
144+
145+
::close(socket);
146+
std::cout << buffer << std::endl;
147+
response = mochios::Response(buffer);
148+
if (callback != nullptr) {
149+
callback(response);
150+
}
151+
152+
return;
153+
}

0 commit comments

Comments
 (0)