Skip to content

Commit

Permalink
hotplace rev.460 http
Browse files Browse the repository at this point in the history
  • Loading branch information
princeb612 committed Jan 13, 2024
1 parent 641641f commit defdf8d
Show file tree
Hide file tree
Showing 15 changed files with 229 additions and 41 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
* status
* JOSE ![implemented](https://img.shields.io/badge/implemented-green)
* CBOR ![implemented](https://img.shields.io/badge/implemented-green)
* COSE ![studying](https://img.shields.io/badge/implemented-magenta)
* COSE ![implemented](https://img.shields.io/badge/implemented-green)
* HTTP/1.1,2,3 ![studying](https://img.shields.io/badge/implemented-magenta)

## implemented

Expand Down Expand Up @@ -94,9 +95,9 @@
* RFC 2069 An Extension to HTTP : Digest Access Authentication
* RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
* RFC 7616 HTTP Digest Access Authentication
* merlin project
* sdk/net/http
* test/httpserver
* test/httpget

## not applied

Expand Down
1 change: 1 addition & 0 deletions sdk/base/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ enum errorcode_t {
/* 0xef01002a 4009820202 */ suspicious,
/* 0xef01002b 4009820203 */ unknown,
/* 0xef01002c 4009820204 */ inaccurate,
/* 0xef01002d 4009820205 */ authenticate,

/* 0xef010080 4009820288 */ internal_error_0 = 0xef010080,
/* 0xef010081 4009820289 */ internal_error_1,
Expand Down
2 changes: 2 additions & 0 deletions sdk/base/stream/basic_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,6 @@ bool basic_stream::operator<(basic_stream& obj) { return 0 < strcmp((*this).c_st

bool basic_stream::operator>(basic_stream& obj) { return 0 > strcmp((*this).c_str(), obj.c_str()); }

bool basic_stream::operator==(basic_stream& obj) { return 0 == strcmp((*this).c_str(), obj.c_str()); }

} // namespace hotplace
2 changes: 2 additions & 0 deletions sdk/base/stream/basic_stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ class basic_stream : public stream_t {
*/
bool operator>(basic_stream& obj);

bool operator==(basic_stream& obj);

protected:
bufferio _bio;
bufferio_context_t* _handle;
Expand Down
13 changes: 11 additions & 2 deletions sdk/net/basic/client_socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace hotplace {
namespace net {

client_socket::client_socket() {
client_socket::client_socket() : _ttl(1000) {
// do nothing
}

Expand Down Expand Up @@ -55,7 +55,7 @@ return_t client_socket::close(socket_t sock, tls_context_t* tls_handle) {
return_t client_socket::read(socket_t sock, tls_context_t* tls_handle, char* ptr_data, size_t size_data, size_t* size_read) {
return_t ret = errorcode_t::success;

ret = wait_socket(sock, 1000, SOCK_WAIT_READABLE);
ret = wait_socket(sock, _ttl, SOCK_WAIT_READABLE);
if (errorcode_t::success == ret) {
#if defined _WIN32 || defined _WIN64
int ret_recv = recv(sock, ptr_data, (int)size_data, 0);
Expand Down Expand Up @@ -113,5 +113,14 @@ return_t client_socket::send(socket_t sock, tls_context_t* tls_handle, const cha
return ret;
}

client_socket& client_socket::set_ttl(uint32 milliseconds) {
if (milliseconds) {
_ttl = milliseconds;
}
return *this;
}

uint32 client_socket::get_ttl() { return _ttl; }

} // namespace net
} // namespace hotplace
6 changes: 6 additions & 0 deletions sdk/net/basic/client_socket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ class client_socket {
* @return error code (see error.hpp)
*/
virtual return_t send(socket_t sock, tls_context_t* tls_handle, const char* ptr_data, size_t size_data, size_t* size_sent);

client_socket& set_ttl(uint32 milliseconds);
uint32 get_ttl();

private:
uint32 _ttl; // msec, default 1,000 msec (1 sec)
};

} // namespace net
Expand Down
29 changes: 22 additions & 7 deletions sdk/net/http/http.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ class http_header {
* "cnonce=\"f3806458ed81c203\"";
*
* http_header::to_keyvalue(auth, kv);
* const char* nonce = kv.get("nonce");
* const char* uri = kv.get("uri");
* const char* response = kv.get("response");
* const char* opaque = kv.get("opaque");
* const char* qop = kv.get("qop");
* const char* nc = kv.get("nc");
* const char* cnonce = kv.get("cnonce");
* std::string nonce = kv.get("nonce");
* std::string uri = kv.get("uri");
* std::string response = kv.get("response");
* std::string opaque = kv.get("opaque");
* std::string qop = kv.get("qop");
* std::string nc = kv.get("nc");
* std::string cnonce = kv.get("cnonce");
*/
static return_t to_keyvalue(std::string const& value, key_value& kv);

Expand Down Expand Up @@ -181,6 +181,19 @@ class http_uri {
*/
size_t countof_query();

/*
* @brief conversion
* @param std::string const& value [in]
* @param key_value& kv [out]
* @return error code (see error.hpp)
* @sample
* const char* input = "/resource?client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw";
* http_uri::to_keyvalue(input, kv);
* std::string client_id = kv.get("client_id");
* std::string client_secret = kv.get("client_secret");
*/
static return_t to_keyvalue(std::string const& value, key_value& kv);

void addref();
void release();

Expand Down Expand Up @@ -343,6 +356,7 @@ class http_client {
http_client& request(std::string const& url, http_response** response);
http_client& request(http_request& request, http_response** response);
http_client& close();
http_client& set_ttl(uint32 milliseconds);

protected:
http_client& request_and_response(url_info_t const& url_info, http_request& request, http_response** response);
Expand All @@ -354,6 +368,7 @@ class http_client {
tls_context_t* _tls_context;
SSL_CTX* _x509;
url_info_t _url_info;
uint32 _ttl;
};

} // namespace net
Expand Down
22 changes: 18 additions & 4 deletions sdk/net/http/http_authenticate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,11 +460,25 @@ return_t http_bearer_authenticate_provider::request_auth(network_session* sessio
__leave2;
}

response->get_http_header().add("WWW-Authenticate", format("Bearer realm=\"%s\"", _realm.c_str()));
std::string session_bearer = session->get_session_data()->get("bearer");
if ("access_token" == session_bearer) {
session->get_session_data()->remove("bearer");

int status_code = 401;
std::string body = format("<html><body>%i %s</body></html>", status_code, http_resource::get_instance()->load(status_code).c_str());
response->compose(status_code, "text/html", body.c_str());
openssl_prng prng;
std::string access_token = prng.nonce(16);
std::string refresh_token = prng.nonce(16);
session->get_session_data()->set("access_token", access_token);
session->get_session_data()->set("refresh_token", refresh_token);

response->compose(200, "application/json", "{\"access_token\":\"%s\",\"token_type\":\"Bearer\",\"refresh_token\":\"%s\"}", access_token.c_str(),
refresh_token.c_str());
} else {
response->get_http_header().add("WWW-Authenticate", format("Bearer realm=\"%s\"", _realm.c_str()));

int status_code = 401;
std::string body = format("<html><body>%i %s</body></html>", status_code, http_resource::get_instance()->load(status_code).c_str());
response->compose(status_code, "text/html", body.c_str());
}
}
__finally2 {
// do nothing
Expand Down
14 changes: 12 additions & 2 deletions sdk/net/http/http_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace hotplace {
using namespace io;
namespace net {

http_client::http_client() : _socket(0), _client_socket(nullptr), _tls_context(nullptr), _x509(nullptr) {
http_client::http_client() : _socket(0), _client_socket(nullptr), _tls_context(nullptr), _x509(nullptr), _ttl(1000) {
x509_open_simple(&_x509);
_tls_client_socket = new transport_layer_security_client(new transport_layer_security(_x509));
_client_socket = new client_socket;
Expand Down Expand Up @@ -63,7 +63,10 @@ client_socket* http_client::connect(url_info_t const& url_info) {
// not connected
if (0 == _socket) {
ret = client->connect(&_socket, &_tls_context, url_info.host.c_str(), url_info.port, 5);
_url_info = url_info;
if (errorcode_t::success == ret) {
_url_info = url_info;
client->set_ttl(_ttl);
}
}
}
__finally2 {
Expand Down Expand Up @@ -155,5 +158,12 @@ http_client& http_client::close() {
return *this;
}

http_client& http_client::set_ttl(uint32 milliseconds) {
if (milliseconds) {
_ttl = milliseconds;
}
return *this;
}

} // namespace net
} // namespace hotplace
3 changes: 2 additions & 1 deletion sdk/net/http/http_request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ return_t http_request::open(const char* request, size_t size_request, bool optim
_content.assign(request + epos, size_request - epos);
}

// RFC 6750 2.2. Form-Encoded Body Parameter
if (optimize) {
if (_uri.countof_query()) {
constexpr char constexpr_content_type[] = "Content-Type";
Expand Down Expand Up @@ -161,7 +162,7 @@ http_request& http_request::compose(http_method_t method, std::string const& uri
}
stream << "\r\n" << body;

open(stream, true); // parse and optimize
open(stream, true); // reform if body is empty

return *this;
}
Expand Down
1 change: 1 addition & 0 deletions sdk/net/http/http_response.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ return_t http_response::close() {

_content_type.clear();
_content.clear();
// check... do not clear header

return ret;
}
Expand Down
35 changes: 35 additions & 0 deletions sdk/net/http/http_uri.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,41 @@ return_t http_uri::query(std::string key, std::string& value) {

size_t http_uri::countof_query() { return _query_kv.size(); }

return_t http_uri::to_keyvalue(std::string const& value, key_value& kv) {
return_t ret = errorcode_t::success;

std::string input;
std::string token;
std::string k;
std::string v;
size_t pos = 0;

input = tokenize(value, "?", pos); /* until '?' character */
if (std::string::npos != pos) {
input = value.substr(pos);
}

pos = 0;
while (true) {
token = tokenize(input, "&", pos);

if (token.size() && (std::string::npos != token.find("="))) {
ltrim(rtrim(token));

size_t tpos = 0;
k = tokenize(token, "=", tpos);
v = tokenize(token, "=", tpos);

kv.set(k, v);
}

if ((size_t)-1 == pos) {
break;
}
}
return ret;
}

void http_uri::addref() { _shared.addref(); }

void http_uri::release() { _shared.delref(); }
Expand Down
4 changes: 2 additions & 2 deletions sdk/net/tls/tls_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace hotplace {
namespace net {

transport_layer_security_client::transport_layer_security_client(transport_layer_security* tls) : _tls(tls) {
transport_layer_security_client::transport_layer_security_client(transport_layer_security* tls) : client_socket(), _tls(tls) {
if (nullptr == tls) {
throw errorcode_t::insufficiency;
}
Expand Down Expand Up @@ -75,7 +75,7 @@ return_t transport_layer_security_client::read(socket_t sock, tls_context_t* tls
* in case read 8 bytes and 2 bytes remains, return errorcode_t::more_data
*/
while (true) {
ret = wait_socket(sock, 1000, SOCK_WAIT_READABLE);
ret = wait_socket(sock, get_ttl(), SOCK_WAIT_READABLE);
if (errorcode_t::success == ret) {
ret = _tls->read(tls_handle, tls_io_flag_t::read_ssl_read | tls_io_flag_t::read_bio_write | tls_io_flag_t::read_socket_recv, ptr_data, size_data,
cbread);
Expand Down
Loading

0 comments on commit defdf8d

Please sign in to comment.