static json_t *mbp_post(struct rest_uri_param *param) { json_t *req; int8 *action = NULL; int32 cm_lid; cm_lid = get_asset_idx(param, "mbp_id", MC_TYPE_CM); if (cm_lid == -1) { HTTPD_ERR("get cm loc lid fail\n"); return NULL; } update_response_info(param, HTTP_APPLICATION_ERROR); req = json_parse_with_len(param->json_data, (int32)(param->content_length)); if (req == NULL) { HTTPD_ERR("json parse error\n"); return NULL; } action = json_string_value(json_object_get(req, RMM_JSON_ACTION)); if (action == NULL) { HTTPD_ERR("get action error\n"); json_free(req); return NULL; } if (0 == strcmp(action, RMM_JSON_UPDATE)) { HTTPD_INFO("processing mbp reset\n"); return mbp_process_update(req, cm_lid, param); } else if (0 == strcmp(action, RMM_JSON_RESET)) { HTTPD_INFO("processing mbp reset\n"); return mbp_process_reset(req, cm_lid, param); } else if (0 == strcmp(action, RMM_JSON_SETUARTTARGET)) { HTTPD_INFO("processing mbp set uart target\n"); return mbp_set_uart_target(req, cm_lid, param); } json_free(req); return NULL; }
int32 main(int32 argc, int8 **argv) { if (rmm_modules_init(MODULEINIT_LOG | MODULEINIT_COREDUMP | MODULEINIT_ASSETD | MODULEINIT_REDFISHD, IPMIWEBSOCKET_PORT, JSONRPCINIT_MEMDB | JSONRPCINIT_JIPMI) == -1) { exit(-1); } if (is_asset_module_ready(10) == -1) exit(-1); HTTPD_INFO("Restd start ...\n"); main_loop(); return 0; }
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; }
static int32 main_loop() { int32 rc = 0; int32 conn_fd = -1; int32 listen_fd = -1; fd_set rfds; socklen_t addrlen = 0; usockaddr usa; pthread_t tid_ipmi_cb; struct sigaction sa; struct http_request *request = NULL; int32 port = 0; /* ingore sigpipe */ sa.sa_handler = SIG_IGN; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(SIGPIPE, &sa, 0); rest_register_handlers(); port = rmm_cfg_get_port(RESTD_PORT); listen_fd = open_listen_socket(port); if (listen_fd == -1) { HTTPD_ERR("Failed to open HTTP server!\n"); return -1; } fprintf(stderr, "Mini-HTTP Server is Running ...\n"); /* Create IPMI callback thread. */ if (pthread_create(&tid_ipmi_cb, NULL, ipmi_cb_thread, NULL) != 0) { close(listen_fd); HTTPD_ERR("Failed to create ipmi callback thread!\n"); return -1; } for (;;) { FD_ZERO(&rfds); FD_SET(listen_fd, &rfds); rc = select(listen_fd + 1, &rfds, NULL, NULL, NULL); if (rc <= 0) continue; addrlen = sizeof(usa); conn_fd = accept(listen_fd, &usa.sa, &addrlen); if (conn_fd < 0) continue; HTTPD_INFO("restd accepted a new connection: fd = %d\n", conn_fd); request = malloc(sizeof(struct http_request)); if (NULL == request) { HTTPD_ERR("Malloc error: %s\n", strerror(errno)); return -1; } memset(request, 0, sizeof(struct http_request)); request->fd = conn_fd; request->from = usa; if (pthread_create(&request->tid_rest_req, NULL, http_process, (void *)request) != 0) { HTTPD_ERR("Failed to create rest_req_thread!\n"); return -1; } } return 0; }