⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webserver.c

📁 linux下简单对象应用协议的开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
        {	  soap_print_fault(tsoap, stderr);          fprintf(stderr, "SSL request failed, continue with next call...\n");          soap_end(tsoap);          soap_done(tsoap);          free(tsoap);          continue;        }#endif        tsoap->user = (void*)req;        THREAD_CREATE(&tid, (void*(*)(void*))process_request, (void*)tsoap);      }      else      {#ifdef WITH_OPENSSL        if (secure && soap_ssl_accept(soap))        {	  soap_print_fault(soap, stderr);          fprintf(stderr, "SSL request failed, continue with next call...\n");          soap_end(soap);          continue;        }#endif        if (soap_serve(soap))        {	  fprintf(stderr, "Request #%d completed with failure %d\n", req, soap->error);          soap_print_fault(soap, stderr);        }        soap_end(soap);        if (options[OPTION_v].selected)          fprintf(stderr, "Request #%d completed\n", req);      }    }  }  if (poolsize > 0)  {    int job;    for (job = 0; job < poolsize; job++)    {      while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM)        sleep(1);    }    for (job = 0; job < poolsize; job++)    {      fprintf(stderr, "Waiting for thread %d to terminate... ", job);      THREAD_JOIN(tids[job]);      fprintf(stderr, "terminated\n");      soap_done(soap_thr[job]);      free(soap_thr[job]);    }  }}/******************************************************************************\ * *	Process dispatcher *\******************************************************************************/void *process_request(void *soap){  struct soap *tsoap = (struct soap*)soap;  THREAD_DETACH(THREAD_ID);  if (soap_serve(tsoap))  {    fprintf(stderr, "Thread %d completed with failure %d\n", (int)tsoap->user, tsoap->error);    soap_print_fault(tsoap, stderr);  }  else if (options[OPTION_v].selected)    fprintf(stderr, "Thread %d completed\n", (int)tsoap->user);  /* soap_destroy((struct soap*)soap); */ /* cleanup class instances (but this is a C app) */  soap_end(tsoap);  soap_done(tsoap);  free(soap);  return NULL;}/******************************************************************************\ * *	Thread pool (enabled with option -o<num>) *\******************************************************************************/void *process_queue(void *soap){  struct soap *tsoap = (struct soap*)soap;  for (;;)  {    tsoap->socket = dequeue();    if (!soap_valid_socket(tsoap->socket))    { if (options[OPTION_v].selected)        fprintf(stderr, "Thread %d terminating\n", (int)tsoap->user);      break;    }#ifdef WITH_OPENSSL    if (secure && soap_ssl_accept(tsoap))    {      soap_print_fault(tsoap, stderr);      fprintf(stderr, "SSL request failed, continue with next call...\n");      soap_end(tsoap);      soap_done(tsoap);      continue;    }#endif    if (options[OPTION_v].selected)      fprintf(stderr, "Thread %d accepted a request\n", (int)tsoap->user);    if (soap_serve(tsoap))    {      fprintf(stderr, "Thread %d finished serving request with failure %d\n", (int)tsoap->user, tsoap->error);      soap_print_fault(tsoap, stderr);    }    else if (options[OPTION_v].selected)      fprintf(stderr, "Thread %d finished serving request\n", (int)tsoap->user);    soap_destroy(tsoap);    soap_end(tsoap);  }  return NULL;}int enqueue(SOAP_SOCKET sock){  int status = SOAP_OK;  int next;  int ret;  if ((ret = MUTEX_LOCK(queue_cs)))    fprintf(stderr, "MUTEX_LOCK error %d\n", ret);  next = (tail + 1) % MAX_QUEUE;  if (head == next)  {    /* don't block on full queue, return SOAP_EOM */    status = SOAP_EOM;  }  else  {    queue[tail] = sock;    tail = next;    if (options[OPTION_v].selected)      fprintf(stderr, "enqueue(%d)\n", sock);    if ((ret = COND_SIGNAL(queue_cv)))      fprintf(stderr, "COND_SIGNAL error %d\n", ret);  }  if ((ret = MUTEX_UNLOCK(queue_cs)))    fprintf(stderr, "MUTEX_UNLOCK error %d\n", ret);  return status;}SOAP_SOCKET dequeue(){  SOAP_SOCKET sock;  int ret;  if ((ret = MUTEX_LOCK(queue_cs)))    fprintf(stderr, "MUTEX_LOCK error %d\n", ret);  while (head == tail)    if ((ret = COND_WAIT(queue_cv, queue_cs)))      fprintf(stderr, "COND_WAIT error %d\n", ret);  sock = queue[head];    head = (head + 1) % MAX_QUEUE;  if (options[OPTION_v].selected)    fprintf(stderr, "dequeue(%d)\n", sock);  if ((ret = MUTEX_UNLOCK(queue_cs)))    fprintf(stderr, "MUTEX_UNLOCK error %d\n", ret);  return sock;}/******************************************************************************\ * *	SOAP/XML handling: calculator example *\******************************************************************************/int ns__add(struct soap *soap, double a, double b, double *c){  *c = a + b;  return SOAP_OK;}int ns__sub(struct soap *soap, double a, double b, double *c){  *c = a - b;  return SOAP_OK;}int ns__mul(struct soap *soap, double a, double b, double *c){  *c = a * b;  return SOAP_OK;}int ns__div(struct soap *soap, double a, double b, double *c){  *c = a / b;  return SOAP_OK;}/******************************************************************************\ * *	Server dummy methods to avoid link errors *\******************************************************************************/int ns__addResponse_(struct soap *soap, double a){  return SOAP_NO_METHOD; /* we don't use this: we use soap_send_ns__addResponse instead */}int ns__subResponse_(struct soap *soap, double a){  return SOAP_NO_METHOD; /* we don't use this: we use soap_send_ns__subResponse instead */}int ns__mulResponse_(struct soap *soap, double a){  return SOAP_NO_METHOD; /* we don't use this: we use soap_send_ns__mulResponse instead */}int ns__divResponse_(struct soap *soap, double a){  return SOAP_NO_METHOD; /* we don't use this: we use soap_send_ns__divResponse instead */}/******************************************************************************\ * *	HTTP GET handler for plugin *\******************************************************************************/int http_get_handler(struct soap *soap){  /* gSOAP >=2.5 soap_response() will do this automatically for us, when sending SOAP_HTML or SOAP_FILE:  if ((soap->omode & SOAP_IO) != SOAP_IO_CHUNK)    soap_set_omode(soap, SOAP_IO_STORE); */ /* if not chunking we MUST buffer entire content when returning HTML pages to determine content length */#ifdef WITH_ZLIB  if (options[OPTION_z].selected && soap->zlib_out == SOAP_ZLIB_GZIP) /* client accepts gzip */  { soap_set_omode(soap, SOAP_ENC_ZLIB); /* so we can compress content (gzip) */    soap->z_level = 9; /* best compression */  }  else    soap_clr_omode(soap, SOAP_ENC_ZLIB); /* so we can compress content (gzip) */#endif  /* Use soap->path (from request URL) to determine request: */  if (options[OPTION_v].selected)    fprintf(stderr, "HTTP GET Request: %s\n", soap->endpoint);  /* Note: soap->path always starts with '/' */  if (strchr(soap->path + 1, '/') || strchr(soap->path + 1, '\\'))	/* we don't like snooping in dirs */    return 403; /* HTTP forbidden */  if (!soap_tag_cmp(soap->path, "*.html"))    return copy_file(soap, soap->path + 1, "text/html");  if (!soap_tag_cmp(soap->path, "*.xml")   || !soap_tag_cmp(soap->path, "*.xsd")   || !soap_tag_cmp(soap->path, "*.wsdl"))    return copy_file(soap, soap->path + 1, "text/xml");  if (!soap_tag_cmp(soap->path, "*.jpg"))    return copy_file(soap, soap->path + 1, "image/jpeg");  if (!soap_tag_cmp(soap->path, "*.gif"))    return copy_file(soap, soap->path + 1, "image/gif");  if (!soap_tag_cmp(soap->path, "*.png"))    return copy_file(soap, soap->path + 1, "image/png");  if (!soap_tag_cmp(soap->path, "*.ico"))    return copy_file(soap, soap->path + 1, "image/ico");  if (!strncmp(soap->path, "/calc?", 6))    return calcget(soap);  if (!strncmp(soap->path, "/genivia", 8))  { strcpy(soap->endpoint, "http://genivia.com"); /* redirect */    strcat(soap->endpoint, soap->path + 8);    return 307; /* Temporary Redirect */  }  /* Check requestor's authentication: */  if (check_authentication(soap))    return 401; /* HTTP not authorized */  /* Return Web server status */  if (soap->path[1] == '\0' || soap->path[1] == '?')    return info(soap);  return 404; /* HTTP not found */}int check_authentication(struct soap *soap){ if (soap->userid && soap->passwd)  { if (!strcmp(soap->userid, AUTH_USERID) && !strcmp(soap->passwd, AUTH_PASSWD))      return SOAP_OK;  }#ifdef HTTPDA_H  else if (soap->authrealm && soap->userid)  { if (!strcmp(soap->authrealm, AUTH_REALM) && !strcmp(soap->userid, AUTH_USERID))      if (!http_da_verify_get(soap, AUTH_PASSWD))        return SOAP_OK;  }#endif  soap->authrealm = AUTH_REALM;  return 401;}/******************************************************************************\ * *	HTTP POST application/x-www-form-urlencoded handler for plugin *\******************************************************************************/int http_form_handler(struct soap *soap){#ifdef WITH_ZLIB  if (options[OPTION_z].selected && soap->zlib_out == SOAP_ZLIB_GZIP) /* client accepts gzip */    soap_set_omode(soap, SOAP_ENC_ZLIB); /* so we can compress content (gzip) */  soap->z_level = 9; /* best compression */#endif  /* Use soap->path (from request URL) to determine request: */  if (options[OPTION_v].selected)    fprintf(stderr, "HTTP POST Request: %s\n", soap->endpoint);  /* Note: soap->path always starts with '/' */  if (!strcmp(soap->path, "/calc"))    return calcpost(soap);  return 404; /* HTTP not found */}/******************************************************************************\ * *	Copy static page *\******************************************************************************/int copy_file(struct soap *soap, const char *name, const char *type){ FILE *fd;  size_t r;  fd = fopen(name, "rb"); /* open file to copy */  if (!fd)    return 404; /* return HTTP not found */  soap->http_content = type;  if (soap_response(soap, SOAP_FILE)) /* OK HTTP response header */  { soap_end_send(soap);    fclose(fd);    return soap->error;  }  for (;;)  { r = fread(soap->tmpbuf, 1, sizeof(soap->tmpbuf), fd);    if (!r)      break;    if (soap_send_raw(soap, soap->tmpbuf, r))    { soap_end_send(soap);      fclose(fd);      return soap->error;    }  }  fclose(fd);  return soap_end_send(soap);}/******************************************************************************\ * *	Example dynamic HTTP GET application/x-www-form-urlencoded calculator *\******************************************************************************/int calcget(struct soap *soap){ int o = 0, a = 0, b = 0, val;  char buf[256];  char *s = query(soap); /* get argument string from URL ?query string */  while (s)  { char *key = query_key(soap, &s); /* decode next query string key */    char *val = query_val(soap, &s); /* decode next query string value (if any) */    if (key && val)    { if (!strcmp(key, "o"))        o = val[0];      else if (!strcmp(key, "a"))        a = strtol(val, NULL, 10);      else if (!strcmp(key, "b"))        b = strtol(val, NULL, 10);    }  }  switch (o)  { case 'a':      val = a + b;      break;    case 's':      val = a - b;      break;    case 'm':      val = a * b;      break;    case 'd':      val = a / b;      break;    default:      return soap_sender_fault(soap, "Unknown operation", NULL);  }  soap_response(soap, SOAP_HTML);  sprintf(buf, "<html>value=%d</html>", val);  soap_send(soap, buf);  soap_end_send(soap);  return SOAP_OK;}/******************************************************************************\ * *	Example dynamic HTTP POST application/x-www-form-urlencoded calculator *\******************************************************************************/int calcpost(struct soap *soap){ int o = 0, a = 0, b = 0, val;  char buf[256];  char *s = form(soap); /* get form data from body */  while (s)  { char *key = query_key(soap, &s); /* decode next key */    char *val = query_val(soap, &s); /* decode next value (if any) */    if (key && val)    { if (!strcmp(key, "o"))        o = val[0];      else if (!strcmp(key, "a"))        a = strtol(val, NULL, 10);      else if (!strcmp(key, "b"))        b = strtol(val, NULL, 10);    }  }  switch (o)  { case 'a':      val = a + b;      break;    case 's':      val = a - b;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -