📄 webserver.c
字号:
{ 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 + -