Fix indent trouble

This commit is contained in:
jbnadal
2018-04-24 18:22:59 +02:00
parent b1b3f8742c
commit f2a9e3c9c7
29 changed files with 594 additions and 676 deletions

View File

@@ -74,7 +74,6 @@ void HttpHeader::send(uhttpd_ops *an_ops, client *a_client, uint16_t a_code, boo
if (!m_etag.empty()) if (!m_etag.empty())
{ {
ustream_printf(a_client->us, "ETag: %s\r\n", m_etag.c_str()); ustream_printf(a_client->us, "ETag: %s\r\n", m_etag.c_str());
} }

View File

@@ -34,24 +34,24 @@ struct uhttpd_ops;
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class HttpHeader { class HttpHeader
{
public:
HttpHeader(void);
HttpHeader(uint16_t a_timeout);
public: void send(uhttpd_ops *an_ops, client *a_client, uint16_t a_code, bool a_chunked = false);
HttpHeader (void); void send_option(uhttpd_ops *an_ops, client *a_client, uint16_t a_code);
HttpHeader (uint16_t a_timeout);
void send (uhttpd_ops *an_ops, client *a_client, uint16_t a_code, bool a_chunked = false); void add_origin(const std::string &an_origin);
void send_option (uhttpd_ops *an_ops, client *a_client, uint16_t a_code); void add_etag(const std::string &an_etag);
void add_timeout(uint16_t a_timeout);
void add_origin (const std::string &an_origin); private:
void add_etag (const std::string &an_etag); bool use_chunked(struct client *a_client);
void add_timeout (uint16_t a_timeout); void prepare_header(struct client *a_client, int a_code, const std::string &a_summary);
private: private:
bool use_chunked (struct client *a_client);
void prepare_header (struct client *a_client, int a_code, const std::string &a_summary);
private:
std::string m_etag; std::string m_etag;
std::string m_origin; std::string m_origin;
uint16_t m_timeout; uint16_t m_timeout;

View File

@@ -34,28 +34,25 @@ extern "C" {
#include "http-parameter.h" #include "http-parameter.h"
#define kIfNoneMatch "if-none-match"
#define kIfNoneMatch "if-none-match" #define kPrefer "prefer"
#define kPrefer "prefer" #define kOrigin "origin"
#define kOrigin "origin"
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn HttpParameter * @fn HttpParameter
* *
* @brief constructor of the http parameter. * @brief constructor of the http parameter.
*/ */
HttpParameter::HttpParameter (void) : HttpParameter::HttpParameter(void) : m_request_timeout(-1)
m_request_timeout(-1)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn parse_from_uri * @fn parse_from_uri
* *
* @brief parse parameters from the uri. * @brief parse parameters from the uri.
*/ */
std::string HttpParameter::parse_from_uri (const std::string &a_parameters) std::string HttpParameter::parse_from_uri(const std::string &a_parameters)
{ {
std::string the_result; std::string the_result;
std::vector<std::string> the_list; std::vector<std::string> the_list;
@@ -66,13 +63,13 @@ std::string HttpParameter::parse_from_uri (const std::string &a_parameters)
the_root_node = json_object_new_object(); the_root_node = json_object_new_object();
the_list = split_params(a_parameters, '&'); the_list = split_params(a_parameters, '&');
for (the_it = the_list.begin(); the_it != the_list.end(); ++the_it) { for (the_it = the_list.begin(); the_it != the_list.end(); ++the_it)
{
// printf("--> %s\n", (*the_it).c_str()); // printf("--> %s\n", (*the_it).c_str());
the_pos = (*the_it).find_first_of("=", 0); the_pos = (*the_it).find_first_of("=", 0);
if (the_pos != std::string::npos) { if (the_pos != std::string::npos)
{
the_key = (*the_it).substr(0, the_pos); the_key = (*the_it).substr(0, the_pos);
the_value = (*the_it).substr(the_pos + 1); the_value = (*the_it).substr(the_pos + 1);
the_value_decoded = UriTransform::decode(the_value); the_value_decoded = UriTransform::decode(the_value);
@@ -100,13 +97,12 @@ std::string HttpParameter::parse_from_uri (const std::string &a_parameters)
return the_result; return the_result;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn parse * @fn parse
* *
* @brief parse the http header and save only the wanted headers. * @brief parse the http header and save only the wanted headers.
*/ */
bool HttpParameter::parse (client *a_client) bool HttpParameter::parse(client *a_client)
{ {
std::string the_prefer_string; std::string the_prefer_string;
char *the_string = blobmsg_format_json(a_client->hdr.head, true); char *the_string = blobmsg_format_json(a_client->hdr.head, true);
@@ -116,37 +112,37 @@ bool HttpParameter::parse (client *a_client)
// printf("HttpParameter::parse: <%s>\n", the_string); // printf("HttpParameter::parse: <%s>\n", the_string);
free(the_string); free(the_string);
if (the_root_node == NULL) { if (the_root_node == NULL)
{
return false; return false;
} }
// Get if-none-match // Get if-none-match
if (json_object_object_get_ex(the_root_node, kIfNoneMatch, &the_value_node)) { if (json_object_object_get_ex(the_root_node, kIfNoneMatch, &the_value_node))
{
m_etag = json_object_get_string(the_value_node); m_etag = json_object_get_string(the_value_node);
} }
// Get Prefer - wait RFC 7240 // Prefer: wait=120 // Get Prefer - wait RFC 7240 // Prefer: wait=120
if (json_object_object_get_ex(the_root_node, kPrefer, &the_value_node)) { if (json_object_object_get_ex(the_root_node, kPrefer, &the_value_node))
{
std::vector<std::string> the_list; std::vector<std::string> the_list;
the_prefer_string = json_object_get_string(the_value_node); the_prefer_string = json_object_get_string(the_value_node);
the_list = split_params(the_prefer_string, '='); the_list = split_params(the_prefer_string, '=');
std::string the_token = the_list [1]; std::string the_token = the_list[1];
//printf("the_prefer_string: %s\n", the_prefer_string.c_str()); //printf("the_prefer_string: %s\n", the_prefer_string.c_str());
//printf("the_token: %s\n", the_token.c_str()); //printf("the_token: %s\n", the_token.c_str());
if (is_number(the_token)) { if (is_number(the_token))
{
m_request_timeout = std::atoi(the_token.c_str()); m_request_timeout = std::atoi(the_token.c_str());
} }
// printf("timeout = %d\n", m_request_timeout); // printf("timeout = %d\n", m_request_timeout);
} }
// Get Origin // Get Origin
if (json_object_object_get_ex(the_root_node, kOrigin, &the_value_node)) { if (json_object_object_get_ex(the_root_node, kOrigin, &the_value_node))
{
m_origin = json_object_get_string(the_value_node); m_origin = json_object_get_string(the_value_node);
} }
@@ -157,55 +153,51 @@ bool HttpParameter::parse (client *a_client)
return true; return true;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_origin * @fn get_origin
* *
* @brief get the etag from the header request. * @brief get the etag from the header request.
*/ */
std::string HttpParameter::get_origin (void) std::string HttpParameter::get_origin(void)
{ {
return m_origin; return m_origin;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_etag * @fn get_etag
* *
* @brief get the etag from the header request. * @brief get the etag from the header request.
*/ */
std::string HttpParameter::get_etag (void) std::string HttpParameter::get_etag(void)
{ {
return m_etag; return m_etag;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_request_timeout * @fn get_request_timeout
* *
* @brief extract the the keep-alive timeout from the header (as second) * @brief extract the the keep-alive timeout from the header (as second)
* and return it as millisecond timeout. * and return it as millisecond timeout.
*/ */
int16_t HttpParameter::get_request_timeout (void) int16_t HttpParameter::get_request_timeout(void)
{ {
return m_request_timeout; return m_request_timeout;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn split_params * @fn split_params
* *
* @brief method to split a string into sub string from a separator. and return a * @brief method to split a string into sub string from a separator. and return a
* vector from all the substrings. * vector from all the substrings.
*/ */
std::vector<std::string> HttpParameter::split_params (const std::string &a_string, char a_seperator) std::vector<std::string> HttpParameter::split_params(const std::string &a_string, char a_seperator)
{ {
std::vector<std::string> the_output; std::vector<std::string> the_output;
std::string::size_type the_prev_pos = 0, the_pos = 0; std::string::size_type the_prev_pos = 0, the_pos = 0;
while ((the_pos = a_string.find(a_seperator, the_pos)) != std::string::npos) { while ((the_pos = a_string.find(a_seperator, the_pos)) != std::string::npos)
{
std::string substring(a_string.substr(the_prev_pos, the_pos - the_prev_pos)); std::string substring(a_string.substr(the_prev_pos, the_pos - the_prev_pos));
the_output.push_back(substring); the_output.push_back(substring);
the_prev_pos = ++the_pos; the_prev_pos = ++the_pos;
@@ -216,15 +208,14 @@ std::vector<std::string> HttpParameter::split_params (const std::string &a_strin
return the_output; return the_output;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn is_number * @fn is_number
* *
* @brief return true if the string given has parameter is a number. * @brief return true if the string given has parameter is a number.
*/ */
bool HttpParameter::is_number (const std::string & a_string) bool HttpParameter::is_number(const std::string &a_string)
{ {
char* p; char *p;
strtod (a_string.c_str(), &p); strtod(a_string.c_str(), &p);
return *p == 0; return *p == 0;
} }

View File

@@ -36,26 +36,26 @@ struct client;
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class HttpParameter { class HttpParameter
{
public:
HttpParameter(void);
public: std::string parse_from_uri(const std::string &a_parameters);
HttpParameter (void);
std::string parse_from_uri (const std::string &a_parameters); bool parse(client *a_client);
bool parse (client *a_client); std::string get_origin(void);
std::string get_etag(void);
int16_t get_request_timeout(void);
std::string get_origin (void); private:
std::string get_etag (void); std::vector<std::string> split_params(const std::string &a_string, char a_seperator);
int16_t get_request_timeout (void); bool is_number(const std::string &a_string);
private:
std::vector<std::string> split_params (const std::string &a_string, char a_seperator);
bool is_number (const std::string & a_string);
std::string m_origin; std::string m_origin;
std::string m_etag; std::string m_etag;
int16_t m_request_timeout; int16_t m_request_timeout;
}; };
#endif /* _HTTP_PARAMETERS_H */ #endif /* _HTTP_PARAMETERS_H */

View File

@@ -24,25 +24,24 @@
#include "http-reason.h" #include "http-reason.h"
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn HttpReason * @fn HttpReason
* *
* @brief constructor of the http reason. * @brief constructor of the http reason.
*/ */
HttpReason::HttpReason (void) HttpReason::HttpReason(void)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get * @fn get
* *
* @brief return as string the reazson from the http code. * @brief return as string the reazson from the http code.
*/ */
std::string HttpReason::get (uint16_t a_code) std::string HttpReason::get(uint16_t a_code)
{ {
switch (a_code) { switch (a_code)
{
// --- 100 // --- 100
case 100: case 100:
return "Continue"; return "Continue";

View File

@@ -30,12 +30,12 @@
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class HttpReason { class HttpReason
{
public:
HttpReason(void);
public: static std::string get(uint16_t a_code);
HttpReason (void);
static std::string get (uint16_t a_code);
}; };
#endif /* _HTTP_REASON_H */ #endif /* _HTTP_REASON_H */

View File

@@ -30,58 +30,56 @@ extern "C" {
#include "ubus-reason.h" #include "ubus-reason.h"
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn UbusReason * @fn UbusReason
* *
* @brief constructor of the ubus reason. * @brief constructor of the ubus reason.
*/ */
UbusReason::UbusReason (void) UbusReason::UbusReason(void)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get * @fn get
* *
* @brief return as an http code from an ubus code. * @brief return as an http code from an ubus code.
*/ */
uint16_t UbusReason::get (int16_t an_exec_result) uint16_t UbusReason::get(int16_t an_exec_result)
{ {
int the_result_code; int the_result_code;
// printf("%s result code: %d\n", __PRETTY_FUNCTION__, an_exec_result); // printf("%s result code: %d\n", __PRETTY_FUNCTION__, an_exec_result);
switch (an_exec_result) { switch (an_exec_result)
{
case 0: case 0:
the_result_code = 200; // HTTP_OK the_result_code = 200; // HTTP_OK
break; break;
case -1: case -1:
the_result_code = 404; // HTTP_NOT_FOUND the_result_code = 404; // HTTP_NOT_FOUND
break; break;
case -2: case -2:
the_result_code = 507; // HTTP_INSUFFICIENT_STORAGE the_result_code = 507; // HTTP_INSUFFICIENT_STORAGE
break; break;
case UBUS_STATUS_METHOD_NOT_FOUND: case UBUS_STATUS_METHOD_NOT_FOUND:
the_result_code = 405; // HTTP_METHOD_NOT_ALLOWED the_result_code = 405; // HTTP_METHOD_NOT_ALLOWED
break; break;
case -3: case -3:
the_result_code = 500; // HTTP_INTERNAL_SERVER_ERROR the_result_code = 500; // HTTP_INTERNAL_SERVER_ERROR
break; break;
case -4: // NotImplemented case -4: // NotImplemented
case 4: case 4:
the_result_code = 501; // HTTP_NOT_IMPLEMENTED the_result_code = 501; // HTTP_NOT_IMPLEMENTED
break; break;
case kExecInvalidArguments: case kExecInvalidArguments:
case UBUS_STATUS_INVALID_ARGUMENT: case UBUS_STATUS_INVALID_ARGUMENT:
the_result_code = 412; // HTTP_PRECONDITION_FAILED the_result_code = 412; // HTTP_PRECONDITION_FAILED
break; break;
case kExecFailed: case kExecFailed:
the_result_code = 400; // HTTP_BAD_REQUEST the_result_code = 400; // HTTP_BAD_REQUEST
break; break;
default: default:
the_result_code = 500; // HTTP_INTERNAL_SERVER_ERROR the_result_code = 500; // HTTP_INTERNAL_SERVER_ERROR
break; break;
} }
return the_result_code; return the_result_code;

View File

@@ -30,12 +30,12 @@
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class UbusReason { class UbusReason
{
public:
UbusReason(void);
public: static uint16_t get(int16_t an_exec_result);
UbusReason (void);
static uint16_t get (int16_t an_exec_result);
}; };
#endif /* _UBUS_REASON_H */ #endif /* _UBUS_REASON_H */

View File

@@ -24,81 +24,78 @@
#include "uri-transform.h" #include "uri-transform.h"
// Only alphanum is safe. // Only alphanum is safe.
const char SAFE[256] = const char SAFE[256] =
{ {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, /* 3 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
/* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, /* 4 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, /* 5 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
/* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, /* 6 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, /* 7 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
/* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* A */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* B */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* C */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* D */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* E */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 /* F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
};
const int8_t HEX2DEC[256] = const int8_t HEX2DEC[256] =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* 0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 1 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 2 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
/* 4 */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 5 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 6 */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 7 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 8 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 9 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* A */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* B */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* C */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* D */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* E */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
std::string iso_8859_1_to_utf8(std::string str)
{ {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ std::string strOut;
/* 0 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, for (std::string::iterator it = str.begin(); it != str.end(); ++it)
/* 1 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, {
/* 2 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, uint8_t ch = *it;
/* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1, -1,-1,-1,-1, if (ch < 0x80)
{
/* 4 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1, strOut.push_back(ch);
/* 5 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, }
/* 6 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1, else
/* 7 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, {
strOut.push_back(0xc0 | ch >> 6);
/* 8 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, strOut.push_back(0x80 | (ch & 0x3f));
/* 9 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, }
/* A */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, }
/* B */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, return strOut;
/* C */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
/* D */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
/* E */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
/* F */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
};
std::string iso_8859_1_to_utf8 (std::string str)
{
std::string strOut;
for (std::string::iterator it = str.begin(); it != str.end(); ++it)
{
uint8_t ch = *it;
if (ch < 0x80) {
strOut.push_back(ch);
}
else {
strOut.push_back(0xc0 | ch >> 6);
strOut.push_back(0x80 | (ch & 0x3f));
}
}
return strOut;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn UriTransform * @fn UriTransform
* *
* @brief class to encode and decode a string from an uri. * @brief class to encode and decode a string from an uri.
*/ */
UriTransform::UriTransform (void) UriTransform::UriTransform(void)
{ {
} }
@@ -107,21 +104,21 @@ UriTransform::UriTransform (void)
* *
* @brief Encode A string. * @brief Encode A string.
*/ */
std::string UriTransform::encode (const std::string &a_src) std::string UriTransform::encode(const std::string &a_src)
{ {
const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; const char DEC2HEX[16 + 1] = "0123456789ABCDEF";
const unsigned char * p_src = (const unsigned char *)a_src.c_str(); const unsigned char *p_src = (const unsigned char *)a_src.c_str();
const int SRC_LEN = a_src.length(); const int SRC_LEN = a_src.length();
unsigned char * const p_start = new unsigned char[SRC_LEN * 3]; unsigned char *const p_start = new unsigned char[SRC_LEN * 3];
unsigned char * p_end = p_start; unsigned char *p_end = p_start;
const unsigned char * const SRC_END = p_src + SRC_LEN; const unsigned char *const SRC_END = p_src + SRC_LEN;
for (; p_src < SRC_END; ++p_src) {
for (; p_src < SRC_END; ++p_src)
{
if (SAFE[*p_src]) if (SAFE[*p_src])
*p_end++ = *p_src; *p_end++ = *p_src;
else { else
{
// escape this char // escape this char
*p_end++ = '%'; *p_end++ = '%';
*p_end++ = DEC2HEX[*p_src >> 4]; *p_end++ = DEC2HEX[*p_src >> 4];
@@ -130,38 +127,36 @@ std::string UriTransform::encode (const std::string &a_src)
} }
std::string s_result((char *)p_start, (char *)p_end); std::string s_result((char *)p_start, (char *)p_end);
delete [] p_start; delete[] p_start;
return s_result; return s_result;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn decode * @fn decode
* *
* @brief Decode a String * @brief Decode a String
*/ */
std::string UriTransform::decode (const std::string &a_src) std::string UriTransform::decode(const std::string &a_src)
{ {
// Note from RFC1630: "Sequences which start with a percent sign // Note from RFC1630: "Sequences which start with a percent sign
// but are not followed by two hexadecimal characters (0-9, A-F) are reserved // but are not followed by two hexadecimal characters (0-9, A-F) are reserved
// for future extension" // for future extension"
const unsigned char * p_src = (const unsigned char *)a_src.c_str(); const unsigned char *p_src = (const unsigned char *)a_src.c_str();
const int SRC_LEN = a_src.length(); const int SRC_LEN = a_src.length();
const unsigned char * const SRC_END = p_src + SRC_LEN; const unsigned char *const SRC_END = p_src + SRC_LEN;
const unsigned char * const SRC_LAST_DEC = SRC_END - 2; // last decodable '%' const unsigned char *const SRC_LAST_DEC = SRC_END - 2; // last decodable '%'
char * const p_start = new char[SRC_LEN]; char *const p_start = new char[SRC_LEN];
char * p_end = p_start; char *p_end = p_start;
while (p_src < SRC_LAST_DEC) {
if (*p_src == '%') {
while (p_src < SRC_LAST_DEC)
{
if (*p_src == '%')
{
char dec1, dec2; char dec1, dec2;
if (-1 != (dec1 = HEX2DEC[*(p_src + 1)]) if (-1 != (dec1 = HEX2DEC[*(p_src + 1)]) && -1 != (dec2 = HEX2DEC[*(p_src + 2)]))
&& -1 != (dec2 = HEX2DEC[*(p_src + 2)])) { {
*p_end++ = (dec1 << 4) + dec2; *p_end++ = (dec1 << 4) + dec2;
p_src += 3; p_src += 3;
continue; continue;
@@ -176,7 +171,7 @@ std::string UriTransform::decode (const std::string &a_src)
*p_end++ = *p_src++; *p_end++ = *p_src++;
std::string s_result(p_start, p_end); std::string s_result(p_start, p_end);
delete [] p_start; delete[] p_start;
//char *theData = awUTF_ISO88591ToUTF8 (sResult.c_str(), sResult.length()); //char *theData = awUTF_ISO88591ToUTF8 (sResult.c_str(), sResult.length());

View File

@@ -30,13 +30,13 @@
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class UriTransform { class UriTransform
{
public:
UriTransform(void);
public: static std::string encode(const std::string &a_src);
UriTransform (void); static std::string decode(const std::string &a_src);
static std::string encode (const std::string &a_src);
static std::string decode (const std::string &a_src);
}; };
#endif /* _URI_TRANSFORM_H */ #endif /* _URI_TRANSFORM_H */

View File

@@ -27,71 +27,64 @@
#include "core/web-connection.h" #include "core/web-connection.h"
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn WebConnection * @fn WebConnection
* *
* @brief constructor of the web connection object. * @brief constructor of the web connection object.
*/ */
WebConnection::WebConnection (struct uhttpd_ops *an_ops, struct client *a_client) : WebConnection::WebConnection(struct uhttpd_ops *an_ops, struct client *a_client) : m_ops(an_ops),
m_ops(an_ops), m_client(a_client),
m_client(a_client), m_should_be_removed(true)
m_should_be_removed(true)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn ~WebConnection * @fn ~WebConnection
* *
* @brief destructor of the web connection object. * @brief destructor of the web connection object.
*/ */
WebConnection::~WebConnection (void) WebConnection::~WebConnection(void)
{ {
// printf("WebConnection:: desctructor....\n"); // printf("WebConnection:: desctructor....\n");
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn add_data * @fn add_data
* *
* @brief add data to the request. * @brief add data to the request.
*/ */
int WebConnection::add_data (const char *a_data, int a_len) int WebConnection::add_data(const char *a_data, int a_len)
{ {
m_connection_data += a_data; m_connection_data += a_data;
return a_len; return a_len;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_client * @fn get_client
* *
* @brief return pointer on the client object. * @brief return pointer on the client object.
*/ */
struct client * WebConnection::get_client (void) struct client *WebConnection::get_client(void)
{ {
return m_client; return m_client;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn invoke * @fn invoke
* *
* @brief invoke a web connection. * @brief invoke a web connection.
*/ */
void WebConnection::invoke (struct ubus_context *a_ctx) void WebConnection::invoke(struct ubus_context *a_ctx)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn should_be_removed * @fn should_be_removed
* *
* @brief return true if the connection should be removed. * @brief return true if the connection should be removed.
*/ */
bool WebConnection::should_be_removed (void) bool WebConnection::should_be_removed(void)
{ {
return m_should_be_removed; return m_should_be_removed;
} }

View File

@@ -35,27 +35,26 @@ struct ubus_context;
/*----------------------------- Dependencies --------------------------------*/ /*----------------------------- Dependencies --------------------------------*/
#define kEvent_status_entry "status" #define kEvent_status_entry "status"
#define kEvent_version_entry "version" #define kEvent_version_entry "version"
#define kEvent_content_entry "content" #define kEvent_content_entry "content"
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class WebConnection { class WebConnection
{
public:
WebConnection(struct uhttpd_ops *an_ops, struct client *a_client);
virtual ~WebConnection(void);
public: int add_data(const char *a_data, int a_len);
WebConnection (struct uhttpd_ops *an_ops, struct client *a_client); struct client *get_client(void);
virtual ~WebConnection (void);
int add_data (const char *a_data, int a_len); virtual void invoke(struct ubus_context *a_ctx);
struct client *get_client (void);
virtual void invoke (struct ubus_context *a_ctx); bool should_be_removed(void);
bool should_be_removed (void); protected:
protected:
struct uhttpd_ops *m_ops; struct uhttpd_ops *m_ops;
struct client *m_client; struct client *m_client;
std::string m_connection_data; std::string m_connection_data;

View File

@@ -31,61 +31,55 @@
* *
* @brief constructor of the web controller object. * @brief constructor of the web controller object.
*/ */
WebController::WebController (const std::string &a_path) : WebController::WebController(const std::string &a_path) : m_path(a_path)
m_path(a_path)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn ~WebController * @fn ~WebController
* *
* @brief destructor of the web controller object. * @brief destructor of the web controller object.
*/ */
WebController::~WebController (void) WebController::~WebController(void)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn set_name * @fn set_name
* *
* @brief set the name of the controller * @brief set the name of the controller
*/ */
void WebController::set_name (const std::string &a_name) void WebController::set_name(const std::string &a_name)
{ {
m_name = a_name; m_name = a_name;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_name * @fn get_name
* *
* @brief return the name of the controller. * @brief return the name of the controller.
*/ */
const std::string &WebController::get_name (void) const std::string &WebController::get_name(void)
{ {
return m_name; return m_name;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_path * @fn get_path
* *
* @brief return the model path of the controller. * @brief return the model path of the controller.
*/ */
std::string WebController::get_path (void) std::string WebController::get_path(void)
{ {
return m_path; return m_path;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn new_connection * @fn new_connection
* *
* @brief return a new connection object. * @brief return a new connection object.
*/ */
WebConnection *WebController::new_connection (struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters) WebConnection *WebController::new_connection(struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters)
{ {
return new WebConnection(an_ops, a_client); return new WebConnection(an_ops, a_client);
} }

View File

@@ -31,29 +31,28 @@
/*----------------------------- Dependencies --------------------------------*/ /*----------------------------- Dependencies --------------------------------*/
class WebConnection; class WebConnection;
struct uhttpd_ops; struct uhttpd_ops;
struct client; struct client;
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class WebController { class WebController
{
public:
WebController(const std::string &a_path);
virtual ~WebController(void);
public: void set_name(const std::string &a_name);
WebController (const std::string &a_path); const std::string &get_name(void);
virtual ~WebController (void);
void set_name (const std::string &a_name); std::string get_path(void);
const std::string &get_name (void);
std::string get_path (void); virtual WebConnection *new_connection(struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters);
virtual WebConnection *new_connection (struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters); private:
private:
std::string m_name; std::string m_name;
std::string m_path; std::string m_path;
}; };
#endif /* _WEB_CONTROLLER_H */ #endif /* _WEB_CONTROLLER_H */

View File

@@ -40,39 +40,36 @@
#include <uhttpd/uhttpd.h> #include <uhttpd/uhttpd.h>
#include <uhttpd/plugin.h> #include <uhttpd/plugin.h>
#define kdefaultTimeout 30000
#define kdefaultTimeout 30000
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn EtagRestConnection * @fn EtagRestConnection
* *
* @brief constructor of the etag rest connection object. * @brief constructor of the etag rest connection object.
*/ */
EtagRestConnection::EtagRestConnection (struct uhttpd_ops *an_ops, struct client *a_client, EtagRestController *a_controller, const std::string &a_parameters) : EtagRestConnection::EtagRestConnection(struct uhttpd_ops *an_ops, struct client *a_client, EtagRestController *a_controller, const std::string &a_parameters) : WebConnection(an_ops, a_client),
WebConnection(an_ops, a_client), m_controller(a_controller),
m_controller(a_controller), m_http_header(kdefaultTimeout),
m_http_header(kdefaultTimeout), m_ctx(NULL),
m_ctx(NULL), m_wait_response_timeout(kdefaultTimeout)
m_wait_response_timeout(kdefaultTimeout)
{ {
uh_client_ref(a_client); uh_client_ref(a_client);
// printf("%s\n", __PRETTY_FUNCTION__); // printf("%s\n", __PRETTY_FUNCTION__);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn ~EtagRestConnection * @fn ~EtagRestConnection
* *
* @brief destructor of the etag rest connection object. * @brief destructor of the etag rest connection object.
*/ */
EtagRestConnection::~EtagRestConnection (void) EtagRestConnection::~EtagRestConnection(void)
{ {
// printf("%s for client: %d\n", __PRETTY_FUNCTION__, m_client->id); // printf("%s for client: %d\n", __PRETTY_FUNCTION__, m_client->id);
// Stop Timers. // Stop Timers.
stop(); stop();
// Stop receive async events. // Stop receive async events.
if (m_ctx != NULL) { if (m_ctx != NULL)
{
unregister_event(m_ctx); unregister_event(m_ctx);
abort(m_ctx); abort(m_ctx);
} }
@@ -81,13 +78,12 @@ EtagRestConnection::~EtagRestConnection (void)
uh_client_unref(m_client); uh_client_unref(m_client);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn invoke * @fn invoke
* *
* @brief invoke the etag rest connection. * @brief invoke the etag rest connection.
*/ */
void EtagRestConnection::invoke (struct ubus_context *a_ctx) void EtagRestConnection::invoke(struct ubus_context *a_ctx)
{ {
uint32_t the_id = 0; uint32_t the_id = 0;
UBusCall the_cmd; UBusCall the_cmd;
@@ -100,49 +96,47 @@ void EtagRestConnection::invoke (struct ubus_context *a_ctx)
parse_parameter(); parse_parameter();
// printf("%s (object: %s)....\n", __PRETTY_FUNCTION__, m_controller->get_path().c_str()); // printf("%s (object: %s)....\n", __PRETTY_FUNCTION__, m_controller->get_path().c_str());
if (!ubus_lookup_id(a_ctx, m_controller->get_path().c_str(), &the_id)) { if (!ubus_lookup_id(a_ctx, m_controller->get_path().c_str(), &the_id))
{
// printf ("%s launch async call (%s)(%s)....\n", __PRETTY_FUNCTION__, the_method.c_str(), m_parameters.c_str()); // printf ("%s launch async call (%s)(%s)....\n", __PRETTY_FUNCTION__, the_method.c_str(), m_parameters.c_str());
the_cmd.exec_async(a_ctx, the_id, the_method, m_parameters, this); the_cmd.exec_async(a_ctx, the_id, the_method, m_parameters, this);
} }
if (m_client->request.method == UH_HTTP_MSG_GET) { if (m_client->request.method == UH_HTTP_MSG_GET)
{
// printf("start timer (%d)....\n", m_wait_response_timeout); // printf("start timer (%d)....\n", m_wait_response_timeout);
start(m_wait_response_timeout, false); start(m_wait_response_timeout, false);
} }
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn complete * @fn complete
* *
* @brief method called when an async exec result is arrived for this connection. * @brief method called when an async exec result is arrived for this connection.
*/ */
void EtagRestConnection::complete (void) void EtagRestConnection::complete(void)
{ {
// printf("%s.\n", __PRETTY_FUNCTION__); // printf("%s.\n", __PRETTY_FUNCTION__);
manage_response(get_data()); manage_response(get_data());
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn handle_event * @fn handle_event
* *
* @brief method called when a registered event is arrived for this connection. * @brief method called when a registered event is arrived for this connection.
*/ */
void EtagRestConnection::handle_event (const char *a_type, const char *a_json_msg) void EtagRestConnection::handle_event(const char *a_type, const char *a_json_msg)
{ {
// printf("%s.\n", __PRETTY_FUNCTION__); // printf("%s.\n", __PRETTY_FUNCTION__);
manage_response(a_json_msg); manage_response(a_json_msg);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn parse_parameter * @fn parse_parameter
* *
* @brief Extract parameters from the http header to get the wanted parameters by this controller. * @brief Extract parameters from the http header to get the wanted parameters by this controller.
*/ */
int EtagRestConnection::parse_parameter (void) int EtagRestConnection::parse_parameter(void)
{ {
HttpParameter the_http_params; HttpParameter the_http_params;
std::string the_origin; std::string the_origin;
@@ -150,8 +144,8 @@ int EtagRestConnection::parse_parameter (void)
int32_t the_wait_response_timeout = -1; int32_t the_wait_response_timeout = -1;
struct json_object *the_response_node; struct json_object *the_response_node;
if (the_http_params.parse(m_client)) { if (the_http_params.parse(m_client))
{
the_etag = the_http_params.get_etag(); the_etag = the_http_params.get_etag();
the_wait_response_timeout = the_http_params.get_request_timeout(); the_wait_response_timeout = the_http_params.get_request_timeout();
the_origin = the_http_params.get_origin(); the_origin = the_http_params.get_origin();
@@ -159,16 +153,16 @@ int EtagRestConnection::parse_parameter (void)
m_http_header.add_origin(the_origin); m_http_header.add_origin(the_origin);
} }
// printf("EtagRestConnection::parse_parameter timeout: %d\n", the_wait_response_timeout); // printf("EtagRestConnection::parse_parameter timeout: %d\n", the_wait_response_timeout);
if (the_wait_response_timeout != -1) { if (the_wait_response_timeout != -1)
{
// Convert it as milli seconds. // Convert it as milli seconds.
m_wait_response_timeout = the_wait_response_timeout * 1000; m_wait_response_timeout = the_wait_response_timeout * 1000;
} }
// printf("%s - etag: %s, keep alive: %d\n", __PRETTY_FUNCTION__, the_etag.c_str(), the_wait_response_timeout); // printf("%s - etag: %s, keep alive: %d\n", __PRETTY_FUNCTION__, the_etag.c_str(), the_wait_response_timeout);
if (m_client->request.method == UH_HTTP_MSG_GET) { if (m_client->request.method == UH_HTTP_MSG_GET)
{
the_response_node = json_object_new_object(); the_response_node = json_object_new_object();
if (!the_etag.empty()) if (!the_etag.empty())
@@ -177,15 +171,16 @@ int EtagRestConnection::parse_parameter (void)
m_parameters = json_object_to_json_string(the_response_node); m_parameters = json_object_to_json_string(the_response_node);
json_object_put(the_response_node); json_object_put(the_response_node);
} }
else { else
{
struct json_object *the_content_node, *the_root_node; struct json_object *the_content_node, *the_root_node;
if (!m_connection_data.empty()) { if (!m_connection_data.empty())
{
the_root_node = json_object_new_object(); the_root_node = json_object_new_object();
the_content_node = json_tokener_parse(m_connection_data.c_str()); the_content_node = json_tokener_parse(m_connection_data.c_str());
if (the_content_node != NULL) { if (the_content_node != NULL)
{
json_object_object_add(the_root_node, kEvent_content_entry, the_content_node); json_object_object_add(the_root_node, kEvent_content_entry, the_content_node);
} }
@@ -197,13 +192,12 @@ int EtagRestConnection::parse_parameter (void)
return 0; return 0;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn manage_response * @fn manage_response
* *
* @brief manage the response rerceived by an event or an async response. * @brief manage the response rerceived by an event or an async response.
*/ */
void EtagRestConnection::manage_response (std::string a_response_data) void EtagRestConnection::manage_response(std::string a_response_data)
{ {
std::string the_etag; std::string the_etag;
struct json_object *the_root_node, *the_status_node, *the_content_node, *the_etag_node; struct json_object *the_root_node, *the_status_node, *the_content_node, *the_etag_node;
@@ -213,8 +207,8 @@ void EtagRestConnection::manage_response (std::string a_response_data)
// printf("\tdata: (%s)\n", a_response_data.c_str()); // printf("\tdata: (%s)\n", a_response_data.c_str());
the_root_node = json_tokener_parse(a_response_data.c_str()); the_root_node = json_tokener_parse(a_response_data.c_str());
if (the_root_node == NULL) { if (the_root_node == NULL)
{
// response couldn't be parsed. // response couldn't be parsed.
m_http_header.send(m_ops, m_client, 500); m_http_header.send(m_ops, m_client, 500);
m_ops->chunk_printf(m_client, "0\r\n\r\n"); m_ops->chunk_printf(m_client, "0\r\n\r\n");
@@ -223,24 +217,25 @@ void EtagRestConnection::manage_response (std::string a_response_data)
} }
// get status // get status
if (json_object_object_get_ex(the_root_node, kEvent_status_entry, &the_status_node)) { if (json_object_object_get_ex(the_root_node, kEvent_status_entry, &the_status_node))
{
the_result_code = json_object_get_int(the_status_node); the_result_code = json_object_get_int(the_status_node);
} }
// get etag. // get etag.
if (json_object_object_get_ex(the_root_node, kEvent_version_entry, &the_etag_node)) { if (json_object_object_get_ex(the_root_node, kEvent_version_entry, &the_etag_node))
{
enum json_type the_json_type; enum json_type the_json_type;
the_json_type = json_object_get_type(the_etag_node); the_json_type = json_object_get_type(the_etag_node);
if (the_json_type == json_type_int) { if (the_json_type == json_type_int)
{
int the_tmp_value; int the_tmp_value;
the_tmp_value = json_object_get_int(the_etag_node); the_tmp_value = json_object_get_int(the_etag_node);
the_etag = std::to_string(the_tmp_value); the_etag = std::to_string(the_tmp_value);
} }
else if (the_json_type == json_type_string) { else if (the_json_type == json_type_string)
{
the_etag = json_object_get_string(the_etag_node); the_etag = json_object_get_string(the_etag_node);
} }
@@ -249,13 +244,13 @@ void EtagRestConnection::manage_response (std::string a_response_data)
// get contents // get contents
the_content_node = NULL; the_content_node = NULL;
if (!json_object_object_get_ex(the_root_node, kEvent_content_entry, &the_content_node)) { if (!json_object_object_get_ex(the_root_node, kEvent_content_entry, &the_content_node))
{
the_content_node = the_root_node; the_content_node = the_root_node;
} }
if (the_result_code == 204) { if (the_result_code == 204)
{
json_object_put(the_root_node); json_object_put(the_root_node);
register_event(m_ctx, m_controller->get_event_name()); register_event(m_ctx, m_controller->get_event_name());
return; return;
@@ -273,14 +268,13 @@ void EtagRestConnection::manage_response (std::string a_response_data)
m_ops->request_done(m_client); m_ops->request_done(m_client);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn expire * @fn expire
* *
* @brief method called when the connection time has expired. we will close the connection * @brief method called when the connection time has expired. we will close the connection
* with a 204 * with a 204
*/ */
int EtagRestConnection::expire (void) int EtagRestConnection::expire(void)
{ {
// printf("%s client id: %d, path:%s\n", __PRETTY_FUNCTION__, m_client->id, m_controller->get_path().c_str()); // printf("%s client id: %d, path:%s\n", __PRETTY_FUNCTION__, m_client->id, m_controller->get_path().c_str());
stop(); stop();

View File

@@ -36,35 +36,35 @@
#include "core/web-connection.h" #include "core/web-connection.h"
class EtagRestController; class EtagRestController;
struct ubus_context; struct ubus_context;
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class EtagRestConnection : public WebConnection, public UBusExecReceiver, public UBusEventReceiver, public ULoopTimer { class EtagRestConnection : public WebConnection, public UBusExecReceiver, public UBusEventReceiver, public ULoopTimer
{
public: public:
EtagRestConnection (struct uhttpd_ops *an_ops, struct client *a_client, EtagRestController *a_controller, const std::string &a_parameters); EtagRestConnection(struct uhttpd_ops *an_ops, struct client *a_client, EtagRestController *a_controller, const std::string &a_parameters);
~EtagRestConnection (void); ~EtagRestConnection(void);
// WebConnection // WebConnection
void invoke (struct ubus_context *a_ctx); void invoke(struct ubus_context *a_ctx);
// awUBusExecReceiver // awUBusExecReceiver
void complete (void); void complete(void);
// awUBusEventReceiver // awUBusEventReceiver
void handle_event (const char *a_type, const char *a_json_msg); void handle_event(const char *a_type, const char *a_json_msg);
// ULoopTimer. // ULoopTimer.
int expire (void); int expire(void);
private: private:
int parse_parameter (void); int parse_parameter(void);
void manage_response (std::string a_response_data); void manage_response(std::string a_response_data);
private: private:
EtagRestController *m_controller; EtagRestController *m_controller;
HttpHeader m_http_header; HttpHeader m_http_header;
struct ubus_context *m_ctx; struct ubus_context *m_ctx;

View File

@@ -22,66 +22,58 @@
/*------------------------------- INCLUDES ----------------------------------*/ /*------------------------------- INCLUDES ----------------------------------*/
#include "etag-rest/etag-rest-connection.h" #include "etag-rest/etag-rest-connection.h"
#include "etag-rest/etag-rest-controller.h" #include "etag-rest/etag-rest-controller.h"
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn EtagRestController * @fn EtagRestController
* *
* @brief constructor of the etag rest controller object. * @brief constructor of the etag rest controller object.
*/ */
EtagRestController::EtagRestController (const std::string &a_path, const std::string &an_event_name, const std::string &an_etag_key, EtagRestController::EtagRestController(const std::string &a_path, const std::string &an_event_name, const std::string &an_etag_key,
const std::string &a_method_get, const std::string &a_method_put, int a_timeout, bool a_raw_response) : const std::string &a_method_get, const std::string &a_method_put, int a_timeout, bool a_raw_response) : RestController(a_path, a_method_get, a_method_put, a_timeout, a_raw_response),
RestController(a_path, a_method_get, a_method_put, a_timeout, a_raw_response), m_event_name(an_event_name),
m_event_name(an_event_name), m_etag_key(an_etag_key)
m_etag_key(an_etag_key)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn ~EtagRestController * @fn ~EtagRestController
* *
* @brief destructor of the etag rest controller object. * @brief destructor of the etag rest controller object.
*/ */
EtagRestController::~EtagRestController (void) EtagRestController::~EtagRestController(void)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn new_connection * @fn new_connection
* *
* @brief return a new etag rest connection attached to this controller. * @brief return a new etag rest connection attached to this controller.
*/ */
WebConnection *EtagRestController::new_connection (struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters) WebConnection *EtagRestController::new_connection(struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters)
{ {
// printf("%s.\n", __PRETTY_FUNCTION__); // printf("%s.\n", __PRETTY_FUNCTION__);
return new EtagRestConnection(an_ops, a_client, this, a_parameters); return new EtagRestConnection(an_ops, a_client, this, a_parameters);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_event_name * @fn get_event_name
* *
* @brief set the etag key attached to the etag rest controller. * @brief set the etag key attached to the etag rest controller.
*/ */
std::string EtagRestController::get_event_name (void) std::string EtagRestController::get_event_name(void)
{ {
return m_event_name; return m_event_name;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_etag_key * @fn get_etag_key
* *
* @brief return the etag key attached to the etag rest controller. * @brief return the etag key attached to the etag rest controller.
*/ */
std::string EtagRestController::get_etag_key (void) std::string EtagRestController::get_etag_key(void)
{ {
return m_etag_key; return m_etag_key;
} }

View File

@@ -32,31 +32,30 @@
/*--------------------------------- Define ----------------------------------*/ /*--------------------------------- Define ----------------------------------*/
#define kDefaultTimeout 20 #define kDefaultTimeout 20
#define kPassed "passed" #define kPassed "passed"
#define kFailed "failed" #define kFailed "failed"
/*----------------------------- Dependencies --------------------------------*/ /*----------------------------- Dependencies --------------------------------*/
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class EtagRestController : public RestController { class EtagRestController : public RestController
{
public:
EtagRestController(const std::string &a_path, const std::string &an_event_name, const std::string &an_etag_key,
const std::string &a_method_get = "", const std::string &a_method_put = "",
int a_timeout = kDefaultTimeout, bool a_raw_response = false);
~EtagRestController(void);
public: WebConnection *new_connection(struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters);
EtagRestController (const std::string &a_path, const std::string &an_event_name, const std::string &an_etag_key,
const std::string &a_method_get = "", const std::string &a_method_put = "",
int a_timeout = kDefaultTimeout, bool a_raw_response = false);
~EtagRestController (void);
WebConnection *new_connection (struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters); std::string get_event_name(void);
std::string get_etag_key(void);
std::string get_event_name (void); private:
std::string get_etag_key (void);
private:
std::string m_event_name; std::string m_event_name;
std::string m_etag_key; std::string m_etag_key;
}; };
#endif /* _ETAG_REST_CONTROLLER_H */ #endif /* _ETAG_REST_CONTROLLER_H */

View File

@@ -34,44 +34,41 @@ extern "C" {
#include "notification/notification-controller.h" #include "notification/notification-controller.h"
#include "notification/notification-connection.h" #include "notification/notification-connection.h"
#define kdefaultTimeout 20000 #define kdefaultTimeout 20000
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn NotificationConnection * @fn NotificationConnection
* *
* @brief constructor of the notification connection object. * @brief constructor of the notification connection object.
*/ */
NotificationConnection::NotificationConnection (struct uhttpd_ops *an_ops, struct client *a_client, NotificationController *a_controller) : NotificationConnection::NotificationConnection(struct uhttpd_ops *an_ops, struct client *a_client, NotificationController *a_controller) : WebConnection(an_ops, a_client),
WebConnection(an_ops, a_client), m_controller(a_controller),
m_controller(a_controller), m_ctx(NULL)
m_ctx(NULL)
{ {
// printf("constructor NotificationConnection : %p\n", this); // printf("constructor NotificationConnection : %p\n", this);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn ~NotificationConnection * @fn ~NotificationConnection
* *
* @brief destructor of the notification controller object. * @brief destructor of the notification controller object.
*/ */
NotificationConnection::~NotificationConnection (void) NotificationConnection::~NotificationConnection(void)
{ {
//printf("destructor NotificationConnection : %p\n", this); //printf("destructor NotificationConnection : %p\n", this);
stop(); stop();
if (m_ctx != NULL) { if (m_ctx != NULL)
{
unregister_event(m_ctx); unregister_event(m_ctx);
} }
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn invoke * @fn invoke
* *
* @brief invoke an async connection. * @brief invoke an async connection.
*/ */
void NotificationConnection::invoke (struct ubus_context *a_ctx) void NotificationConnection::invoke(struct ubus_context *a_ctx)
{ {
m_ctx = a_ctx; m_ctx = a_ctx;
@@ -82,13 +79,12 @@ void NotificationConnection::invoke (struct ubus_context *a_ctx)
start(kdefaultTimeout, true); start(kdefaultTimeout, true);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn handle_event * @fn handle_event
* *
* @brief method called when a registered event is arrived for this connection. * @brief method called when a registered event is arrived for this connection.
*/ */
void NotificationConnection::handle_event (const char *a_type, const char *a_json_msg) void NotificationConnection::handle_event(const char *a_type, const char *a_json_msg)
{ {
// printf("NotificationConnection::handle_event\n"); // printf("NotificationConnection::handle_event\n");
stop(); stop();
@@ -96,13 +92,12 @@ void NotificationConnection::handle_event (const char *a_type, const char *a_jso
start(kdefaultTimeout, true); start(kdefaultTimeout, true);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn expire * @fn expire
* *
* @brief method called when no data is arrived to the notification canal. * @brief method called when no data is arrived to the notification canal.
*/ */
int NotificationConnection::expire (void) int NotificationConnection::expire(void)
{ {
// printf ("NotificationConnection::expire\n"); // printf ("NotificationConnection::expire\n");
m_ops->chunk_printf(m_client, "{}"); m_ops->chunk_printf(m_client, "{}");

View File

@@ -37,22 +37,22 @@ struct ubus_context;
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class NotificationConnection : public WebConnection, public UBusEventReceiver, public ULoopTimer { class NotificationConnection : public WebConnection, public UBusEventReceiver, public ULoopTimer
{
public: public:
NotificationConnection (struct uhttpd_ops *an_ops, struct client *a_client, NotificationController *a_controller); NotificationConnection(struct uhttpd_ops *an_ops, struct client *a_client, NotificationController *a_controller);
virtual ~NotificationConnection (void); virtual ~NotificationConnection(void);
// WebConnection // WebConnection
void invoke (struct ubus_context *a_ctx); void invoke(struct ubus_context *a_ctx);
// UBusEventReceiver // UBusEventReceiver
void handle_event (const char *a_type, const char *a_json_msg); void handle_event(const char *a_type, const char *a_json_msg);
// Timer. // Timer.
int expire (void); int expire(void);
private: private:
NotificationController *m_controller; NotificationController *m_controller;
struct ubus_context *m_ctx; struct ubus_context *m_ctx;
}; };

View File

@@ -31,30 +31,26 @@
* *
* @brief constructor of the notification controller object. * @brief constructor of the notification controller object.
*/ */
NotificationController::NotificationController (const std::string &a_path) : NotificationController::NotificationController(const std::string &a_path) : WebController(a_path)
WebController(a_path)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn ~NotificationController * @fn ~NotificationController
* *
* @brief destructor of the notification controller object. * @brief destructor of the notification controller object.
*/ */
NotificationController::~NotificationController (void) NotificationController::~NotificationController(void)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn new_connection * @fn new_connection
* *
* @brief create a new connection for this controller. * @brief create a new connection for this controller.
*/ */
WebConnection *NotificationController::new_connection (struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters) WebConnection *NotificationController::new_connection(struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters)
{ {
// printf("%s.\n", __PRETTY_FUNCTION__); // printf("%s.\n", __PRETTY_FUNCTION__);
return new NotificationConnection(an_ops, a_client, this); return new NotificationConnection(an_ops, a_client, this);
} }

View File

@@ -32,12 +32,13 @@
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class NotificationController : public WebController { class NotificationController : public WebController
public: {
NotificationController (const std::string &a_path); public:
~NotificationController (void); NotificationController(const std::string &a_path);
~NotificationController(void);
WebConnection *new_connection (struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters); WebConnection *new_connection(struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters);
}; };
#endif /* _NOTIFICATION_CONTROLLER_H */ #endif /* _NOTIFICATION_CONTROLLER_H */

View File

@@ -29,11 +29,10 @@
/*--------------------------------- PLUGINS ----------------------------------*/ /*--------------------------------- PLUGINS ----------------------------------*/
extern struct ubus_context *get_uhttp_server_ctx (void); extern struct ubus_context *get_uhttp_server_ctx(void);
extern int uhttp_server_setup (struct ubus_context *a_ctx, const struct uhttpd_ops *an_ops); extern int uhttp_server_setup(struct ubus_context *a_ctx, const struct uhttpd_ops *an_ops);
extern bool uhttp_server_check_url (const char *an_url); extern bool uhttp_server_check_url(const char *an_url);
extern void uhttp_server_handle_request (struct client *a_cl, char *an_url, struct path_info *a_pi); extern void uhttp_server_handle_request(struct client *a_cl, char *an_url, struct path_info *a_pi);
bool uhttp_server_check_path(struct path_info *pi, const char *url) bool uhttp_server_check_path(struct path_info *pi, const char *url)
{ {
@@ -49,19 +48,18 @@ static struct dispatch_handler g_ubus_dispatch = {
.handle_request = uhttp_server_handle_request, .handle_request = uhttp_server_handle_request,
}; };
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn uh_awox_api_plugin_init * @fn uh_awox_api_plugin_init
* *
* @brief * @brief
*/ */
static int uh_awox_api_plugin_init (const struct uhttpd_ops *an_ops, struct config *a_conf) static int uh_awox_api_plugin_init(const struct uhttpd_ops *an_ops, struct config *a_conf)
{ {
struct ubus_context *the_ctx; struct ubus_context *the_ctx;
the_ctx = ubus_connect(NULL); the_ctx = ubus_connect(NULL);
if (!the_ctx) { if (!the_ctx)
{
fprintf(stderr, "Unable to connect to ubus socket\n"); fprintf(stderr, "Unable to connect to ubus socket\n");
return -1; return -1;
} }
@@ -75,13 +73,12 @@ static int uh_awox_api_plugin_init (const struct uhttpd_ops *an_ops, struct conf
return 0; return 0;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn uh_awox_api_plugin_post_init * @fn uh_awox_api_plugin_post_init
* *
* @brief * @brief
*/ */
static void uh_awox_api_plugin_post_init (void) static void uh_awox_api_plugin_post_init(void)
{ {
ubus_add_uloop(get_uhttp_server_ctx()); ubus_add_uloop(get_uhttp_server_ctx());
} }

View File

@@ -43,42 +43,38 @@ extern "C" {
#include "rest/rest-connection.h" #include "rest/rest-connection.h"
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn RestConnection * @fn RestConnection
* *
* @brief constructor of the rest connection object. * @brief constructor of the rest connection object.
*/ */
RestConnection::RestConnection (struct uhttpd_ops *an_ops, struct client *a_client, RestController *a_controller, const std::string &a_parameters) : RestConnection::RestConnection(struct uhttpd_ops *an_ops, struct client *a_client, RestController *a_controller, const std::string &a_parameters) : WebConnection(an_ops, a_client),
WebConnection(an_ops, a_client), m_controller(a_controller), m_ctx(0)
m_controller(a_controller), m_ctx(0)
{ {
if (!a_parameters.empty()) { if (!a_parameters.empty())
{
HttpParameter the_http_parm; HttpParameter the_http_parm;
m_connection_data = the_http_parm.parse_from_uri(a_parameters); m_connection_data = the_http_parm.parse_from_uri(a_parameters);
} }
// printf("RestConnection:: constructor....\n"); // printf("RestConnection:: constructor....\n");
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn ~RestConnection * @fn ~RestConnection
* *
* @brief destructor of the rest connection object. * @brief destructor of the rest connection object.
*/ */
RestConnection::~RestConnection (void) RestConnection::~RestConnection(void)
{ {
abort(m_ctx); abort(m_ctx);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn complete * @fn complete
* *
* @brief method called when the async call has been done. * @brief method called when the async call has been done.
*/ */
void RestConnection::complete (void) void RestConnection::complete(void)
{ {
int the_result_code; int the_result_code;
// printf("resultat: <%s>\n", get_data().c_str()); // printf("resultat: <%s>\n", get_data().c_str());
@@ -88,13 +84,12 @@ void RestConnection::complete (void)
send_response(the_result_code, get_data().c_str()); send_response(the_result_code, get_data().c_str());
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn invoke * @fn invoke
* *
* @brief invoke an async connection. * @brief invoke an async connection.
*/ */
void RestConnection::invoke (struct ubus_context *a_ctx) void RestConnection::invoke(struct ubus_context *a_ctx)
{ {
uint32_t the_id = 0; uint32_t the_id = 0;
UBusCall the_cmd; UBusCall the_cmd;
@@ -105,7 +100,8 @@ void RestConnection::invoke (struct ubus_context *a_ctx)
the_method = m_controller->get_method(m_client->request.method); the_method = m_controller->get_method(m_client->request.method);
// printf("RestConnection::invoke(object: %s)....\n", m_controller->get_path().c_str()); // printf("RestConnection::invoke(object: %s)....\n", m_controller->get_path().c_str());
if (!ubus_lookup_id(a_ctx, m_controller->get_path().c_str(), &the_id)) { if (!ubus_lookup_id(a_ctx, m_controller->get_path().c_str(), &the_id))
{
json_object *the_parameter_doc; json_object *the_parameter_doc;
the_parameter_doc = json_tokener_parse(m_connection_data.c_str()); the_parameter_doc = json_tokener_parse(m_connection_data.c_str());
@@ -130,7 +126,7 @@ void RestConnection::invoke (struct ubus_context *a_ctx)
* @brief Parse the document content as form encoded parameters * @brief Parse the document content as form encoded parameters
* and return them as a json object with an attribute for each parameter. * and return them as a json object with an attribute for each parameter.
*/ */
json_object* RestConnection::parse_form_encoded_data () json_object *RestConnection::parse_form_encoded_data()
{ {
json_object *the_parsed_document; json_object *the_parsed_document;
char *the_parameters = strdup(m_connection_data.c_str()); char *the_parameters = strdup(m_connection_data.c_str());
@@ -139,7 +135,8 @@ json_object* RestConnection::parse_form_encoded_data ()
the_parsed_document = json_object_new_object(); the_parsed_document = json_object_new_object();
for (the_encoded_name = strtok(the_parameters, "="); the_encoded_name != NULL; the_encoded_name = strtok(NULL, "=")) { for (the_encoded_name = strtok(the_parameters, "="); the_encoded_name != NULL; the_encoded_name = strtok(NULL, "="))
{
std::string the_name, the_value; std::string the_name, the_value;
the_encoded_value = strtok(NULL, "&"); the_encoded_value = strtok(NULL, "&");
@@ -169,8 +166,8 @@ void RestConnection::send_response(int a_result_code, std::string a_content_docu
struct json_object *the_root_node; struct json_object *the_root_node;
HttpHeader the_http_header; HttpHeader the_http_header;
if (m_controller->is_raw_response()) { if (m_controller->is_raw_response())
{
the_http_header.send(m_ops, m_client, a_result_code); the_http_header.send(m_ops, m_client, a_result_code);
m_ops->chunk_printf(m_client, "%s", get_data().c_str()); m_ops->chunk_printf(m_client, "%s", get_data().c_str());
m_ops->request_done(m_client); m_ops->request_done(m_client);
@@ -182,10 +179,12 @@ void RestConnection::send_response(int a_result_code, std::string a_content_docu
else else
the_status = kFailed; the_status = kFailed;
if (a_content_document.empty()) { if (a_content_document.empty())
{
the_root_node = json_object_new_object(); the_root_node = json_object_new_object();
} }
else { else
{
the_root_node = json_tokener_parse(get_data().c_str()); the_root_node = json_tokener_parse(get_data().c_str());
} }

View File

@@ -39,22 +39,22 @@ struct json_object;
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class RestConnection : public WebConnection, public UBusExecReceiver { class RestConnection : public WebConnection, public UBusExecReceiver
{
public:
RestConnection(struct uhttpd_ops *an_ops, struct client *a_client, RestController *a_controller, const std::string &a_parameters);
~RestConnection(void);
public: void complete(void);
RestConnection (struct uhttpd_ops *an_ops, struct client *a_client, RestController *a_controller, const std::string &a_parameters);
~RestConnection (void);
void complete (void); void invoke(struct ubus_context *a_ctx);
void invoke (struct ubus_context *a_ctx); private:
private:
RestController *m_controller; RestController *m_controller;
struct ubus_context *m_ctx; struct ubus_context *m_ctx;
json_object *parse_form_encoded_data (void); json_object *parse_form_encoded_data(void);
void send_response (int a_result_code, std::string a_content_document = ""); void send_response(int a_result_code, std::string a_content_document = "");
}; };
#endif /* _REST_CONNECTION_H */ #endif /* _REST_CONNECTION_H */

View File

@@ -33,90 +33,82 @@
* *
* @brief constructor of the rest controller object. * @brief constructor of the rest controller object.
*/ */
RestController::RestController (const std::string &a_path, const std::string &a_method_get, const std::string &a_method_put, int a_timeout, bool a_raw_response) : RestController::RestController(const std::string &a_path, const std::string &a_method_get, const std::string &a_method_put, int a_timeout, bool a_raw_response) : WebController(a_path),
WebController(a_path), m_method_get(a_method_get),
m_method_get(a_method_get), m_method_put(a_method_put),
m_method_put(a_method_put), m_timeout(a_timeout),
m_timeout(a_timeout), mf_raw_response(a_raw_response)
mf_raw_response(a_raw_response)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn ~RestController * @fn ~RestController
* *
* @brief destructor of the rest controller object. * @brief destructor of the rest controller object.
*/ */
RestController::~RestController (void) RestController::~RestController(void)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn new_connection * @fn new_connection
* *
* @brief return a new rest connection attached to this controller. * @brief return a new rest connection attached to this controller.
*/ */
WebConnection *RestController::new_connection (struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters) WebConnection *RestController::new_connection(struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters)
{ {
return new RestConnection(an_ops, a_client, this, a_parameters); return new RestConnection(an_ops, a_client, this, a_parameters);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_method_get * @fn get_method_get
* *
* @brief return the get method of the controller. * @brief return the get method of the controller.
*/ */
std::string RestController::get_method_get (void) std::string RestController::get_method_get(void)
{ {
return m_method_get; return m_method_get;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_method_put * @fn get_method_put
* *
* @brief return the put method of the controller. * @brief return the put method of the controller.
*/ */
std::string RestController::get_method_put (void) std::string RestController::get_method_put(void)
{ {
return m_method_put; return m_method_put;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_timeout * @fn get_timeout
* *
* @brief return the wanted timeout of the controller. * @brief return the wanted timeout of the controller.
*/ */
uint16_t RestController::get_timeout (void) uint16_t RestController::get_timeout(void)
{ {
return m_timeout; return m_timeout;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn is_raw_response * @fn is_raw_response
* *
* @brief return the true if the controller didn't need the awox api response template. * @brief return the true if the controller didn't need the awox api response template.
*/ */
bool RestController::is_raw_response (void) bool RestController::is_raw_response(void)
{ {
return mf_raw_response; return mf_raw_response;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_method * @fn get_method
* *
* @brief return the right method in function of the client connection. * @brief return the right method in function of the client connection.
*/ */
std::string RestController::get_method (uint8_t a_method) std::string RestController::get_method(uint8_t a_method)
{ {
switch (a_method) { switch (a_method)
{
case UH_HTTP_MSG_GET: case UH_HTTP_MSG_GET:
return m_method_get; return m_method_get;
break; break;

View File

@@ -32,31 +32,30 @@
/*--------------------------------- Define ----------------------------------*/ /*--------------------------------- Define ----------------------------------*/
#define kDefaultTimeout 20 #define kDefaultTimeout 20
#define kPassed "passed" #define kPassed "passed"
#define kFailed "failed" #define kFailed "failed"
/*----------------------------- Dependencies --------------------------------*/ /*----------------------------- Dependencies --------------------------------*/
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class RestController : public WebController { class RestController : public WebController
{
public:
RestController(const std::string &a_path, const std::string &a_method_get = "", const std::string &a_method_put = "", int a_timeout = kDefaultTimeout, bool a_raw_response = false);
virtual ~RestController(void);
public: WebConnection *new_connection(struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters);
RestController (const std::string &a_path, const std::string &a_method_get = "", const std::string &a_method_put = "", int a_timeout = kDefaultTimeout, bool a_raw_response = false);
virtual ~RestController (void);
WebConnection *new_connection (struct uhttpd_ops *an_ops, struct client *a_client, const std::string &a_parameters); std::string get_method_get(void);
std::string get_method_put(void);
uint16_t get_timeout(void);
bool is_raw_response(void);
std::string get_method_get (void); std::string get_method(uint8_t a_method);
std::string get_method_put (void);
uint16_t get_timeout (void);
bool is_raw_response (void);
std::string get_method (uint8_t a_method); protected:
protected:
std::string m_name; std::string m_name;
std::string m_path; std::string m_path;
std::string m_method_get; std::string m_method_get;
@@ -65,5 +64,4 @@ protected:
bool mf_raw_response; bool mf_raw_response;
}; };
#endif /* _REST_CONTROLLER_H */ #endif /* _REST_CONTROLLER_H */

View File

@@ -20,7 +20,6 @@
* @Date: 16/06/2017 * @Date: 16/06/2017
*/ */
/*------------------------------- INCLUDES ----------------------------------*/ /*------------------------------- INCLUDES ----------------------------------*/
#include <string> #include <string>
@@ -58,35 +57,31 @@ extern "C" {
#include <uhttpd/uhttpd.h> #include <uhttpd/uhttpd.h>
#include <uhttpd/plugin.h> #include <uhttpd/plugin.h>
/*------------------------------- GLOBALS ----------------------------------*/ /*------------------------------- GLOBALS ----------------------------------*/
#define kConfigDirectory "/usr/local/configs/restd/" #define kConfigDirectory "/usr/local/configs/restd/"
#define kControllerKey "controller" #define kControllerKey "controller"
#define kEtagControllerKey "etag_controller" #define kEtagControllerKey "etag_controller"
#define kNotificationKey "notification" #define kNotificationKey "notification"
#define kControllerPathKey "path" #define kControllerPathKey "path"
#define kControllerModelNameKey "model_name" #define kControllerModelNameKey "model_name"
#define kControllerEventNameKey "event_name" #define kControllerEventNameKey "event_name"
#define kControllerEtagKey "etag_key" #define kControllerEtagKey "etag_key"
#define kControllerGetMethodKey "get_method" #define kControllerGetMethodKey "get_method"
#define kControllerSetMethodKey "set_method" #define kControllerSetMethodKey "set_method"
#define kControllerRawResponseKey "raw_response" #define kControllerRawResponseKey "raw_response"
#define kdefaultGetMethod "get" #define kdefaultGetMethod "get"
#define kdefaultSetMethod "set" #define kdefaultSetMethod "set"
#define kJsonControlerNotFound "{{\n" \
" \"id\": \"{}\",\n" \
" \"status\": \"failed\",\n" \
" \"error\": \"Controller Not Found\",\n" \
" \"response_code\": 404\n}}"
#define kJsonControlerNotFound "{{\n" \
" \"id\": \"{}\",\n" \
" \"status\": \"failed\",\n" \
" \"error\": \"Controller Not Found\",\n" \
" \"response_code\": 404\n}}"
#define DEBUG_REQUEST 1 #define DEBUG_REQUEST 1
#define BUFFER_SIZE 100 #define BUFFER_SIZE 100
@@ -97,29 +92,29 @@ extern "C" {
* *
* @brief method to log with time stamp. * @brief method to log with time stamp.
*/ */
void log_with_timestamp (const char *a_msg) void log_with_timestamp(const char *a_msg)
{ {
char the_buffer[512]; char the_buffer[512];
time_t the_time; time_t the_time;
struct timeval the_timeval; struct timeval the_timeval;
the_time = time(NULL); the_time = time(NULL);
strftime(the_buffer, sizeof(the_buffer), "%m/%d/%Y %H:%M:%S", localtime(&the_time)); strftime(the_buffer, sizeof(the_buffer), "%m/%d/%Y %H:%M:%S", localtime(&the_time));
gettimeofday(&the_timeval, NULL); gettimeofday(&the_timeval, NULL);
fprintf (stdout, "%s.%09ld - %s\n", the_buffer, the_timeval.tv_usec*1000, a_msg); fprintf(stdout, "%s.%09ld - %s\n", the_buffer, the_timeval.tv_usec * 1000, a_msg);
} }
double time_diff(struct timeval x , struct timeval y) double time_diff(struct timeval x, struct timeval y)
{ {
double x_ms , y_ms , diff; double x_ms, y_ms, diff;
x_ms = (double)x.tv_sec*1000000 + (double)x.tv_usec; x_ms = (double)x.tv_sec * 1000000 + (double)x.tv_usec;
y_ms = (double)y.tv_sec*1000000 + (double)y.tv_usec; y_ms = (double)y.tv_sec * 1000000 + (double)y.tv_usec;
diff = (double)y_ms - (double)x_ms; diff = (double)y_ms - (double)x_ms;
return diff; return diff;
} }
#endif #endif
@@ -128,10 +123,9 @@ double time_diff(struct timeval x , struct timeval y)
* *
* @brief method to return ubux context to c plugin. * @brief method to return ubux context to c plugin.
*/ */
extern "C" struct ubus_context *get_uhttp_server_ctx (void) extern "C" struct ubus_context *get_uhttp_server_ctx(void)
{ {
return UhttpServer::get_instance().get_context(); return UhttpServer::get_instance().get_context();
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
@@ -139,29 +133,27 @@ extern "C" struct ubus_context *get_uhttp_server_ctx (void)
* *
* @brief init method from c plugin to uhttp server. * @brief init method from c plugin to uhttp server.
*/ */
extern "C" int uhttp_server_setup (struct ubus_context *a_ctx, const struct uhttpd_ops *an_ops) extern "C" int uhttp_server_setup(struct ubus_context *a_ctx, const struct uhttpd_ops *an_ops)
{ {
return UhttpServer::get_instance().setup(a_ctx, an_ops); return UhttpServer::get_instance().setup(a_ctx, an_ops);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn uhttp_server_check_url * @fn uhttp_server_check_url
* *
* @brief Check if the url is managed by this plugin * @brief Check if the url is managed by this plugin
*/ */
extern "C" bool uhttp_server_check_url (const char *an_url) extern "C" bool uhttp_server_check_url(const char *an_url)
{ {
return UhttpServer::get_instance().check_url(an_url); return UhttpServer::get_instance().check_url(an_url);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn uhttp_server_handle_request * @fn uhttp_server_handle_request
* *
* @brief Handle the request. * @brief Handle the request.
*/ */
extern "C" void uhttp_server_handle_request (struct client *a_cl, char *an_url, struct path_info *a_pi) extern "C" void uhttp_server_handle_request(struct client *a_cl, char *an_url, struct path_info *a_pi)
{ {
#ifdef DEBUG_REQUEST #ifdef DEBUG_REQUEST
gettimeofday(&a_cl->start_request, NULL); gettimeofday(&a_cl->start_request, NULL);
@@ -172,13 +164,12 @@ extern "C" void uhttp_server_handle_request (struct client *a_cl, char *an_url,
UhttpServer::get_instance().handle_request(a_cl, an_url, a_pi); UhttpServer::get_instance().handle_request(a_cl, an_url, a_pi);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn uhttp_server_data_send * @fn uhttp_server_data_send
* *
* @brief callback called when data should . * @brief callback called when data should .
*/ */
static int uhttp_server_data_send (struct client *a_cl, const char *a_data, int a_len) static int uhttp_server_data_send(struct client *a_cl, const char *a_data, int a_len)
{ {
#ifdef DEBUG_REQUEST #ifdef DEBUG_REQUEST
log_with_timestamp("uhttp_server_data_send"); log_with_timestamp("uhttp_server_data_send");
@@ -186,100 +177,92 @@ static int uhttp_server_data_send (struct client *a_cl, const char *a_data, int
return UhttpServer::get_instance().data_send(a_cl, a_data, a_len); return UhttpServer::get_instance().data_send(a_cl, a_data, a_len);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn uhttp_server_data_done * @fn uhttp_server_data_done
* *
* @brief callback called when the server is ready to launch the request. * @brief callback called when the server is ready to launch the request.
*/ */
static void uhttp_server_data_done (struct client *a_cl) static void uhttp_server_data_done(struct client *a_cl)
{ {
UhttpServer::get_instance().invoke_request(a_cl); UhttpServer::get_instance().invoke_request(a_cl);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn uhttp_server_request_free * @fn uhttp_server_request_free
* *
* @brief callback call to free the request. * @brief callback call to free the request.
*/ */
static void uhttp_server_request_free (struct client *a_cl) static void uhttp_server_request_free(struct client *a_cl)
{ {
#ifdef DEBUG_REQUEST #ifdef DEBUG_REQUEST
struct timeval the_current_timeval; struct timeval the_current_timeval;
gettimeofday(&the_current_timeval, NULL); gettimeofday(&the_current_timeval, NULL);
char buffer [BUFFER_SIZE]; char buffer[BUFFER_SIZE];
snprintf (buffer, sizeof(buffer), "client id: %d duree: %.0lf ms", a_cl->id, time_diff(a_cl->start_request , the_current_timeval) / 1000); snprintf(buffer, sizeof(buffer), "client id: %d duree: %.0lf ms", a_cl->id, time_diff(a_cl->start_request, the_current_timeval) / 1000);
log_with_timestamp(buffer); log_with_timestamp(buffer);
#endif #endif
UhttpServer::get_instance().request_free(a_cl); UhttpServer::get_instance().request_free(a_cl);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn uhttp_server_close_fds * @fn uhttp_server_close_fds
* *
* @brief callback call when the process close. (needed ? to be dfefined). * @brief callback call when the process close. (needed ? to be dfefined).
*/ */
static void uhttp_server_close_fds (struct client *cl) static void uhttp_server_close_fds(struct client *cl)
{ {
// printf("uhttp_server_close_fds(%p)... client id: %d\n", cl, cl->id); // printf("uhttp_server_close_fds(%p)... client id: %d\n", cl, cl->id);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_instance * @fn get_instance
* *
* @brief singleton to return the instance of UhttpServer. * @brief singleton to return the instance of UhttpServer.
*/ */
UhttpServer &UhttpServer::get_instance (void) UhttpServer &UhttpServer::get_instance(void)
{ {
static UhttpServer m_ptr; static UhttpServer m_ptr;
return m_ptr; return m_ptr;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn UhttpServer * @fn UhttpServer
* *
* @brief Constructor of the Uhttp Server * @brief Constructor of the Uhttp Server
*/ */
UhttpServer::UhttpServer (void): UhttpServer::UhttpServer(void) : m_ctx(NULL),
m_ctx(NULL), m_ops(NULL)
m_ops(NULL)
{ {
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn ~UhttpServer * @fn ~UhttpServer
* *
* @brief Destructor of the Uhttp Server * @brief Destructor of the Uhttp Server
*/ */
UhttpServer::~UhttpServer (void) UhttpServer::~UhttpServer(void)
{ {
ControllerIterator it; ControllerIterator it;
ConnectionIterator the_cnx_it; ConnectionIterator the_cnx_it;
for (it=m_controller_array.begin(); it!=m_controller_array.end(); ++it) { for (it = m_controller_array.begin(); it != m_controller_array.end(); ++it)
{
delete it->second; delete it->second;
} }
for (the_cnx_it=m_connections.begin(); the_cnx_it!=m_connections.end(); ++the_cnx_it) { for (the_cnx_it = m_connections.begin(); the_cnx_it != m_connections.end(); ++the_cnx_it)
{
delete the_cnx_it->second; delete the_cnx_it->second;
} }
ubus_free(m_ctx); ubus_free(m_ctx);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn setup * @fn setup
* *
* @brief setup the http server. * @brief setup the http server.
*/ */
int UhttpServer::setup (struct ubus_context *a_ctx, const struct uhttpd_ops *an_ops) int UhttpServer::setup(struct ubus_context *a_ctx, const struct uhttpd_ops *an_ops)
{ {
m_ctx = a_ctx; m_ctx = a_ctx;
m_ops = const_cast<struct uhttpd_ops *>(an_ops); m_ops = const_cast<struct uhttpd_ops *>(an_ops);
@@ -287,31 +270,28 @@ int UhttpServer::setup (struct ubus_context *a_ctx, const struct uhttpd_ops *an_
return load_config_dir(); return load_config_dir();
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_context * @fn get_context
* *
* @brief return the ubus context. * @brief return the ubus context.
*/ */
struct ubus_context *UhttpServer::get_context (void) struct ubus_context *UhttpServer::get_context(void)
{ {
return m_ctx; return m_ctx;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn check_url * @fn check_url
* *
* @brief check if the url is managed by this plugin. * @brief check if the url is managed by this plugin.
*/ */
bool UhttpServer::check_url (const std::string &an_url) bool UhttpServer::check_url(const std::string &an_url)
{ {
std::list<std::string>::iterator the_it; std::list<std::string>::iterator the_it;
// printf("UhttpServer::check_url: %s\n", an_url.c_str()); // printf("UhttpServer::check_url: %s\n", an_url.c_str());
for (the_it = m_path_list.begin(); the_it != m_path_list.end(); the_it++) { for (the_it = m_path_list.begin(); the_it != m_path_list.end(); the_it++)
{
if (an_url.find(*the_it) != std::string::npos) if (an_url.find(*the_it) != std::string::npos)
return true; return true;
} }
@@ -319,13 +299,12 @@ bool UhttpServer::check_url (const std::string &an_url)
return false; return false;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn handle_request * @fn handle_request
* *
* @brief Handle the Request. * @brief Handle the Request.
*/ */
void UhttpServer::handle_request (struct client *a_cl, const std::string &an_url, struct path_info *a_pi) void UhttpServer::handle_request(struct client *a_cl, const std::string &an_url, struct path_info *a_pi)
{ {
std::string the_url, the_parameters; std::string the_url, the_parameters;
std::size_t the_pos; std::size_t the_pos;
@@ -334,19 +313,21 @@ void UhttpServer::handle_request (struct client *a_cl, const std::string &an_url
// Check if parameters are present on the url. // Check if parameters are present on the url.
the_pos = an_url.find_first_of("?", 0); the_pos = an_url.find_first_of("?", 0);
if (the_pos != std::string::npos) { if (the_pos != std::string::npos)
{
// parameters are present. // parameters are present.
the_url = an_url.substr(0, the_pos); the_url = an_url.substr(0, the_pos);
the_parameters = an_url.substr(the_pos + 1); the_parameters = an_url.substr(the_pos + 1);
// printf("url: <%s> | parameters: <%s>\n", the_url.c_str(), the_parameters.c_str()); // printf("url: <%s> | parameters: <%s>\n", the_url.c_str(), the_parameters.c_str());
} }
else { else
{
the_url = an_url; the_url = an_url;
} }
the_controller = m_controller_array [the_url]; the_controller = m_controller_array[the_url];
if (the_controller == NULL) { if (the_controller == NULL)
{
std::string the_msg; std::string the_msg;
the_msg = fmt::format(kJsonControlerNotFound, the_url); the_msg = fmt::format(kJsonControlerNotFound, the_url);
send_error(a_cl, 404, "Not Found", the_msg); send_error(a_cl, 404, "Not Found", the_msg);
@@ -370,11 +351,11 @@ void UhttpServer::handle_request (struct client *a_cl, const std::string &an_url
break; break;
case UH_HTTP_MSG_OPTIONS: case UH_HTTP_MSG_OPTIONS:
{ {
HttpHeader the_http_header; HttpHeader the_http_header;
the_http_header.send_option(m_ops, a_cl, 200); the_http_header.send_option(m_ops, a_cl, 200);
} }
break; break;
default: default:
// printf("Invalid Request\n"); // printf("Invalid Request\n");
@@ -384,13 +365,12 @@ void UhttpServer::handle_request (struct client *a_cl, const std::string &an_url
// printf("uhttp_server_handle_request -done.\n"); // printf("uhttp_server_handle_request -done.\n");
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn invoke_request * @fn invoke_request
* *
* @brief This method to invoke the request. * @brief This method to invoke the request.
*/ */
void UhttpServer::invoke_request (struct client *a_client) void UhttpServer::invoke_request(struct client *a_client)
{ {
uh_client_ref(a_client); uh_client_ref(a_client);
// printf("UhttpServer::invoke_request\n"); // printf("UhttpServer::invoke_request\n");
@@ -399,22 +379,22 @@ void UhttpServer::invoke_request (struct client *a_client)
uh_client_unref(a_client); uh_client_unref(a_client);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn request_free * @fn request_free
* *
* @brief This method free the complete request. * @brief This method free the complete request.
*/ */
void UhttpServer::request_free (struct client *a_client) void UhttpServer::request_free(struct client *a_client)
{ {
ConnectionIterator the_it; ConnectionIterator the_it;
// printf("UhttpServer::request_free id:%d nb connection: %ld\n", a_client->id, m_connections.size()); // printf("UhttpServer::request_free id:%d nb connection: %ld\n", a_client->id, m_connections.size());
uh_client_ref(a_client); uh_client_ref(a_client);
the_it = m_connections.find(a_client->id); the_it = m_connections.find(a_client->id);
if (the_it != m_connections.end()) { if (the_it != m_connections.end())
{
if ((the_it->second)->should_be_removed()) { if ((the_it->second)->should_be_removed())
{
delete the_it->second; delete the_it->second;
m_connections.erase(the_it); m_connections.erase(the_it);
} }
@@ -424,24 +404,22 @@ void UhttpServer::request_free (struct client *a_client)
// printf("UhttpServer::request_free-done\n"); // printf("UhttpServer::request_free-done\n");
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn data_send * @fn data_send
* *
* @brief This method called when data arrived from the client. * @brief This method called when data arrived from the client.
*/ */
int UhttpServer::data_send (struct client *a_client, const char *a_data, int a_len) int UhttpServer::data_send(struct client *a_client, const char *a_data, int a_len)
{ {
return m_connections[a_client->id]->add_data(a_data, a_len); return m_connections[a_client->id]->add_data(a_data, a_len);
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn load_config_dir * @fn load_config_dir
* *
* @brief Load config from the configuration directory * @brief Load config from the configuration directory
*/ */
int UhttpServer::load_config_dir (void) int UhttpServer::load_config_dir(void)
{ {
DIR *the_rep = NULL; DIR *the_rep = NULL;
struct dirent *the_dir_ent = NULL; struct dirent *the_dir_ent = NULL;
@@ -449,17 +427,17 @@ int UhttpServer::load_config_dir (void)
struct json_object *the_root_node; struct json_object *the_root_node;
the_rep = opendir(kConfigDirectory); the_rep = opendir(kConfigDirectory);
while ((the_dir_ent = readdir(the_rep)) != NULL) { while ((the_dir_ent = readdir(the_rep)) != NULL)
{
if (strcmp(the_dir_ent->d_name, ".") != 0 && strcmp(the_dir_ent->d_name, "..") != 0) { if (strcmp(the_dir_ent->d_name, ".") != 0 && strcmp(the_dir_ent->d_name, "..") != 0)
{
// printf ("load: %s\n", the_dir_ent->d_name); // printf ("load: %s\n", the_dir_ent->d_name);
the_path = kConfigDirectory; the_path = kConfigDirectory;
the_path += the_dir_ent->d_name; the_path += the_dir_ent->d_name;
the_root_node = load(the_path); the_root_node = load(the_path);
if (the_root_node == NULL) { if (the_root_node == NULL)
{
fprintf(stderr, "Failed to load controller configuration file (%s).\n", the_path.c_str()); fprintf(stderr, "Failed to load controller configuration file (%s).\n", the_path.c_str());
return -1; return -1;
} }
@@ -467,20 +445,19 @@ int UhttpServer::load_config_dir (void)
add_controller_from_json(the_root_node); add_controller_from_json(the_root_node);
json_object_put(the_root_node); json_object_put(the_root_node);
} }
} }
closedir(the_rep); closedir(the_rep);
return 0; return 0;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn add_controller_from_json * @fn add_controller_from_json
* *
* @brief Load config from the configuration directory * @brief Load config from the configuration directory
*/ */
int UhttpServer::add_controller_from_json (struct json_object *a_root_node) int UhttpServer::add_controller_from_json(struct json_object *a_root_node)
{ {
struct json_object *the_ctr_array_node, *the_ctrl_node, *the_note_array_node, *the_etag_ctrl_array_node; struct json_object *the_ctr_array_node, *the_ctrl_node, *the_note_array_node, *the_etag_ctrl_array_node;
@@ -489,15 +466,16 @@ int UhttpServer::add_controller_from_json (struct json_object *a_root_node)
int the_len; int the_len;
int i; int i;
if (json_object_object_get_ex(a_root_node, kControllerKey, &the_ctr_array_node)) { if (json_object_object_get_ex(a_root_node, kControllerKey, &the_ctr_array_node))
{
the_len = json_object_array_length(the_ctr_array_node); the_len = json_object_array_length(the_ctr_array_node);
for (i = 0; i < the_len; i++) { for (i = 0; i < the_len; i++)
{
the_ctrl_node = json_object_array_get_idx(the_ctr_array_node, i); the_ctrl_node = json_object_array_get_idx(the_ctr_array_node, i);
if (get_controller_fields(the_ctrl_node, the_path, the_model_name, the_event_name, the_etag_key, the_get_method, the_set_method, the_raw_response)) { if (get_controller_fields(the_ctrl_node, the_path, the_model_name, the_event_name, the_etag_key, the_get_method, the_set_method, the_raw_response))
{
#if 0 #if 0
printf("Path: <%s>\n", the_path.c_str()); printf("Path: <%s>\n", the_path.c_str());
printf("\t- model name: <%s>\n", the_model_name.c_str()); printf("\t- model name: <%s>\n", the_model_name.c_str());
@@ -509,16 +487,16 @@ int UhttpServer::add_controller_from_json (struct json_object *a_root_node)
} }
} }
} }
if (json_object_object_get_ex(a_root_node, kEtagControllerKey, &the_etag_ctrl_array_node)) { if (json_object_object_get_ex(a_root_node, kEtagControllerKey, &the_etag_ctrl_array_node))
{
the_len = json_object_array_length(the_etag_ctrl_array_node); the_len = json_object_array_length(the_etag_ctrl_array_node);
for (i = 0; i < the_len; i++) { for (i = 0; i < the_len; i++)
{
the_ctrl_node = json_object_array_get_idx(the_etag_ctrl_array_node, i); the_ctrl_node = json_object_array_get_idx(the_etag_ctrl_array_node, i);
if (get_controller_fields(the_ctrl_node, the_path, the_model_name, the_event_name, the_etag_key, the_get_method, the_set_method, the_raw_response)) { if (get_controller_fields(the_ctrl_node, the_path, the_model_name, the_event_name, the_etag_key, the_get_method, the_set_method, the_raw_response))
{
EtagRestController *the_etag_rest_controller; EtagRestController *the_etag_rest_controller;
the_etag_rest_controller = new EtagRestController(the_model_name, the_event_name, the_etag_key, the_get_method, the_set_method, kDefaultTimeout, the_raw_response); the_etag_rest_controller = new EtagRestController(the_model_name, the_event_name, the_etag_key, the_get_method, the_set_method, kDefaultTimeout, the_raw_response);
@@ -526,16 +504,16 @@ int UhttpServer::add_controller_from_json (struct json_object *a_root_node)
} }
} }
} }
if (json_object_object_get_ex(a_root_node, kNotificationKey, &the_note_array_node)) { if (json_object_object_get_ex(a_root_node, kNotificationKey, &the_note_array_node))
{
the_len = json_object_array_length(the_note_array_node); the_len = json_object_array_length(the_note_array_node);
for (i = 0; i < the_len; i++) { for (i = 0; i < the_len; i++)
{
the_ctrl_node = json_object_array_get_idx(the_note_array_node, i); the_ctrl_node = json_object_array_get_idx(the_note_array_node, i);
if (get_controller_fields(the_ctrl_node, the_path, the_model_name, the_event_name, the_etag_key, the_get_method, the_set_method, the_raw_response)) { if (get_controller_fields(the_ctrl_node, the_path, the_model_name, the_event_name, the_etag_key, the_get_method, the_set_method, the_raw_response))
{
NotificationController *the_notification_controller; NotificationController *the_notification_controller;
the_notification_controller = new NotificationController(the_event_name); the_notification_controller = new NotificationController(the_event_name);
add_controller(the_path, the_notification_controller); add_controller(the_path, the_notification_controller);
@@ -546,82 +524,94 @@ int UhttpServer::add_controller_from_json (struct json_object *a_root_node)
return 0; return 0;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn get_controller_fields * @fn get_controller_fields
* *
* @brief This method extract the controller fields from a json node. * @brief This method extract the controller fields from a json node.
*/ */
bool UhttpServer::get_controller_fields (struct json_object *a_node, std::string &a_path, std::string &a_model_name, bool UhttpServer::get_controller_fields(struct json_object *a_node, std::string &a_path, std::string &a_model_name,
std::string &an_event_name, std::string &an_etag_key, std::string &an_event_name, std::string &an_etag_key,
std::string &a_get_method, std::string &a_set_method, bool &a_raw_response) std::string &a_get_method, std::string &a_set_method, bool &a_raw_response)
{ {
bool the_result = false; bool the_result = false;
struct json_object *the_path_node, *the_ubus_model_node, *the_ubus_event_node, *the_get_method_node, *the_etag_key_node; struct json_object *the_path_node, *the_ubus_model_node, *the_ubus_event_node, *the_get_method_node, *the_etag_key_node;
struct json_object *the_set_method_node, *the_raw_response_node; struct json_object *the_set_method_node, *the_raw_response_node;
// path // path
if (json_object_object_get_ex(a_node, kControllerPathKey, &the_path_node)) { if (json_object_object_get_ex(a_node, kControllerPathKey, &the_path_node))
{
a_path = json_object_get_string(the_path_node); a_path = json_object_get_string(the_path_node);
the_result = true; the_result = true;
} }
else { else
{
a_path.clear(); a_path.clear();
} }
// model_name // model_name
if (json_object_object_get_ex(a_node, kControllerModelNameKey, &the_ubus_model_node)) { if (json_object_object_get_ex(a_node, kControllerModelNameKey, &the_ubus_model_node))
{
a_model_name = json_object_get_string(the_ubus_model_node); a_model_name = json_object_get_string(the_ubus_model_node);
} }
else { else
{
a_model_name.clear(); a_model_name.clear();
} }
// event name // event name
if (json_object_object_get_ex(a_node, kControllerEventNameKey, &the_ubus_event_node)) { if (json_object_object_get_ex(a_node, kControllerEventNameKey, &the_ubus_event_node))
{
an_event_name = json_object_get_string(the_ubus_event_node); an_event_name = json_object_get_string(the_ubus_event_node);
} }
else { else
{
an_event_name.clear(); an_event_name.clear();
} }
// etag key // etag key
if (json_object_object_get_ex(a_node, kControllerEtagKey, &the_etag_key_node)) { if (json_object_object_get_ex(a_node, kControllerEtagKey, &the_etag_key_node))
{
an_etag_key = json_object_get_string(the_etag_key_node); an_etag_key = json_object_get_string(the_etag_key_node);
} }
else { else
{
an_etag_key.clear(); an_etag_key.clear();
} }
// get_method // get_method
if (json_object_object_get_ex(a_node, kControllerGetMethodKey, &the_get_method_node)) { if (json_object_object_get_ex(a_node, kControllerGetMethodKey, &the_get_method_node))
{
a_get_method = json_object_get_string(the_get_method_node); a_get_method = json_object_get_string(the_get_method_node);
} }
else { else
{
a_get_method = kdefaultGetMethod; a_get_method = kdefaultGetMethod;
} }
// set_method // set_method
if (json_object_object_get_ex(a_node, kControllerSetMethodKey, &the_set_method_node)) { if (json_object_object_get_ex(a_node, kControllerSetMethodKey, &the_set_method_node))
{
a_set_method = json_object_get_string(the_set_method_node); a_set_method = json_object_get_string(the_set_method_node);
} }
else { else
{
a_set_method = kdefaultSetMethod; a_set_method = kdefaultSetMethod;
} }
// raw_response // raw_response
if (json_object_object_get_ex(a_node, kControllerRawResponseKey, &the_raw_response_node)) { if (json_object_object_get_ex(a_node, kControllerRawResponseKey, &the_raw_response_node))
{
a_raw_response = json_object_get_boolean(the_raw_response_node); a_raw_response = json_object_get_boolean(the_raw_response_node);
} }
else { else
{
a_raw_response = false; a_raw_response = false;
} }
return the_result; return the_result;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn load * @fn load
* *
* @brief This method load the restd controllers and file it into a json object. * @brief This method load the restd controllers and file it into a json object.
* return null otherwise. * return null otherwise.
*/ */
struct json_object *UhttpServer::load (const std::string &a_file) struct json_object *UhttpServer::load(const std::string &a_file)
{ {
struct json_object *the_root_node = NULL; struct json_object *the_root_node = NULL;
struct stat the_stat; struct stat the_stat;
@@ -629,21 +619,21 @@ struct json_object *UhttpServer::load (const std::string &a_file)
char *the_addr; char *the_addr;
the_fd = open(a_file.c_str(), O_RDONLY); the_fd = open(a_file.c_str(), O_RDONLY);
if (the_fd == -1) { if (the_fd == -1)
{
perror("open"); perror("open");
return NULL; return NULL;
} }
if (fstat(the_fd, &the_stat) == -1) { if (fstat(the_fd, &the_stat) == -1)
{
perror("fstat"); perror("fstat");
close(the_fd); close(the_fd);
return NULL; return NULL;
} }
the_addr = (char *) mmap(NULL, the_stat.st_size, PROT_READ, MAP_PRIVATE, the_fd, 0); the_addr = (char *)mmap(NULL, the_stat.st_size, PROT_READ, MAP_PRIVATE, the_fd, 0);
if (the_addr == MAP_FAILED) { if (the_addr == MAP_FAILED)
{
perror("mmap"); perror("mmap");
close(the_fd); close(the_fd);
return NULL; return NULL;
@@ -656,13 +646,12 @@ struct json_object *UhttpServer::load (const std::string &a_file)
return the_root_node; return the_root_node;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn add_rest_controller * @fn add_rest_controller
* *
* @brief add a rest controller. * @brief add a rest controller.
*/ */
int UhttpServer::add_controller (const std::string &an_uri, WebController *a_controller) int UhttpServer::add_controller(const std::string &an_uri, WebController *a_controller)
{ {
std::string the_path; std::string the_path;
std::size_t the_pos; std::size_t the_pos;
@@ -676,10 +665,11 @@ int UhttpServer::add_controller (const std::string &an_uri, WebController *a_con
// Keep a list of the API root. to check if a controller is managed by this plugin or not. // Keep a list of the API root. to check if a controller is managed by this plugin or not.
the_pos = an_uri.find_first_of("/", 1); the_pos = an_uri.find_first_of("/", 1);
if (the_pos != std::string::npos) { if (the_pos != std::string::npos)
{
the_path = an_uri.substr(0, the_pos + 1); the_path = an_uri.substr(0, the_pos + 1);
if (std::find(m_path_list.begin(), m_path_list.end(), the_path) == m_path_list.end()) { if (std::find(m_path_list.begin(), m_path_list.end(), the_path) == m_path_list.end())
{
// uniq version. we add it. // uniq version. we add it.
m_path_list.push_back(the_path); m_path_list.push_back(the_path);
} }
@@ -688,13 +678,12 @@ int UhttpServer::add_controller (const std::string &an_uri, WebController *a_con
return 0; return 0;
} }
/*! ---------------------------------------------------------------------------- /*! ----------------------------------------------------------------------------
* @fn send_error * @fn send_error
* *
* @brief Send an error message to the client. * @brief Send an error message to the client.
*/ */
void UhttpServer::send_error (struct client *a_cl, int a_code, const char *a_summary, const std::string &a_msg) void UhttpServer::send_error(struct client *a_cl, int a_code, const char *a_summary, const std::string &a_msg)
{ {
m_ops->http_header(a_cl, a_code, a_summary); m_ops->http_header(a_cl, a_code, a_summary);
ustream_printf(a_cl->us, "Content-Type: application/json\r\n\r\n"); ustream_printf(a_cl->us, "Content-Type: application/json\r\n\r\n");

View File

@@ -31,7 +31,6 @@
/*--------------------------------- Define ----------------------------------*/ /*--------------------------------- Define ----------------------------------*/
/*----------------------------- Dependencies --------------------------------*/ /*----------------------------- Dependencies --------------------------------*/
struct ubus_context; struct ubus_context;
@@ -43,42 +42,42 @@ class WebConnection;
/*--------------------------------- CLASS ----------------------------------*/ /*--------------------------------- CLASS ----------------------------------*/
class UhttpServer { class UhttpServer
{
public: public:
typedef std::unordered_map<std::string, WebController *> ControllerContainer; typedef std::unordered_map<std::string, WebController *> ControllerContainer;
typedef ControllerContainer::iterator ControllerIterator; typedef ControllerContainer::iterator ControllerIterator;
typedef std::unordered_map <int, WebConnection *> ConnectionContainer; typedef std::unordered_map<int, WebConnection *> ConnectionContainer;
typedef ConnectionContainer::iterator ConnectionIterator; typedef ConnectionContainer::iterator ConnectionIterator;
public: public:
UhttpServer (void); UhttpServer(void);
~UhttpServer (void); ~UhttpServer(void);
static UhttpServer &get_instance (void); static UhttpServer &get_instance(void);
int setup (struct ubus_context *a_ctx, const struct uhttpd_ops *an_ops); int setup(struct ubus_context *a_ctx, const struct uhttpd_ops *an_ops);
struct ubus_context *get_context (void); struct ubus_context *get_context(void);
bool check_url (const std::string &an_url); bool check_url(const std::string &an_url);
void handle_request (struct client *a_cl, const std::string &an_url, struct path_info *a_pi); void handle_request(struct client *a_cl, const std::string &an_url, struct path_info *a_pi);
void invoke_request (struct client *a_client); void invoke_request(struct client *a_client);
void request_free (struct client *a_client); void request_free(struct client *a_client);
int data_send (struct client *a_client, const char *a_data, int a_len); int data_send(struct client *a_client, const char *a_data, int a_len);
private: private:
int load_config_dir (void); int load_config_dir(void);
int add_controller_from_json (struct json_object *a_root_node); int add_controller_from_json(struct json_object *a_root_node);
bool get_controller_fields (struct json_object *a_node, std::string &a_path, std::string &a_model_name, bool get_controller_fields(struct json_object *a_node, std::string &a_path, std::string &a_model_name,
std::string &an_event_name, std::string &an_etag_key, std::string &an_event_name, std::string &an_etag_key,
std::string &a_get_method, std::string &a_set_method, bool &a_raw_response); std::string &a_get_method, std::string &a_set_method, bool &a_raw_response);
struct json_object *load (const std::string &a_file); struct json_object *load(const std::string &a_file);
int add_controller (const std::string &an_uri, WebController *a_controller); int add_controller(const std::string &an_uri, WebController *a_controller);
void send_error (struct client *a_cl, int a_code, const char *a_summary, const std::string &a_msg); void send_error(struct client *a_cl, int a_code, const char *a_summary, const std::string &a_msg);
private: private:
struct ubus_context *m_ctx; struct ubus_context *m_ctx;
struct uhttpd_ops *m_ops; struct uhttpd_ops *m_ops;
ControllerContainer m_controller_array; ControllerContainer m_controller_array;