static struct mi_root* mi_reg_reload(struct mi_root* cmd, void* param) { struct mi_root *rpl_tree; int i; int err = 0; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==NULL) return NULL; for(i=0; i<reg_hsize; i++) { lock_get(®_htable[i].lock); if (reg_htable[i].s_list!=NULL) { LM_ERR("Found non NULL s_list\n"); slinkedl_list_destroy(reg_htable[i].s_list); reg_htable[i].s_list = NULL; } reg_htable[i].s_list = slinkedl_init(®_alloc, ®_free); if (reg_htable[i].p_list == NULL) { LM_ERR("oom while allocating list\n"); err = 1; } lock_release(®_htable[i].lock); if (err) goto error; } /* Load registrants into the secondary list */ if(load_reg_info_from_db(1) !=0){ LM_ERR("unable to reload the registrant data\n"); free_mi_tree(rpl_tree); goto error; } /* Swap the lists: secondary will become primary */ for(i=0; i<reg_hsize; i++) { lock_get(®_htable[i].lock); slinkedl_list_destroy(reg_htable[i].p_list); reg_htable[i].p_list = reg_htable[i].s_list; reg_htable[i].s_list = NULL; lock_release(®_htable[i].lock); } return rpl_tree; error: for(i=0; i<reg_hsize; i++) { lock_get(®_htable[i].lock); if (reg_htable[i].s_list) slinkedl_list_destroy(reg_htable[i].s_list); reg_htable[i].s_list = NULL; lock_release(®_htable[i].lock); } return NULL; }
int answer_to_connection (void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { str page = {NULL, 0}; struct MHD_Response *response; int ret; void *async_data = NULL; struct httpd_cb *cb; const char *normalised_url; struct post_request *pr; str_str_t *kv; char *p; int cnt_type = HTTPD_STD_CNT_TYPE; int accept_type = HTTPD_STD_CNT_TYPE; int ret_code = MHD_HTTP_OK; LM_DBG("START *** cls=%p, connection=%p, url=%s, method=%s, " "versio=%s, upload_data[%zu]=%p, *con_cls=%p\n", cls, connection, url, method, version, *upload_data_size, upload_data, *con_cls); pr = *con_cls; if(pr == NULL){ pr = pkg_malloc(sizeof(struct post_request)); if(pr==NULL) { LM_ERR("oom while allocating post_request structure\n"); return MHD_NO; } memset(pr, 0, sizeof(struct post_request)); *con_cls = pr; pr = NULL; } if(strncmp(method, "POST", 4)==0) { if(pr == NULL){ pr = *con_cls; pr->p_list = slinkedl_init(&httpd_alloc, &httpd_free); if (pr->p_list==NULL) { LM_ERR("oom while allocating list\n"); return MHD_NO; } LM_DBG("running MHD_create_post_processor\n"); pr->pp = MHD_create_post_processor(connection, post_buf_size, &post_iterator, pr); if(pr->pp==NULL) { if (*upload_data_size == 0) { /* We need to wait for morte data before * handling the POST request */ return MHD_YES; } LM_DBG("NOT a regular POST :o)\n"); if (pr->content_type==0 && pr->content_len==0) MHD_get_connection_values(connection, MHD_HEADER_KIND, &getConnectionHeader, pr); if (pr->content_type<=0 || pr->content_len<=0) { LM_ERR("got a bogus request\n"); return MHD_NO; } if (*upload_data_size != pr->content_len) { /* For now, we don't support large POST with truncated data */ LM_ERR("got a truncated POST request\n"); return MHD_NO; } LM_DBG("got ContentType [%d] with len [%d]: %.*s\\n", pr->content_type, pr->content_len, (int)*upload_data_size, upload_data); /* Here we save data. */ switch (pr->content_type) { case HTTPD_TEXT_XML_CNT_TYPE: case HTTPD_APPLICATION_JSON_CNT_TYPE: /* Save the entire body as 'body' */ kv = (str_str_t*)slinkedl_append(pr->p_list, sizeof(str_str_t) + 1 + *upload_data_size); p = (char*)(kv + 1); kv->key.len = 1; kv->key.s = p; memcpy(p, "1", 1); p += 1; kv->val.len = *upload_data_size; kv->val.s = p; memcpy(p, upload_data, *upload_data_size); break; default: LM_ERR("Unhandled data for ContentType [%d]\n", pr->content_type); return MHD_NO; } /* Mark the fact that we consumed all data */ *upload_data_size = 0; return MHD_YES; } LM_DBG("pr=[%p] pp=[%p] p_list=[%p]\n", pr, pr->pp, pr->p_list); return MHD_YES; } else { if (pr->pp==NULL) { if (*upload_data_size == 0) { if (pr->content_type==HTTPD_TEXT_XML_CNT_TYPE) cnt_type = HTTPD_TEXT_XML_CNT_TYPE; if (pr->content_type==HTTPD_APPLICATION_JSON_CNT_TYPE) cnt_type = HTTPD_APPLICATION_JSON_CNT_TYPE; *con_cls = pr->p_list; cb = get_httpd_cb(url); if (cb) { normalised_url = &url[cb->http_root->len+1]; LM_DBG("normalised_url=[%s]\n", normalised_url); ret_code = cb->callback(cls, (void*)connection, normalised_url, method, version, upload_data, upload_data_size, con_cls, &buffer, &page); } else { page = MI_HTTP_U_URL; ret_code = MHD_HTTP_BAD_REQUEST; } /* slinkedl_traverse(pr->p_list, &httpd_print_data, NULL, NULL); */ slinkedl_list_destroy(*con_cls); pkg_free(pr); *con_cls = pr = NULL; goto send_response; } LM_DBG("NOT a regular POST :o)\n"); if (pr->content_type==0 && pr->content_len==0) MHD_get_connection_values(connection, MHD_HEADER_KIND, &getConnectionHeader, pr); if (pr->content_type<=0 || pr->content_len<=0) { LM_ERR("got a bogus request\n"); return MHD_NO; } if (*upload_data_size != pr->content_len) { /* For now, we don't support large POST with truncated data */ LM_ERR("got a truncated POST request\n"); return MHD_NO; } LM_DBG("got ContentType [%d] with len [%d]: %.*s\\n", pr->content_type, pr->content_len, (int)*upload_data_size, upload_data); /* Here we save data. */ switch (pr->content_type) { case HTTPD_TEXT_XML_CNT_TYPE: case HTTPD_APPLICATION_JSON_CNT_TYPE: /* Save the entire body as 'body' */ kv = (str_str_t*)slinkedl_append(pr->p_list, sizeof(str_str_t) + 1 + *upload_data_size); p = (char*)(kv + 1); kv->key.len = 1; kv->key.s = p; memcpy(p, "1", 1); p += 1; kv->val.len = *upload_data_size; kv->val.s = p; memcpy(p, upload_data, *upload_data_size); break; default: LM_ERR("Unhandled data for ContentType [%d]\n", pr->content_type); return MHD_NO; } /* Mark the fact that we consumed all data */ *upload_data_size = 0; return MHD_YES; } LM_DBG("running MHD_post_process: " "pp=%p status=%d upload_data_size=%zu\n", pr->pp, pr->status, *upload_data_size); if (pr->status<0) { slinkedl_list_destroy(pr->p_list); pr->p_list = NULL; /* FIXME: * It might be better to reply with an error * instead of resetting the connection via MHD_NO */ return MHD_NO; } ret =MHD_post_process(pr->pp, upload_data, *upload_data_size); LM_DBG("ret=%d upload_data_size=%zu\n", ret, *upload_data_size); if(*upload_data_size != 0) { *upload_data_size = 0; return MHD_YES; } LM_DBG("running MHD_destroy_post_processor: " "pr=[%p] pp=[%p] p_list=[%p]\n", pr, pr->pp, pr->p_list); MHD_destroy_post_processor(pr->pp); LM_DBG("done MHD_destroy_post_processor\n"); /* slinkedl_traverse(pr->p_list, &httpd_print_data, NULL, NULL); */ *con_cls = pr->p_list; cb = get_httpd_cb(url); if (cb) { normalised_url = &url[cb->http_root->len+1]; LM_DBG("normalised_url=[%s]\n", normalised_url); ret_code = cb->callback(cls, (void*)connection, normalised_url, method, version, upload_data, upload_data_size, con_cls, &buffer, &page); } else { page = MI_HTTP_U_URL; ret_code = MHD_HTTP_BAD_REQUEST; } /* slinkedl_traverse(pr->p_list, &httpd_print_data, NULL, NULL); */ slinkedl_list_destroy(*con_cls); pkg_free(pr); *con_cls = pr = NULL; } }else if(strncmp(method, "GET", 3)==0) { pr = *con_cls; MHD_get_connection_values(connection, MHD_HEADER_KIND, &getConnectionHeader, pr); accept_type = pr->accept_type; pkg_free(pr); *con_cls = pr = NULL; LM_DBG("accept_type=[%d]\n", accept_type); cb = get_httpd_cb(url); if (cb) { normalised_url = &url[cb->http_root->len+1]; LM_DBG("normalised_url=[%s]\n", normalised_url); ret_code = cb->callback(cls, (void*)connection, normalised_url, method, version, upload_data, upload_data_size, con_cls, &buffer, &page); } else { page = MI_HTTP_U_URL; ret_code = MHD_HTTP_BAD_REQUEST; } }else{ page = MI_HTTP_U_METHOD; ret_code = MHD_HTTP_METHOD_NOT_ACCEPTABLE; } send_response: if (page.s) { LM_DBG("MHD_create_response_from_data [%p:%d]\n", page.s, page.len); response = MHD_create_response_from_data(page.len, (void*)page.s, 0, 1); } else { LM_DBG("MHD_create_response_from_callback\n"); response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, buffer.len, cb->flush_data_callback, (void*)async_data, NULL); } if (cnt_type==HTTPD_TEXT_XML_CNT_TYPE || accept_type==HTTPD_TEXT_XML_CNT_TYPE) MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, "text/xml; charset=utf-8"); if (cnt_type==HTTPD_APPLICATION_JSON_CNT_TYPE || accept_type==HTTPD_APPLICATION_JSON_CNT_TYPE) MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, "application/json"); ret = MHD_queue_response (connection, ret_code, response); MHD_destroy_response (response); return ret; }