int http_request_handle()

in bundles/http_admin/http_admin/src/http_admin.c [176:350]


int http_request_handle(struct mg_connection *connection) {
    int ret_status = 400; //Default bad request

    if (connection != NULL) {
        const struct mg_request_info *ri = mg_get_request_info(connection);
        http_admin_manager_t *admin = (http_admin_manager_t *) ri->user_data;
        service_tree_node_t *node = NULL;

        if (mg_get_header(connection, "Upgrade") != NULL) {
            //Assume this is a websocket request...
            ret_status = 0; //... so return zero to let the civetweb server handle the request.
        }
        else {
            celix_auto(celix_rwlock_rlock_guard_t) lock = celixRwlockRlockGuard_init(&(admin->admin_lock));
            const char *req_uri = ri->request_uri;
            node = findServiceNodeInTree(&admin->http_svc_tree, req_uri);

            if (node != NULL) {
                //Requested URI with node exists, now obtain the http service and call the requested function.
                celix_http_service_t *httpSvc = (celix_http_service_t *) node->svc_data->service;

                if (strcmp("GET", ri->request_method) == 0) {
                    if (httpSvc->doGet != NULL) {
                        ret_status = httpSvc->doGet(httpSvc->handle, connection, req_uri);
                    } else {
                        ret_status = 0; //Let civetweb handle the request
                    }
                } else if (strcmp("HEAD", ri->request_method) == 0) {
                    if (httpSvc->doHead != NULL) {
                        ret_status = httpSvc->doHead(httpSvc->handle, connection, req_uri);
                    } else {
                        ret_status = 0; //Let civetweb handle the request
                    }
                } else if (strcmp("POST", ri->request_method) == 0) {
                    if (httpSvc->doPost != NULL) {
                        int bytes_read = 0;
                        bool no_data = false;
                        char *rcv_buf = NULL;

                        if (ri->content_length > 0) {
                            int content_size = (ri->content_length > INT_MAX ? INT_MAX : (int) ri->content_length);
                            rcv_buf = malloc((size_t) content_size + 1);
                            rcv_buf[content_size] = '\0';
                            bytes_read = mg_read(connection, rcv_buf, (size_t) content_size);
                        } else {
                            no_data = true;
                        }

                        if (bytes_read > 0 || no_data) {
                            ret_status = httpSvc->doPost(httpSvc->handle, connection, rcv_buf, (size_t) bytes_read);
                        } else {
                            mg_send_http_error(connection, 400, "%s", "Bad request");
                            ret_status = 400; //Bad Request, failed to read data
                        }

                        if (rcv_buf != NULL) {
                            free(rcv_buf);
                        }
                    } else {
                        ret_status = 0; //Let civetweb handle the request
                    }

                } else if (strcmp("PUT", ri->request_method) == 0) {
                    if (httpSvc->doPut != NULL) {
                        int bytes_read = 0;
                        bool no_data = false;
                        char *rcv_buf = NULL;

                        if (ri->content_length > 0) {
                            int content_size = (ri->content_length > INT_MAX ? INT_MAX : (int) ri->content_length);
                            rcv_buf = malloc((size_t) content_size + 1);
                            rcv_buf[content_size] = '\0';
                            bytes_read = mg_read(connection, rcv_buf, (size_t) content_size);
                        } else {
                            no_data = true;
                        }

                        if (bytes_read > 0 || no_data) {
                            ret_status = httpSvc->doPut(httpSvc->handle, connection, req_uri, rcv_buf,
                                                        (size_t) bytes_read);
                        } else {
                            mg_send_http_error(connection, 400, "%s", "Bad request");
                            ret_status = 400; //Bad Request, failed to read data
                        }

                        if (rcv_buf != NULL) {
                            free(rcv_buf);
                        }
                    } else {
                        ret_status = 0; //Let civetweb handle the request
                    }
                } else if (strcmp("DELETE", ri->request_method) == 0) {
                    if (httpSvc->doDelete != NULL) {
                        ret_status = httpSvc->doDelete(httpSvc->handle, connection, req_uri);
                    } else {
                        ret_status = 0; //Let civetweb handle the request
                    }
                } else if (strcmp("TRACE", ri->request_method) == 0) {
                    if (httpSvc->doTrace != NULL) {
                        int bytes_read = 0;
                        bool no_data = false;
                        char *rcv_buf = NULL;

                        if (ri->content_length > 0) {
                            int content_size = (ri->content_length > INT_MAX ? INT_MAX : (int) ri->content_length);
                            rcv_buf = malloc((size_t) content_size + 1);
                            rcv_buf[content_size] = '\0';
                            bytes_read = mg_read(connection, rcv_buf, (size_t) content_size);
                        } else {
                            no_data = true;
                        }

                        if (bytes_read > 0 || no_data) {
                            ret_status = httpSvc->doTrace(httpSvc->handle, connection, rcv_buf, (size_t) bytes_read);
                        } else {
                            mg_send_http_error(connection, 400, "%s", "Bad request");
                            ret_status = 400; //Bad Request, failed to read data
                        }

                        if (rcv_buf != NULL) {
                            free(rcv_buf);
                        }
                    } else {
                        ret_status = 0; //Let civetweb handle the request
                    }
                } else if (strcmp("OPTIONS", ri->request_method) == 0) {
                    if (httpSvc->doOptions != NULL) {
                        ret_status = httpSvc->doOptions(httpSvc->handle, connection);
                    } else {
                        ret_status = 0; //Let civetweb handle the request
                    }
                } else if (strcmp("PATCH", ri->request_method) == 0) {
                    if (httpSvc->doPatch != NULL) {
                        int bytes_read = 0;
                        bool no_data = false;
                        char *rcv_buf = NULL;

                        if (ri->content_length > 0) {
                            int content_size = (ri->content_length > INT_MAX ? INT_MAX : (int) ri->content_length);
                            rcv_buf = malloc((size_t) content_size + 1);
                            rcv_buf[content_size] = '\0';
                            bytes_read = mg_read(connection, rcv_buf, (size_t) content_size);
                        } else {
                            no_data = true;
                        }

                        if (bytes_read > 0 || no_data) {
                            ret_status = httpSvc->doPatch(httpSvc->handle, connection, req_uri, rcv_buf,
                                                          (size_t) bytes_read);
                        } else {
                            mg_send_http_error(connection, 400, "%s", "Bad request");
                            ret_status = 400; //Bad Request, failed to read data
                        }

                        if (rcv_buf != NULL) {
                            free(rcv_buf);
                        }
                    } else {
                        ret_status = 0; //Let civetweb handle the request
                    }
                } else {
                    mg_send_http_error(connection, 501, "%s", "Not found");
                    ret_status = 501; //Not implemented...
                }
            } else {
                ret_status = 0; //Not found requested URI, let civetweb handle this situation
            }
        }
    } else {
        mg_send_http_error(connection, 400, "%s", "Bad request");
    }


    return ret_status;
}