static int32 add_headers(int8 *buf, int32 status, const int8 *title, const int8 *extra_header, const int8 *mime_type) { int32 len = 0; time_t now; int8 timebuf[128]; struct tm *gmt = NULL; len += snprintf_s_sis(&buf[len], BUFFSIZ, "%s %d %s\r\n", HTTPD_PROTOCOL, status, (char *)title); len += snprintf_s_s(&buf[len], (BUFFSIZ - len), "Server: %s\r\n", HTTPD_SERVER_NAME); now = time(NULL); gmt = gmtime(&now); if (gmt == NULL) return 0; strftime(timebuf, sizeof(timebuf), HTTPD_RFC1123FMT, gmt); len += snprintf_s_s(&buf[len], (BUFFSIZ - len), "Date: %s\r\n", timebuf); if (extra_header != NULL) len += snprintf_s_s(&buf[len], (BUFFSIZ - len), "%s\r\n", (char *)extra_header); if (mime_type != NULL) len += snprintf_s_s(&buf[len], (BUFFSIZ - len), "Content-Type: %s\r\n", (char *)mime_type); len += snprintf(&buf[len], (BUFFSIZ - len), "Access-Control-Allow-Origin: *\r\n"); /* Allow swagger json access */ len += snprintf(&buf[len], (BUFFSIZ - len), "Access-Control-Allow-Headers:Content-Type, api_key, Authorization\r\n"); /* Allow swagger to allow method POSe */ len += snprintf(&buf[len], (BUFFSIZ - len), "Access-Control-Allow-Methods: GET,PUT,POST,DELETE\r\n"); len += snprintf(&buf[len], (BUFFSIZ - len), "Allow:OPTIONS,POST,PUT\r\n"); len += snprintf(&buf[len], (BUFFSIZ - len), "Proxy-Connection: Keep-Alive\r\n"); len += snprintf(&buf[len], (BUFFSIZ - len), "Connection: close\r\n"); len += snprintf(&buf[len], (BUFFSIZ - len), "\r\n"); return len; }
int32 process_listener(json_t *req, listener_dest_t *listener, int32 mask) { int8 *event_type = NULL; int8 *dest = NULL; int8 *context = NULL; int8 *protocol = NULL; int8 *name = NULL; int8 *description = NULL; json_t *elem = NULL; json_t *event_types = NULL; int32 array_size, i = 0; int32 rc = 0; context = json_string_value(json_object_get(req, RMM_JSON_CONTEXT)); dest = json_string_value(json_object_get(req, RMM_JSON_DEST)); protocol = json_string_value(json_object_get(req, RMM_JSON_PROTOCOL)); event_types = json_object_get(req, RMM_JSON_RF_EVT_TYPES); name = json_string_value(json_object_get(req, RMM_JSON_RF_NAME)); description = json_string_value(json_object_get(req, RMM_JSON_RF_DESC)); if (!(context && dest && protocol && event_types)) { HTTPD_ERR("get json string error\n"); return -1; } snprintf_s_s(listener->name, sizeof(listener->name), "%s", name); snprintf_s_s(listener->description, sizeof(listener->description), "%s", description); snprintf_s_s(listener->context, sizeof(listener->context), "%s", context); snprintf_s_s(listener->dest, sizeof(listener->dest), "%s", dest); snprintf_s_s(listener->protocol, sizeof(listener->protocol), "%s", protocol); listener->idx_mask = mask; array_size = json_array_size(event_types); if (is_event_types_valid(array_size, event_types) == -1) return -1; for (i = 0; i < array_size; i++) { elem = NULL; elem = json_array_get(event_types, i); if (elem == NULL) { HTTPD_ERR("get json array element error\n"); return -1; } event_type = json_string_value(elem); if(event_type == NULL) { HTTPD_ERR("get json string event error\n"); return -1; } if (subscribe_event(listener, event_type) != 0) return -1; } return 0; }
int32 evt_listener_init(evt_listener_t *listener, int32 mask, int32 listener_idx, const int8 *fmt, ...) { listener_t *header = NULL; int8 format[256] = {0}; listener_t *tmp; int8 prefix[PREFIX_LEN] = {0}; json_t *evt_type_item = NULL; int32 rs = 0; int32 count = 0; va_list args; rs = libwrap_get_evt_listeners_count(mask, &count); if (rs != 0 || listener_idx > count) { HTTPD_ERR("invalid listener index \n"); return -1; } snprintf_s_s(listener->copy_right, sizeof(listener->copy_right), "%s", RF_COPY_RIGHT); rs = rmm_cfg_get_rest_prefix(prefix, PREFIX_LEN); if (rs != 0) { HTTPD_ERR("get rest prefix fail\n"); return -1; } snprintf_s_ssss(format, sizeof(format), "%s%s%s%s", prefix, (char *)fmt, RF_EVENT_ODATA_CONTEXT_STR, RF_EVENT_LISTENER_MEMBER_STR); va_start(args, fmt); vsnprintf(listener->odata_context, CONTEXT_LEN, format, args); va_end(args); evt_type_item = json_array(); if (evt_type_item == NULL) { HTTPD_ERR("json array alloc fail\n"); return -1; } snprintf_s_ssssi(listener->odata_id, sizeof(listener->odata_id), "%s%s%s%s/%d", prefix , (char *)fmt , RF_EVENT_SERVICE_STR , RF_EVENT_SUBSCRIBE_STR , listener_idx); snprintf_s_s(listener->odata_type, sizeof(listener->odata_type), "%s", RF_EVENT_ODATA_TYPE_DEST); snprintf_s_i(listener->id, sizeof(listener->id), "%d", listener_idx); rs = libwrap_get_evt_listener(mask, listener, listener_idx); if (rs != 0) { HTTPD_ERR("get listeners fail\n"); return -1; } // snprintf(listener->context, sizeof(listener->context), "%s", RF_EVENT_CONTEXT_STR); // snprintf(listener->protocol, sizeof(listener->protocol), "%s", RF_EVENT_PROTOCOL_STR); return 0; }
result_t libwrap_get_listener_links(int reg, memdb_integer nid, rf_link_t *links) { int mask = 0; int subnode_num, i, j, index = 0; memdb_integer listener_nid = 0; char listener[256] = {0}; struct node_info *subnode = NULL; subnode = libdb_list_subnode(DB_RMM, nid, &subnode_num, NULL, LOCK_ID_NULL); for (i = 0; i < subnode_num; i++) { listener_nid = libwrap_get_subnode_id_by_type(subnode[i].node_id, MC_REDFISH_LISTENER); if (listener_nid == 0) continue; libdb_attr_get_int(DB_RMM, listener_nid, RF_EVENT_LISTENER_INDEXES_STR, &mask, LOCK_ID_NULL); if ((mask & reg) != 0) { libdb_attr_get_string(DB_RMM, listener_nid, RF_EVENT_LISTENER_DEST_STR, listener, 256, LOCK_ID_NULL); for (j = 0; j < index; j++) { if (strcmp(listener, links->listeners[j]) == 0) break; } if (j == index) { snprintf_s_s(links->listeners[index], sizeof(links->listeners[index]), "%s", listener); index++; } } } return RESULT_OK; }
int32 evt_listeners_init(evt_listeners_t *listeners, int32 mask, const int8 * fmt, ...) { json_t *result = NULL; json_t *jitem = NULL; json_t *evt_type_item = NULL; int32 i = 0; int8 evt_type[128]; listener_t *tmp; int8 format[256] = {0}; int8 prefix[PREFIX_LEN] = {0}; int8 buff[256] = {0}; int32 count = 0; int32 rs = 0; va_list args; snprintf_s_s(listeners->copy_right, sizeof(listeners->copy_right), "%s", RF_COPY_RIGHT); rs = rmm_cfg_get_rest_prefix(prefix, PREFIX_LEN); if (rs != 0) { HTTPD_ERR("get rest prefix fail\n"); return -1; } snprintf_s_ssss(format, sizeof(format), "%s%s%s%s", prefix, (char *)fmt, RF_EVENT_ODATA_CONTEXT_STR, RF_EVENT_EVT_MEMBER_STR); va_start(args, fmt); vsnprintf(listeners->odata_context, CONTEXT_LEN, format, args); va_end(args); snprintf_s_s(listeners->odata_type, sizeof(listeners->odata_type), "%s", RF_EVENT_ODATA_TYPE_DEST_COLL); snprintf_s_s(listeners->name, sizeof(listeners->name), "%s", RF_EVENT_LISTENERS_NAME); rs = libwrap_get_evt_listeners_count(mask, &count); if (rs != 0) { HTTPD_ERR("get listener count fail\n"); return -1; } listeners->num = count; for (i = 0; i < count; i++) { snprintf_s_ssssi(listeners->url[i], sizeof(listeners->url[i]), "%s%s%s%s/%d", prefix, (char *)fmt, RF_EVENT_SERVICE_STR, RF_EVENT_SUBSCRIBE_STR, (i + 1)); } return 0; }
memdb_integer get_asset_node_id(const struct rest_uri_param *param, const int8 *name) { int8 *p_uuid = NULL; int8 uuid[64] = {0}; memdb_integer node_id; p_uuid = rest_path_value(param, name); if (p_uuid == NULL) { HTTPD_ERR("get value from path fail\n"); return 0; } snprintf_s_s((int8 *)uuid, sizeof(uuid), "%s", p_uuid); libwrap_get_node_id_by_uuid(uuid, &node_id); return node_id; }
fpga_result sysfs_objectid_from_path(const char *sysfspath, uint64_t *object_id) { char sdevpath[SYSFS_PATH_MAX]; uint32_t major = 0; uint32_t minor = 0; fpga_result result; snprintf_s_s(sdevpath, SYSFS_PATH_MAX, "%s/dev", sysfspath); result = sysfs_read_u32_pair(sdevpath, &major, &minor, ':'); if (FPGA_OK != result) return result; *object_id = ((major & 0xFFF) << 20) | (minor & 0xFFFFF); return FPGA_OK; }
void send_error(int32 fd, int32 status, const int8 *title, const int8 *extra_header, const int8 *text) { int32 len = 0; int32 str_len = 0; int8 buf[BUFFSIZ]; len += add_headers(buf, status, title, extra_header, "text/html"); str_len = len; len += snprintf_s_isis(&buf[len], (BUFFSIZ - str_len), "<HTML>" "<HEAD><TITLE>%d %s</TITLE></HEAD>\n" "<BODY BGCOLOR=\"#cc9999\">" "<H4>%d %s</H4>\n", status, (char *)title, status, (char *)title); str_len = len; len += snprintf_s_s(&buf[len], (BUFFSIZ - str_len), "%s\n", (char *)text); str_len = len; len += snprintf(&buf[len], (BUFFSIZ - str_len), "</BODY></HTML>\n"); http_write(fd, buf, len); }
void generate_gami_reg_info(gami_reg_t *reg_info) { char ip_str[64]; bzero(ip_str, sizeof(ip_str)); libutils_net_get_ip("eth0", ip_str, sizeof(ip_str)); reg_info->ip_addr = inet_addr(ip_str); reg_info->port = rmm_cfg_get_port(ASSET_MODULE_PORT); strncpy_safe((char *)reg_info->name, __progname, MAX_NAME_LEN, MAX_NAME_LEN - 1); snprintf_s_s(reg_info->capability.cap_mbp[0], GAMI_MAX_NAME_LEN, "%s", RMM_JSON_RESET); snprintf_s_s(reg_info->capability.cap_mbp[1], GAMI_MAX_NAME_LEN, "%s", RMM_JSON_SETUARTTARGET); snprintf_s_s(reg_info->capability.cap_mbp[2], GAMI_MAX_NAME_LEN, "%s", RMM_JSON_UPDATE); snprintf_s_s(reg_info->capability.cap_psu[0], GAMI_MAX_NAME_LEN, "%s", RMM_JSON_REQ_STATE_CHANGE); snprintf_s_s(reg_info->capability.cap_fan[0], GAMI_MAX_NAME_LEN, "%s", RMM_JSON_REQ_STATE_CHANGE); snprintf_s_s(reg_info->capability.cap_fan[1], GAMI_MAX_NAME_LEN, "%s", RMM_JSON_SET_DESIRED_SPEED); snprintf_s_s(reg_info->capability.cap_drawer[0], GAMI_MAX_NAME_LEN, "%s", RMM_JSON_RESET); }
void *http_process(void *args) { int32 fd; struct http_request *req; int8 *cp = NULL; int8 *line = NULL; int8 *method = NULL; int8 *url = NULL; int8 *protocol = NULL; struct timeval timo; int32 optval = 1; int32 rc, rc_r, rc_s; int32 r = 0; if (NULL == args) return NULL; req = (struct http_request *)args; fd = req->fd; req->buff = malloc(BUFFSIZ); req->buff_size = BUFFSIZ; if (NULL == req->buff) { HTTPD_ERR("get_request_line malloc %d fail\n", BUFFSIZ); free(args); return NULL; } memset(req->buff, 0, BUFFSIZ); rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)); if (rc < 0) HTTPD_ERR("setsockopt error rc=%d errno=%d %s\n", rc, errno, strerror(errno)); timo.tv_sec = HTTPD_TIMO; timo.tv_usec = 0; rc_r = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timo, sizeof(timo)); rc_s = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timo, sizeof(timo)); if (rc_r < 0 || rc_s < 0) HTTPD_ERR("setsockopt error fd=%d rc=%d rc_r=%d rc_s=%d errno=%d %s\n", fd, rc, rc_r, rc_s, errno, strerror(errno)); /* GET / HTTP/1.1 */ method = get_request_line(req); if (method == NULL) goto close_task; url = parse_reqline(fd, method); if (url == NULL) goto close_task; protocol = parse_reqline(fd, url); if (protocol == NULL) goto close_task; req->method = http_method(method); if (req->method == M_OPTIONS) { send_error(fd, 204, "No Content", NULL, "Method OPTIONS."); goto close_task; } if (req->method == M_UNKNOWN) { send_error(fd, 400, "Bad Request", NULL, "Method Not Support."); goto close_task; } decode_url(req, url); HTTPD_INFO("method[%s] protocol[%s] url[%s] path[%s] query[%s]!\n", method, protocol, url, req->path, req->query ? : ""); while ((line = get_request_line(req)) != NULL) { if (line[0] == '\0') break; if (strncasecmp(line, "Upgrade:", 8) == 0) { cp = &line[8]; cp += strspn(cp, " \t"); if (strncasecmp(cp, "websocket", 9) == 0) req->is_websocket = 1; } else if (strncasecmp(line, "Connection:", 11) == 0) { cp = &line[11]; cp += strspn(cp, " \t"); /* Firefox: [Connection: keep-alive, Upgrade] */ if (strcasestr(cp, "Upgrade") != NULL) req->is_connection_upgrade = 1; } else if (strncasecmp(line, "Sec-WebSocket-Key:", 18) == 0) { cp = &line[18]; cp += strspn(cp, " \t"); req->sec_websocket_key = cp; } else if (strncasecmp(line, "Origin:", 7) == 0) { cp = &line[7]; cp += strspn(cp, " \t"); req->origin = cp; } else if (strncasecmp(line, "Sec-WebSocket-Version:", 22) == 0) { cp = &line[22]; cp += strspn(cp, " \t"); req->sec_websocket_version = atoi(cp); } else if (strncasecmp(line, "Content-Length:", 15) == 0) { cp = &line[15]; cp += strspn(cp, " \t"); req->content_length = atol(cp); if ((BUFFSIZ < req->content_length + MAX_HEADER_LEN) && (req->buff_size != req->content_length + MAX_HEADER_LEN) + 1) { re_alloc_buff(req); memset(req->buff + BUFFSIZ, 0, req->buff_size - BUFFSIZ); } } else if (strncasecmp(line, "Content-Type:", 13) == 0) { cp = &line[13]; cp += strspn(cp, " \t"); req->content_type = cp; } else if (strncasecmp(line, "Host:", 5) == 0) { cp = &line[5]; cp += strspn(cp, " \t"); req->host = cp; } } HTTPD_INFO("Left %d bytes HTTP data with Content-Length: %ld req->sz[%d] req->pos[%d]\n", req->sz - req->pos, req->content_length, req->sz, req->pos); if (line == NULL || req->path[0] != '/') send_error(fd, 400, "Bad Request", NULL, "Bad Request!"); if ((0 != req->content_length) && (req->sz != req->hd_sz + req->content_length)) { while ((r = http_read(req->fd, req->buff + req->sz, req->buff_size - req->sz)) > 0) { req->sz += r; if (req->sz == req->hd_sz + req->content_length) break; } } if (req->is_websocket) ws_process(req); else { uint32 i = 0; int8 *file = NULL; int8 *path = req->path; int8 *pTmp = path; int8 prefix[PREFIX_LEN] = {0}; int8 new_link[MAX_URL + 8] = {0}; rmm_cfg_get_rest_prefix(prefix, PREFIX_LEN); /*snprintf(new_link, (MAX_URL + 8), "%s%s", prefix, "/rack");*/ snprintf_s_s(new_link, (MAX_URL + 8), "%s", prefix); /*TODO: move to correct place */ get_json_pointer(req); /* remove redundant '/' */ for (; *(path+i) != '\0'; i++) { if ((*(path+i) == '/') && (*(path+i+1) == '/')) continue; *pTmp++ = *(path+i); } *pTmp = '\0'; if ((path[1] == '\0') || (strncasecmp(path, new_link, strnlen_s(new_link, sizeof(new_link)-1)) == 0)) file = NULL; else file = path; if (file != NULL) send_file(req->fd, file); else rest_process(req); } close_task: close(fd); if (NULL != req->buff) { free(req->buff); req->buff = NULL; } HTTPD_INFO("\nrest_req_thread[%lld] exit, fd[%d], errno:%d %s\n", (uint64)(req->tid_rest_req), fd, errno, strerror(errno)); free(args); pthread_detach(pthread_self()); return NULL; }