Esempio n. 1
0
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" );
}
Esempio n. 2
0
/////////////// 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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
/////////////// 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;
}
Esempio n. 6
0
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;
}