static nxweb_result delete_batch_on_request( nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_response* resp) { nxweb_set_response_content_type(resp, "text/plain"); nxweb_parse_request_parameters( req, 0 ); const char *name_space = nx_simple_map_get_nocase( req->parameters, "namespace" ); const char *fname_raw = nx_simple_map_get_nocase( req->parameters, "names" ); if (!fname_raw) { nxweb_response_printf(resp, "url error\nexample: http://127.0.0.1:8055/deletefiles?names=f1[:f2][&namespace=np]\n"); return NXWEB_ERROR; } KCSTR kc_fnames[400] = {0}; char fnames_with_space[400][1024] = {0}; char *pC = (char *)fname_raw; int fname_cnt = 0; int fname_len = 0; do{ char *pT = strstr( pC, ":" ); if (pT){ fname_len = pT - pC; pT++; } else { fname_len = strlen( pC ); } if (fname_len == 0){pC = pT; continue;} if (name_space) {strcpy(fnames_with_space[fname_cnt], name_space);} strcat(fnames_with_space[fname_cnt], ":/" ); strncat(fnames_with_space[fname_cnt], pC, fname_len); kc_fnames[fname_cnt].buf = (char *)(fnames_with_space + fname_cnt); kc_fnames[fname_cnt].size = strlen(fnames_with_space[fname_cnt]); pC = pT; fname_cnt++; } while(pC); int i=0; for(; i<fname_cnt; ++i) { char pBuf[1024] = {0}; memcpy( pBuf, kc_fnames[i].buf, kc_fnames[i].size ); } kcdbremovebulk( g_kcdb, kc_fnames, fname_cnt, 0 ); nxweb_response_printf( resp, "OK\n" ); }
/////////////// status ///////////////////// static nxweb_result status_on_request(nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_response* resp) { nxweb_set_response_content_type(resp, "text/plain"); char *status = kcdbstatus( g_kcdb ); size_t len = 2*strlen(status); char *buf = malloc(len); memset(buf, 0, len); int i=0, j=0; for (i=0; i<strlen(status); i++) { if (status[i] == '\t') { strcat(buf, ": "); j+=2; } else { buf[j] = status[i]; j++; } } nxweb_response_printf( resp, "%s\n", buf ); kcfree( status ); status = NULL; free(buf); return NXWEB_OK; }
static nxweb_result delete_on_request( nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_response* resp) { nxweb_set_response_content_type(resp, "text/plain"); nxweb_parse_request_parameters(req, 0); const char *name_space = nx_simple_map_get_nocase(req->parameters, "namespace"); char * url = malloc(strlen(req->path_info)+1); if (!url) { nxweb_send_http_error(resp, 500, "Please retry"); resp->keep_alive=0; return NXWEB_ERROR; } strcpy(url, req->path_info); url[strlen(req->path_info)] = '\0'; nxweb_url_decode(url, 0); char *fname = url, *temp; while (temp = strstr(fname, "/")) {fname = temp + 1;} char *strip_args = strstr(fname, "?"); int fname_len = strip_args?strip_args-fname:strlen(fname); char fname_with_space[1024]= {0}; if (strlen(url) > sizeof(fname_with_space)-1) { nxweb_send_http_error(resp, 414, "Request URI Too Long"); resp->keep_alive=0; free(url); return NXWEB_MISS; } if (name_space) {sprintf( fname_with_space, "%s:/", name_space);} else {strcpy(fname_with_space, ":/");} strncat(fname_with_space, fname, fname_len); kcdbremove(g_kcdb, fname_with_space, strlen( fname_with_space)); nxweb_response_printf(resp, "OK\n"); free(url); return NXWEB_OK; }
static nxweb_result list_on_request(nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_response* resp) { nxweb_set_response_content_type(resp, "text/plain"); const char *name_space = nx_simple_map_get_nocase( req->parameters, "namespace" ); const char *prefix = nx_simple_map_get_nocase( req->parameters, "prefix" ); char kc_prefix[1024] = {0}; if( name_space ){ strncpy( kc_prefix, name_space, sizeof( kc_prefix )-3 ); strcat( kc_prefix, ":/" ); if (prefix){ strncat(kc_prefix, prefix, sizeof(kc_prefix)-strlen(kc_prefix)-1); } } printf("list prefix:%s\n", kc_prefix ); char *fnames[MAX_COUNT_PER_LIST] = {0}; int cnt = kcdbmatchprefix (g_kcdb, kc_prefix, fnames, MAX_COUNT_PER_LIST ); int i = 0; while( i< cnt ){ nxweb_response_printf( resp, "%s\n", fnames[i] ); kcfree( fnames[i] ); fnames[i] = NULL; i++; } return NXWEB_OK; }
/////////////// clean ////////////////////// static nxweb_result clean_on_request( nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_response* resp) { if (strlen(req->path_info) <= 1 || strlen(req->path_info) >= 4 ) { nxweb_send_http_error(resp, 403, "NUMBER error!\nExample:\nhttp://host:port/clean/24"); resp->keep_alive=0; return NXWEB_ERROR; } char tmp[8] = {0}; strcpy(tmp, (req->path_info) +1); int interval_hour = atoi(tmp); if (interval_hour < 0 || interval_hour > 99) { nxweb_send_http_error(resp, 403, "NUMBER error!\nExample:\nhttp://host:port/clean/24"); resp->keep_alive=0; return NXWEB_ERROR; } WipeData(interval_hour); nxweb_response_printf(resp, "OK"); return NXWEB_OK; }
static nxweb_result python_on_request(nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_response* resp) { nxb_buffer* nxb=req->nxb; nxweb_handler* handler=conn->handler; const char* request_uri=req->uri; char* query_string=strchr(request_uri, '?'); int ulen=query_string? (query_string-request_uri) : strlen(request_uri); if (query_string) query_string++; int pfxlen=req->path_info? (req->path_info - req->uri) : 0; int plen=ulen-pfxlen; const char* path_info=request_uri+pfxlen; if (handler->uri && *handler->uri) { pfxlen=strlen(handler->uri); ulen=pfxlen+plen; char* u=nxb_alloc_obj(nxb, ulen+1); memcpy(u, handler->uri, pfxlen); memcpy(u+pfxlen, path_info, plen); u[ulen]='\0'; request_uri=u; path_info=request_uri+pfxlen; } const char* host_port=req->host? strchr(req->host, ':') : 0; int content_fd=0; if (req->content_length) { nxd_fwbuffer* fwb=nxweb_get_request_data(req, PYTHON_HANDLER_KEY).ptr; if (fwb) { if (fwb->error || fwb->size > fwb->max_size) { nxweb_send_http_error(resp, 413, "Request Entity Too Large"); // most likely cause return NXWEB_ERROR; } else if (req->content_received!=fwb->size) { nxweb_log_error("content_received does not match upload stored size for %s", req->uri); nxweb_send_http_error(resp, 500, "Internal Server Error"); return NXWEB_ERROR; } else { content_fd=fwb->fd; if (lseek(content_fd, 0, SEEK_SET)==-1) { nxweb_log_error("can't lseek() temp upload file for %s", req->uri); nxweb_send_http_error(resp, 500, "Internal Server Error"); return NXWEB_ERROR; } } } } nxweb_log_debug("invoke python"); PyGILState_STATE gstate=PyGILState_Ensure(); PyObject* py_func_args=PyTuple_New(1); PyObject* py_environ=PyDict_New(); assert(PyDict_Check(py_environ)); dict_set(py_environ, "SERVER_NAME", PyString_FromStringAndSize(req->host, host_port? (host_port-req->host) : strlen(req->host))); dict_set(py_environ, "SERVER_PORT", PyString_FromString(host_port? host_port+1 : "")); dict_set(py_environ, "SERVER_PROTOCOL", PyString_FromString(req->http11? "HTTP/1.1" : "HTTP/1.0")); dict_set(py_environ, "SERVER_SOFTWARE", PyString_FromString(PACKAGE_STRING)); dict_set(py_environ, "GATEWAY_INTERFACE", PyString_FromString("CGI/1.1")); dict_set(py_environ, "REQUEST_METHOD", PyString_FromString(req->method)); dict_set(py_environ, "REQUEST_URI", PyString_FromStringAndSize(request_uri, ulen)); dict_set(py_environ, "SCRIPT_NAME", PyString_FromStringAndSize(request_uri, pfxlen)); dict_set(py_environ, "PATH_INFO", PyString_FromStringAndSize(path_info, plen)); dict_set(py_environ, "QUERY_STRING", PyString_FromString(query_string? query_string : "")); dict_set(py_environ, "REMOTE_ADDR", PyString_FromString(conn->remote_addr)); dict_set(py_environ, "CONTENT_TYPE", PyString_FromString(req->content_type? req->content_type : "")); dict_set(py_environ, "CONTENT_LENGTH", PyInt_FromLong(req->content_received)); if (req->cookie) dict_set(py_environ, "HTTP_COOKIE", PyString_FromString(req->cookie)); if (req->host) dict_set(py_environ, "HTTP_HOST", PyString_FromString(req->host)); if (req->user_agent) dict_set(py_environ, "HTTP_USER_AGENT", PyString_FromString(req->user_agent)); if (req->if_modified_since) { struct tm tm; gmtime_r(&req->if_modified_since, &tm); char ims[32]; nxweb_format_http_time(ims, &tm); dict_set(py_environ, "HTTP_IF_MODIFIED_SINCE", PyString_FromString(ims)); } if (req->headers) { // write added headers // encode http headers into CGI variables; see 4.1.18 in https://tools.ietf.org/html/rfc3875 char hname[256]; memcpy(hname, "HTTP_", 5); char* h=hname+5; nx_simple_map_entry* itr; for (itr=nx_simple_map_itr_begin(req->headers); itr; itr=nx_simple_map_itr_next(itr)) { nx_strtoupper(h, itr->name); char* p; for (p=h; *p; p++) { if (*p=='-') *p='_'; } dict_set(py_environ, hname, PyString_FromString(itr->value)); } } dict_set(py_environ, "wsgi.url_scheme", PyString_FromString(conn->secure? "https" : "http")); if (req->content_length) { if (content_fd) { dict_set(py_environ, "nxweb.req.content_fd", PyInt_FromLong(content_fd)); } else { dict_set(py_environ, "nxweb.req.content", PyByteArray_FromStringAndSize(req->content? req->content : "", req->content_received)); } } if (req->if_modified_since) dict_set(py_environ, "nxweb.req.if_modified_since", PyLong_FromLong(req->if_modified_since)); dict_set(py_environ, "nxweb.req.uid", PyLong_FromLongLong(req->uid)); if (req->parent_req) { nxweb_http_request* preq=req->parent_req; while (preq->parent_req) preq=preq->parent_req; // find root request if (preq->uid) { dict_set(py_environ, "nxweb.req.root_uid", PyLong_FromLongLong(preq->uid)); } } // call python PyTuple_SetItem(py_func_args, 0, py_environ); PyObject* py_result=PyObject_CallObject(py_nxweb_on_request_func, py_func_args); Py_DECREF(py_func_args); if (py_result && PyTuple_Check(py_result) && PyTuple_Size(py_result)==3) { PyObject* py_status=PyTuple_GET_ITEM(py_result, 0); PyObject* py_headers=PyTuple_GET_ITEM(py_result, 1); PyObject* py_body=PyTuple_GET_ITEM(py_result, 2); if (py_status && PyString_Check(py_status)) { const char* status_string=PyString_AS_STRING(py_status); int status_code=0; const char* p=status_string; while (*p && *p>='0' && *p<='9') { status_code=status_code*10+(*p-'0'); p++; } while (*p && *p==' ') p++; if (status_code>=200 && status_code<600 && *p) { resp->status_code=status_code; resp->status=nxb_copy_str(nxb, p); } } if (py_headers && PyList_Check(py_headers)) { const int size=PyList_Size(py_headers); int i; for (i=0; i<size; i++) { PyObject* py_header_tuple=PyList_GET_ITEM(py_headers, i); if (py_header_tuple && PyTuple_Check(py_header_tuple) && PyTuple_Size(py_header_tuple)==2) { PyObject* py_name=PyTuple_GET_ITEM(py_header_tuple, 0); PyObject* py_value=PyTuple_GET_ITEM(py_header_tuple, 1); if (py_name && PyString_Check(py_name) && py_value && PyString_Check(py_value)) { nxweb_add_response_header_safe(resp, PyString_AS_STRING(py_name), PyString_AS_STRING(py_value)); } } } } if ((!resp->status_code || resp->status_code==200) && !resp->content_type) resp->content_type="text/html"; char* rcontent=0; nxe_ssize_t rsize=0; if (PyByteArray_Check(py_body)) { rcontent=PyByteArray_AS_STRING(py_body); rsize=PyByteArray_Size(py_body); } else if (PyString_Check(py_body)) { rcontent=PyString_AS_STRING(py_body); rsize=PyString_Size(py_body); } if (rcontent && rsize>0) nxweb_response_append_data(resp, rcontent, rsize); } else if (py_result && PyString_Check(py_result)) { resp->status_code=500; resp->status="Internal Server Error"; resp->content_type="text/html"; nxweb_log_error("python call failed: %s", PyString_AS_STRING(py_result)); nxweb_response_printf(resp, "python call failed: %H", PyString_AS_STRING(py_result)); } else { PyErr_Print(); nxweb_log_error("python call failed"); nxweb_response_printf(resp, "python call failed"); } Py_XDECREF(py_result); // Release the thread. No Python API allowed beyond this point. PyGILState_Release(gstate); nxweb_log_debug("invoke python complete"); return NXWEB_OK; }