#ifndef __INCLUDE_HTTPUTIL_H__ #define __INCLUDE_HTTPUTIL_H__ /* * Copyright (c) 2013, 2016 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 * */ #include /* for ... string */ #include /* for ... http libevent client */ #include #include #include /* for ... F_GETFL */ using namespace std; #include "nodeBase.h" #include "timeUtil.h" /* for ... time_delta_type */ /* HTTP Error Codes with no specific existing define MACRO */ #define MTC_HTTP_BAD_REQUEST 400 #define MTC_HTTP_UNAUTHORIZED 401 #define MTC_HTTP_FORBIDDEN 403 #define MTC_HTTP_METHOD_NOT_ALLOWED 405 #define MTC_HTTP_CONFLICT 409 #define MTC_HTTP_LENGTH_REQUIRED 411 #define MTC_HTTP_NORESPONSE 444 #define MTC_HTTP_UNPROCESSABLE_ENTITY 422 #define MTC_HTTP_ACCEPTED 202 #define EVENT_METHODS (EVHTTP_REQ_PATCH | \ EVHTTP_REQ_POST | \ EVHTTP_REQ_GET | \ EVHTTP_REQ_PUT | \ EVHTTP_REQ_DELETE) /** Maximum libevent response message size in bytes. */ // #define MAX_EVENT_LEN (163840) #define MAX_URL_LEN (200) #define HTTP_VIM_TIMEOUT (20) #define HTTP_MAX_RETRIES (3) #define HTTP_SYSINV_CRIT_TIMEOUT (20) #define HTTP_SYSINV_NONC_TIMEOUT (10) #define HTTP_TOKEN_TIMEOUT (30) #define HTTP_KEYSTONE_GET_TIMEOUT (10) #define HTTP_SMGR_TIMEOUT (20) #define HTTP_VIM_TIMEOUT (20) #define HTTP_SECRET_TIMEOUT (5) #define SMGR_MAX_RETRIES (3) #define CLIENT_HEADER "User-Agent" #define CLIENT_SYSINV_1_0 "sysinv/1.0" #define EVENT_SERVER "HTTP Event Server" #define SMGR_EVENT_SIG "smgrEvent" #define SYSINV_EVENT_SIG "sysinvEvent" #define SECRET_EVENT_SIG "secretEvent" #define KEYSTONE_SIG "token" #define SENSOR_SIG "sensor" #define SYSINV_SIG "sysinv" #define SMGR_SIG "smgr" #define VIM_SIG "vim" #define SECRET_SIG "secret" #define SYSINV_OPER__LOAD_HOST "load host" #define SYSINV_OPER__UPDATE_TASK "update task" #define SYSINV_OPER__FORCE_TASK "force task" #define SYSINV_OPER__UPDATE_UPTIME "update uptime" #define SYSINV_OPER__UPDATE_VALUE "update value" #define SYSINV_OPER__UPDATE_STATE "update state" #define SYSINV_OPER__UPDATE_STATES "update states" #define SYSINV_OPER__FORCE_STATES "force states" #define SYSINV_OPER__CONFIG_SHOW "config show" #define SYSINV_OPER__CONFIG_MODIFY "config modify" #define VIM_HOST__DISABLED "disabled" #define VIM_HOST__ENABLED "enabled" #define VIM_HOST__OFFLINE "offline" #define VIM_HOST__FAILED "failed" /** The workQueue_process FSM states */ typedef enum { HTTP__TRANSMIT = 0, HTTP__RECEIVE_WAIT = 1, HTTP__RECEIVE = 2, HTTP__FAILURE = 3, HTTP__DONE_FAIL = 4, HTTP__DONE_PASS = 5, HTTP__STAGES = 6 } httpStages_enum ; #define HTTP_RECEIVE_WAIT_MSEC (10) typedef struct { string url ; /**< Keystone server URL string */ string issued ; /**< Timestamp token was issued */ string expiry ; /**< Timestamp when token is expired */ string token ; /**< The huge 3kb token */ bool refreshed; /**< set true when refreshed */ bool delay ; /**< trigger renew with small delay error renewal - flood avoidance */ } keyToken_type ; typedef enum { MTC_SECRET__START = 0, MTC_SECRET__GET_REF, MTC_SECRET__GET_REF_FAIL, MTC_SECRET__GET_REF_RECV, MTC_SECRET__GET_PWD, MTC_SECRET__GET_PWD_FAIL, MTC_SECRET__GET_PWD_RECV, MTC_SECRET__STAGES, } mtc_secretStages_enum ; typedef struct { string reference; string payload ; mtc_secretStages_enum stage ; } barbicanSecret_type; /** All supported Request Type Enums */ typedef enum { SERVICE_NONE, SYSINV_ADD, SYSINV_GET, SYSINV_HOST_QUERY, SYSINV_UPDATE, SYSINV_CONFIG_SHOW, SYSINV_CONFIG_MODIFY, SYSINV_SENSOR_LOAD, SYSINV_SENSOR_LOAD_GROUPS, SYSINV_SENSOR_LOAD_GROUP, SYSINV_SENSOR_ADD, SYSINV_SENSOR_ADD_GROUP, SYSINV_SENSOR_DEL, SYSINV_SENSOR_DEL_GROUP, SYSINV_SENSOR_MOD, SYSINV_SENSOR_MOD_GROUP, SYSINV_SENSOR_GROUP_SENSORS, VIM_UPDATE, VIM_HOST_DISABLED, VIM_HOST_ENABLED, VIM_HOST_OFFLINE, VIM_HOST_FAILED, VIM_DPORT_FAILED, VIM_DPORT_CLEARED, VIM_DPORT_DEGRADED, VIM_DPORT_OFFLINE, VIM_HOST_QUERY, VIM_HOST_STATE_QUERY, VIM_HOST_INSTANCE_QUERY, VIM_HOST_INSTANCE_FAILED, VIM_HOST_INSTANCE_STATUS, VIM_HOST_INSTANCE_NOTIFY, SMGR_START_SWACT, SMGR_QUERY_SWACT, SMGR_HOST_UNLOCKED, SMGR_HOST_LOCKED, SMGR_HOST_ENABLED, SMGR_HOST_DISABLED, KEYSTONE_TOKEN, KEYSTONE_GET_TOKEN, KEYSTONE_GET_SERVICE_LIST, KEYSTONE_GET_ENDPOINT_LIST, BARBICAN_GET_SECRET, BARBICAN_READ_SECRET, SERVICE_LAST } libEvent_enum ; /** Local event control structure for REST API services * * Nova, Neutron, Keystone, Barbican and Inventory * */ struct libEvent { /** Execution Controls */ httpStages_enum state ; /**< This http request FSM state */ int sequence ; /**< Event sequence number */ bool mutex ; /**< single operation at a time */ bool active ; /**< true if waiting on response */ int stuck ; /**< Count mutex active stuck state */ bool blocking ; /**< true if command is blocking */ bool found ; /**< true if query was found */ int timeout ; /**< Request timeout */ int count ; /**< retry recover counter */ int fails ; /**< fail counter */ int retries ; /**< number of retries on failure*/ int cur_retries ; int max_retries ; bool noncritical ; /**< true: event is non-ctitical */ int rx_retry_cnt ; /**< help avoid infinite rx retry*/ int rx_retry_max ; /**< each cmd can have a max */ /* HTTP request Info */ enum evhttp_cmd_type type; /**< HTTP Request Type ; PUT/GET */ struct event_base *base; /**< libEvent API service base */ struct evhttp_connection *conn; /**< HTTP connection ptr */ struct evhttp_request *req ; /**< HTTP request ptr */ struct evbuffer *buf ; /**< HTTP output buffer ptr */ struct evbuffer_ptr evp ; /**< HTTP output buffer ptr */ int fd ; struct sockaddr_in addr ; struct evhttp *httpd ; string log_prefix ; /**< log prefix for this event */ /** Service Specific Request Info */ libEvent_enum request ; /**< Specify the request command */ keyToken_type token ; /**< Copy of the active token */ string service ; /**< Service being executed */ string hostname ; /**< Target hostname */ string uuid ; /**< The UUID for this request */ string new_uuid ; /**< The UUID created & returned */ string ip ; /**< Server IP address */ int port ; /**< Server port number */ string operation ; /**< Specify the operation */ string information ; string key ; string value ; string prefix_path ; string label ; /**< typically a response label */ string entity_path ; /**< HTTP entity request string */ string entity_path_next ; /**< next entity request string */ string address ; /**< http url address */ string payload ; /**< the request's payload */ string user_agent ; /**< set the User-Agent header */ /** Result Info */ int status ; /**< Execution Status */ int http_status ; /**< raw http returned status */ int exec_time_msec ; /**< execution time in msec */ node_inv_type inv_info ; size_t response_len ; /**< the json response length */ string response ; /**< the json response string */ string result ; /**< Command specific result str */ /* Endpoint strings */ string admin_url ; string internal_url ; string public_url ; time_debug_type send_time ; /**< Request Dispatch Timestamp */ time_debug_type done_time ; /**< Response Handler Timestamp */ time_delta_type diff_time ; /**< how long the command handling took */ bool low_wm ; bool med_wm ; bool high_wm ; int (*handler) (struct libEvent &) ; char req_str[MAX_API_LOG_LEN] ; unsigned long long prev_time ; /* latency log candidate start (prev) time */ unsigned long long this_time ; /* ... end (now or this) time */ } ; typedef struct { struct event_base * base_ptr ; struct libEvent * event_ptr ; } event_base_pair_type ; typedef struct { int elements ; list pair_list ; } event_base_list_type ; /** Maximum number of headers that can be added to an HTTP message. */ #define MAX_HEADERS (10) /** A header entry type. */ typedef struct { string key ; /**< the header label. */ string value ; /**< the header value. */ } http_header_entry_type; /** The header entry table. */ typedef struct { int entries ; /**< Number of entries in the header table. */ http_header_entry_type entry[MAX_HEADERS]; /**< entry array. */ } http_headers_type ; void httpUtil_init ( void ); int httpUtil_event_init ( libEvent * ptr , string hostname, string service, string ip, int port ); /** Add payload to the HTTP message body. */ int httpUtil_payload_add ( libEvent & event ); /** Add all headers in header table to the HTTP connection message. */ int httpUtil_header_add ( libEvent * ptr, http_headers_type * hdrs_ptr ); /** Create an HTTP request. */ int httpUtil_request_make ( libEvent * ptr, enum evhttp_cmd_type type, string path ); /** Open a connection to an HTTP server. */ int httpUtil_connect ( libEvent & event ); /** Get a new HTTP request pointer. */ int httpUtil_request ( libEvent & event, void(*hdlr)(struct evhttp_request *, void *)); /** Common REST API Request Utility */ int httpUtil_api_request ( libEvent & event ); /** Common REST API Request Utility */ int httpUtil_request ( libEvent & event , bool block, void(*hdlr)(struct evhttp_request *, void *)); /** Common REST API Receive Utility for non-blocking requests */ int httpUtil_receive ( libEvent & event ); /** HTTP response status checker */ int httpUtil_status ( libEvent & event ); /** Free the libEvent */ void httpUtil_free_base ( libEvent & event ); /** Free the event lib connection */ void httpUtil_free_conn ( libEvent & event ); /** TODO: FIXME: Get the payload string length. */ string httpUtil_payload_len ( libEvent * ptr ); /** Get the length of the json response */ int httpUtil_get_length ( libEvent & event ); /** Load the json response into the event struct */ int httpUtil_get_response ( libEvent & event ); /** print event filtered event */ void httpUtil_log_event ( libEvent * event ); void httpUtil_event_info ( libEvent & event ); const char * getHttpCmdType_str ( evhttp_cmd_type type ); /* HTTP Server setup utilities */ int httpUtil_bind ( libEvent & event ); int httpUtil_setup ( libEvent & event, int supported_methods, void(*hdlr)(struct evhttp_request *, void *)); /* Cleanup */ void httpUtil_fini ( libEvent & event ); void httpUtil_look ( libEvent & event ); #endif /* __INCLUDE_HTTPUTIL_H__ */