~ifolder-dev/simias/trunk-packaging

« back to all changes in this revision

Viewing changes to tools/gsoap/gsoap-linux-2.7/samples/webserver/.svn/text-base/webserver.c.svn-base

  • Committer: Jorge O. Castro
  • Date: 2007-12-03 06:56:46 UTC
  • Revision ID: jorge@ubuntu.com-20071203065646-mupcnjcwgm5mnhyt
* Remove a bunch of .svn directories we no longer need.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 
3
 
webserver.c
4
 
 
5
 
Example stand-alone gSOAP Web server based on the gSOAP HTTP GET plugin.
6
 
This is a small but fully functional (embedded) Web server for serving
7
 
static and dynamic pages and SOAP/XML responses.
8
 
 
9
 
--------------------------------------------------------------------------------
10
 
gSOAP XML Web services tools
11
 
Copyright (C) 2001-2004, Robert van Engelen, Genivia, Inc. All Rights Reserved.
12
 
This software is released under one of the following two licenses:
13
 
GPL or Genivia's license for commercial use.
14
 
--------------------------------------------------------------------------------
15
 
GPL license.
16
 
 
17
 
This program is free software; you can redistribute it and/or modify it under
18
 
the terms of the GNU General Public License as published by the Free Software
19
 
Foundation; either version 2 of the License, or (at your option) any later
20
 
version.
21
 
 
22
 
This program is distributed in the hope that it will be useful, but WITHOUT ANY
23
 
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
24
 
PARTICULAR PURPOSE. See the GNU General Public License for more details.
25
 
 
26
 
You should have received a copy of the GNU General Public License along with
27
 
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
28
 
Place, Suite 330, Boston, MA 02111-1307 USA
29
 
 
30
 
Author contact information:
31
 
engelen@genivia.com / engelen@acm.org
32
 
--------------------------------------------------------------------------------
33
 
A commercial use license is available from Genivia, Inc., contact@genivia.com
34
 
--------------------------------------------------------------------------------
35
 
 
36
 
        The Web server handles HTTP GET requests to serve pages and HTTP POST
37
 
        reguests to handle SOAP/XML messages. This example only implements
38
 
        a simple calculator XML Web service for demonstration purposes (the
39
 
        service responds with SOAP/XML).
40
 
 
41
 
        This application requires Zlib and Pthreads (you can replace Pthreads
42
 
        with another thread library, but you need to study the OpenSSL thread
43
 
        changes in the OpenSSL documentation).
44
 
 
45
 
        On Unix/Linux, please enable SIGPIPE handling, see main function below.
46
 
        SIGPIPE handling will avoid your server from termination when sockets
47
 
        are disconnected by clients before the transaction was completed
48
 
        (aka broken pipe).
49
 
 
50
 
        Compile without OpenSSL:
51
 
        soapcpp2 -c -n -popt opt.h
52
 
        soapcpp2 -c webserver.h
53
 
        Customize your COOKIE_DOMAIN in this file
54
 
        gcc -DWITH_COOKIES -DWITH_ZLIB -o webserver webserver.c options.c plugin/httpget.c plugin/httpform.c plugin/logging.c stdsoap2.c soapC.c soapClient.c soapServer.c -lpthread -lz
55
 
 
56
 
        Compile with OpenSSL:
57
 
        soapcpp2 -c -n -popt opt.h
58
 
        soapcpp2 -c webserver.h
59
 
        Customize your COOKIE_DOMAIN in this file
60
 
        gcc -DWITH_OPENSSL -DWITH_COOKIES -DWITH_ZLIB -o webserver webserver.c options.c plugin/httpget.c plugin/httpform.c plugin/logging.c stdsoap2.c soapC.c soapClient.c soapServer.c -lpthread -lz -lssl -lcrypto
61
 
 
62
 
        Use (HTTP GET):
63
 
        Compile the web server as explained above
64
 
        Start the web server on an even numbered port (e.g. 8080):
65
 
        > webserver 8080 &
66
 
        Start a web browser and open a (localhost) location:
67
 
        http://127.0.0.1:8080
68
 
        and type userid 'admin' and passwd 'guest' to gain access
69
 
        Open the location:
70
 
        http://127.0.0.1:8080/calc.html
71
 
        then enter an expression
72
 
        Open the locations:
73
 
        http://127.0.0.1:8080/test.html
74
 
        http://127.0.0.1:8081/webserver.wsdl
75
 
 
76
 
        Use (HTTPS GET):
77
 
        Create the SSL certificate
78
 
        Compile the web server with OpenSSL as explained above
79
 
        Start the web server on an odd numbered port (e.g. 8081)
80
 
        > webserver 8081 &
81
 
        Actually, you can start two servers, one on 8080 and a secure one on
82
 
        8081
83
 
        Start a web browser and open a (localhost) location:
84
 
        https://127.0.0.1:8081
85
 
        and type userid 'admin' and passwd 'guest' to gain access
86
 
        Open the location:
87
 
        https://127.0.0.1:8081/calc.html
88
 
        and enter an expression
89
 
        Open the locations:
90
 
        https://127.0.0.1:8081/test.html
91
 
        https://127.0.0.1:8081/webserver.wsdl
92
 
 
93
 
        Use (HTTP POST):
94
 
        Serves SOAP/XML calculation requests
95
 
 
96
 
        Command-line options:
97
 
        -z              enables compression
98
 
        -c              enables chunking
99
 
        -k              enables keep-alive
100
 
        -i              enables non-threaded iterative server
101
 
        -v              enables verbose mode
102
 
        -o<num>         pool of <num> threads (cannot be used with option -i)
103
 
                        Note: interactive chunking/keep-alive settings cannot be
104
 
                        changed, unless the number of threads is interactively
105
 
                        changed to restart the pool
106
 
                        Note: <num>=0 specifies unlimited threads
107
 
        -t<num>         sets I/O timeout value (seconds)
108
 
        -s<num>         sets server timeout value (seconds)
109
 
        -d<host>        sets cookie domain
110
 
        -p<path>        sets cookie path
111
 
        -l[none inbound outbound both]
112
 
                        enables logging
113
 
 
114
 
        Requires options.h and options.c for command line option parsing and
115
 
        for parsing interactive Web page options settings. The
116
 
        default_options[] array defines application options, short-hands,
117
 
        selection lists, and default values. See options.h for more details.
118
 
*/
119
 
 
120
 
#include "soapH.h"
121
 
#include "webserver.nsmap"
122
 
#include "options.h"
123
 
#include "httpget.h"
124
 
#include "httpform.h"
125
 
#include "logging.h"
126
 
#include "threads.h"
127
 
/* #include "httpda.h" */       /* enable HTTP Digest Authentication */
128
 
#include <signal.h>             /* defines SIGPIPE */
129
 
 
130
 
#define BACKLOG (100)
131
 
 
132
 
#define AUTH_REALM "gSOAP Web Server Admin"
133
 
#define AUTH_USERID "admin"     /* user ID to access admin pages */
134
 
#define AUTH_PASSWD "guest"     /* user pw to access admin pages */
135
 
 
136
 
/******************************************************************************\
137
 
 *
138
 
 *      Thread pool and request queue
139
 
 *
140
 
\******************************************************************************/
141
 
 
142
 
#define MAX_THR (100)
143
 
#define MAX_QUEUE (1000)
144
 
 
145
 
static int poolsize = 0;
146
 
 
147
 
static int queue[MAX_QUEUE];
148
 
static int head = 0, tail = 0;
149
 
 
150
 
static MUTEX_TYPE queue_cs;
151
 
static COND_TYPE queue_cv;
152
 
 
153
 
/******************************************************************************\
154
 
 *
155
 
 *      Program options
156
 
 *
157
 
\******************************************************************************/
158
 
 
159
 
static const struct option default_options[] =
160
 
{ { "z.compress", NULL, },
161
 
  { "c.chunking", NULL, },
162
 
  { "k.keepalive", NULL, },
163
 
  { "i.iterative", NULL, },
164
 
  { "v.verbose", NULL, },
165
 
  { "o.pool", "threads", 6, "none"},
166
 
  { "t.ioTimeout", "seconds", 6, "5"},
167
 
  { "s.serverTimeout", "seconds", 6, "3600"},
168
 
  { "d.cookieDomain", "host", 20, "localhost"},
169
 
  { "p.cookiePath", "path", 20, "/"},
170
 
  { "l.logging", "none inbound outbound both", },
171
 
  { "", "port", },              /* rest of command line args */
172
 
  { NULL },                     /* must be NULL terminated */
173
 
};
174
 
 
175
 
/* The numbering of these defines must correspond to the option sequence */
176
 
#define OPTION_z        0
177
 
#define OPTION_c        1
178
 
#define OPTION_k        2
179
 
#define OPTION_i        3
180
 
#define OPTION_v        4
181
 
#define OPTION_o        5
182
 
#define OPTION_t        6
183
 
#define OPTION_s        7
184
 
#define OPTION_d        8
185
 
#define OPTION_p        9
186
 
#define OPTION_l        10
187
 
#define OPTION_port     11
188
 
 
189
 
/******************************************************************************\
190
 
 *
191
 
 *      Static
192
 
 *
193
 
\******************************************************************************/
194
 
 
195
 
static struct option *options = NULL;
196
 
static time_t start;
197
 
static int secure = 0;          /* =0: no SSL, =1: support SSL */
198
 
 
199
 
static const char *minutes[60] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
200
 
static const char *hours[24] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"};
201
 
 
202
 
/******************************************************************************\
203
 
 *
204
 
 *      Forward decls
205
 
 *
206
 
\******************************************************************************/
207
 
 
208
 
void server_loop(struct soap*);
209
 
void *process_request(void*);   /* multi-threaded request handler */
210
 
void *process_queue(void*);     /* multi-threaded request handler for pool */
211
 
int enqueue(SOAP_SOCKET);
212
 
SOAP_SOCKET dequeue();
213
 
int http_get_handler(struct soap*);     /* HTTP get handler */
214
 
int http_form_handler(struct soap*);    /* HTTP form handler */
215
 
int check_authentication(struct soap*); /* HTTP authentication check */
216
 
int copy_file(struct soap*, const char*, const char*);  /* copy file as HTTP response */
217
 
int calcget(struct soap*);
218
 
int calcpost(struct soap*);
219
 
int info(struct soap*);
220
 
int html_hbar(struct soap*, const char*, size_t, size_t, unsigned long);
221
 
int html_hist(struct soap*, const char*, size_t, size_t, size_t, const char**, size_t*, size_t);
222
 
void sigpipe_handle(int); /* SIGPIPE handler: Unix/Linux only */
223
 
 
224
 
/******************************************************************************\
225
 
 *
226
 
 *      OpenSSL
227
 
 *
228
 
\******************************************************************************/
229
 
 
230
 
int CRYPTO_thread_setup();
231
 
void CRYPTO_thread_cleanup();
232
 
 
233
 
/******************************************************************************\
234
 
 *
235
 
 *      Main
236
 
 *
237
 
\******************************************************************************/
238
 
 
239
 
int main(int argc, char **argv)
240
 
{
241
 
  struct soap soap;
242
 
  SOAP_SOCKET master;
243
 
  int port = 0;
244
 
 
245
 
  start = time(NULL);
246
 
 
247
 
  options = copy_options(default_options); /* must copy, so option values can be modified */
248
 
  if (parse_options(argc, argv, options))
249
 
    exit(0);
250
 
 
251
 
  if (options[OPTION_port].value)
252
 
    port = atol(options[OPTION_port].value);
253
 
  if (!port)
254
 
    port = 8080;
255
 
  fprintf(stderr, "Starting Web server on port %d\n", port);
256
 
  /* if the port is an odd number, the Web server uses HTTPS only */
257
 
  if (port % 2)
258
 
    secure = 1;
259
 
  if (secure)
260
 
    fprintf(stderr, "[Note: use https://localhost:%d/test.html to test the server from browser]\n", port);
261
 
  else
262
 
    fprintf(stderr, "[Note: use http://localhost:%d/test.html to test the server from browser]\n", port);
263
 
  fprintf(stderr, "[Note: you should enable Linux/Unix SIGPIPE handlers to avoid broken pipe]\n");
264
 
 
265
 
  soap_init2(&soap, SOAP_IO_KEEPALIVE, SOAP_IO_DEFAULT);
266
 
 
267
 
#ifdef WITH_OPENSSL
268
 
  if (CRYPTO_thread_setup())
269
 
  {
270
 
    fprintf(stderr, "Cannot setup thread mutex\n");
271
 
    exit(1);
272
 
  }
273
 
  /* SSL (to enable: compile all sources with -DWITH_OPENSSL) */
274
 
  if (secure && soap_ssl_server_context(&soap,
275
 
    SOAP_SSL_DEFAULT,
276
 
    "server.pem",       /* keyfile: see SSL docs on how to obtain this file */
277
 
    "password",         /* password to read the key file */
278
 
    NULL,               /* cacert */
279
 
    NULL,               /* capath */
280
 
    "dh512.pem",        /* DH file, if NULL use RSA */
281
 
    NULL,               /* if randfile!=NULL: use a file with random data to seed randomness */ 
282
 
    "webserver"         /* server identification for SSL session cache (must be a unique name) */
283
 
  ))
284
 
  {
285
 
    soap_print_fault(&soap, stderr);
286
 
    exit(1);
287
 
  }
288
 
#endif
289
 
  /* Register HTTP GET plugin */
290
 
  if (soap_register_plugin_arg(&soap, http_get, (void*)http_get_handler))
291
 
    soap_print_fault(&soap, stderr);
292
 
  /* Register HTTP POST plugin */
293
 
  if (soap_register_plugin_arg(&soap, http_form, (void*)http_form_handler))
294
 
    soap_print_fault(&soap, stderr);
295
 
  /* Register logging plugin */
296
 
  if (soap_register_plugin(&soap, logging))
297
 
    soap_print_fault(&soap, stderr);
298
 
#ifdef HTTPDA_H
299
 
  /* Register HTTP Digest Authentication plugin */
300
 
  if (soap_register_plugin(&soap, http_da))
301
 
    soap_print_fault(&soap, stderr);
302
 
#endif
303
 
  /* Unix SIGPIPE, this is OS dependent (win does not need this) */
304
 
  /* soap.accept_flags = SO_NOSIGPIPE; */       /* some systems like this */
305
 
  /* soap.socket_flags = MSG_NOSIGNAL; */       /* others need this */
306
 
  /* signal(SIGPIPE, sigpipe_handle); */        /* and some older Unix systems may require a sigpipe handler */
307
 
  master = soap_bind(&soap, NULL, port, BACKLOG);
308
 
  if (!soap_valid_socket(master))
309
 
  {
310
 
    soap_print_fault(&soap, stderr);
311
 
    exit(1);
312
 
  }
313
 
  fprintf(stderr, "Port bind successful: master socket = %d\n", master);
314
 
  MUTEX_SETUP(queue_cs);
315
 
  COND_SETUP(queue_cv);
316
 
  server_loop(&soap);
317
 
  MUTEX_CLEANUP(queue_cs);
318
 
  COND_CLEANUP(queue_cv);
319
 
  free_options(options);
320
 
  soap_end(&soap);
321
 
  soap_done(&soap);
322
 
#ifdef WITH_OPENSSL
323
 
  CRYPTO_thread_cleanup();
324
 
#endif
325
 
  THREAD_EXIT;
326
 
  return 0;
327
 
}
328
 
 
329
 
void server_loop(struct soap *soap)
330
 
{
331
 
  struct soap *soap_thr[MAX_THR];
332
 
  THREAD_TYPE tid, tids[MAX_THR];
333
 
  int req;
334
 
  struct logging_data *logdata;
335
 
 
336
 
  logdata = (struct logging_data*)soap_lookup_plugin(soap, logging_id); /* need to access plugin's data */
337
 
 
338
 
  for (req = 1; ; req++)
339
 
  {
340
 
    SOAP_SOCKET sock;
341
 
    int newpoolsize;
342
 
    
343
 
    soap->cookie_domain = options[OPTION_d].value;
344
 
    soap->cookie_path = options[OPTION_p].value;
345
 
    soap_set_cookie(soap, "visit", "true", NULL, NULL);
346
 
    soap_set_cookie_expire(soap, "visit", 600, NULL, NULL);
347
 
 
348
 
    if (options[OPTION_c].selected)
349
 
      soap_set_omode(soap, SOAP_IO_CHUNK); /* use chunked HTTP content (fast) */
350
 
    if (options[OPTION_k].selected)
351
 
      soap_set_omode(soap, SOAP_IO_KEEPALIVE);
352
 
    if (options[OPTION_t].value)
353
 
      soap->send_timeout = soap->recv_timeout = atol(options[OPTION_t].value);
354
 
    if (options[OPTION_s].value)
355
 
      soap->accept_timeout = atol(options[OPTION_s].value);
356
 
    if (options[OPTION_l].selected == 1 || options[OPTION_l].selected == 3)
357
 
      logdata->inbound = stdout;
358
 
    else
359
 
      logdata->inbound = NULL;
360
 
    if (options[OPTION_l].selected == 2 || options[OPTION_l].selected == 3)
361
 
      logdata->outbound = stdout;
362
 
    else
363
 
      logdata->outbound = NULL;
364
 
 
365
 
    newpoolsize = atol(options[OPTION_o].value);
366
 
 
367
 
    if (newpoolsize < 0)
368
 
      newpoolsize = 0;
369
 
    else if (newpoolsize > MAX_THR)
370
 
      newpoolsize = MAX_THR;
371
 
 
372
 
    if (poolsize > newpoolsize)
373
 
    {
374
 
      int job;
375
 
 
376
 
      for (job = 0; job < poolsize; job++)
377
 
      {
378
 
        while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM)
379
 
          sleep(1);
380
 
      }
381
 
 
382
 
      for (job = 0; job < poolsize; job++)
383
 
      {
384
 
        fprintf(stderr, "Waiting for thread %d to terminate...\n", job);
385
 
        THREAD_JOIN(tids[job]);
386
 
        fprintf(stderr, "Thread %d has stopped\n", job);
387
 
        soap_done(soap_thr[job]);
388
 
        free(soap_thr[job]);
389
 
      }
390
 
 
391
 
      poolsize = 0;
392
 
    }
393
 
 
394
 
    if (poolsize < newpoolsize)
395
 
    {
396
 
      int job;
397
 
 
398
 
      for (job = poolsize; job < newpoolsize; job++)
399
 
      {
400
 
        soap_thr[job] = soap_copy(soap);
401
 
        if (!soap_thr[job])
402
 
          break;
403
 
 
404
 
        soap_thr[job]->user = (void*)job;
405
 
        
406
 
        fprintf(stderr, "Starting thread %d\n", job);
407
 
        THREAD_CREATE(&tids[job], (void*(*)(void*))process_queue, (void*)soap_thr[job]);
408
 
      }
409
 
 
410
 
      poolsize = job;
411
 
    }
412
 
 
413
 
    sock = soap_accept(soap);
414
 
    if (!soap_valid_socket(sock))
415
 
    {
416
 
      if (soap->errnum)
417
 
      {
418
 
        soap_print_fault(soap, stderr);
419
 
        fprintf(stderr, "Retry...\n");
420
 
        continue;
421
 
      }
422
 
      fprintf(stderr, "gSOAP Web server timed out\n");
423
 
      break;
424
 
    }
425
 
 
426
 
    if (options[OPTION_v].selected)
427
 
      fprintf(stderr, "Request #%d accepted on socket %d connected from IP %d.%d.%d.%d\n", req, sock, (int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF, (int)(soap->ip>>8)&0xFF, (int)soap->ip&0xFF);
428
 
 
429
 
    if (poolsize > 0)
430
 
    {
431
 
      while (enqueue(sock) == SOAP_EOM)
432
 
        sleep(1);
433
 
    }
434
 
    else
435
 
    {
436
 
      struct soap *tsoap = NULL;
437
 
 
438
 
      if (!options[OPTION_i].selected)
439
 
        tsoap = soap_copy(soap);
440
 
 
441
 
      if (tsoap)
442
 
      {
443
 
#ifdef WITH_OPENSSL
444
 
        if (secure && soap_ssl_accept(tsoap))
445
 
        {
446
 
          soap_print_fault(tsoap, stderr);
447
 
          fprintf(stderr, "SSL request failed, continue with next call...\n");
448
 
          soap_end(tsoap);
449
 
          soap_done(tsoap);
450
 
          free(tsoap);
451
 
          continue;
452
 
        }
453
 
#endif
454
 
        tsoap->user = (void*)req;
455
 
        THREAD_CREATE(&tid, (void*(*)(void*))process_request, (void*)tsoap);
456
 
      }
457
 
      else
458
 
      {
459
 
#ifdef WITH_OPENSSL
460
 
        if (secure && soap_ssl_accept(soap))
461
 
        {
462
 
          soap_print_fault(soap, stderr);
463
 
          fprintf(stderr, "SSL request failed, continue with next call...\n");
464
 
          soap_end(soap);
465
 
          continue;
466
 
        }
467
 
#endif
468
 
        if (soap_serve(soap))
469
 
        {
470
 
          fprintf(stderr, "Request #%d completed with failure %d\n", req, soap->error);
471
 
          soap_print_fault(soap, stderr);
472
 
        }
473
 
 
474
 
        soap_end(soap);
475
 
        if (options[OPTION_v].selected)
476
 
          fprintf(stderr, "Request #%d completed\n", req);
477
 
      }
478
 
    }
479
 
  }
480
 
 
481
 
  if (poolsize > 0)
482
 
  {
483
 
    int job;
484
 
 
485
 
    for (job = 0; job < poolsize; job++)
486
 
    {
487
 
      while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM)
488
 
        sleep(1);
489
 
    }
490
 
 
491
 
    for (job = 0; job < poolsize; job++)
492
 
    {
493
 
      fprintf(stderr, "Waiting for thread %d to terminate... ", job);
494
 
      THREAD_JOIN(tids[job]);
495
 
      fprintf(stderr, "terminated\n");
496
 
      soap_done(soap_thr[job]);
497
 
      free(soap_thr[job]);
498
 
    }
499
 
  }
500
 
}
501
 
 
502
 
/******************************************************************************\
503
 
 *
504
 
 *      Process dispatcher
505
 
 *
506
 
\******************************************************************************/
507
 
 
508
 
void *process_request(void *soap)
509
 
{
510
 
  struct soap *tsoap = (struct soap*)soap;
511
 
 
512
 
  THREAD_DETACH(THREAD_ID);
513
 
 
514
 
  if (soap_serve(tsoap))
515
 
  {
516
 
    fprintf(stderr, "Thread %d completed with failure %d\n", (int)tsoap->user, tsoap->error);
517
 
    soap_print_fault(tsoap, stderr);
518
 
  }
519
 
  else if (options[OPTION_v].selected)
520
 
    fprintf(stderr, "Thread %d completed\n", (int)tsoap->user);
521
 
  /* soap_destroy((struct soap*)soap); */ /* cleanup class instances (but this is a C app) */
522
 
 
523
 
  soap_end(tsoap);
524
 
  soap_done(tsoap);
525
 
  free(soap);
526
 
 
527
 
  return NULL;
528
 
}
529
 
 
530
 
/******************************************************************************\
531
 
 *
532
 
 *      Thread pool (enabled with option -o<num>)
533
 
 *
534
 
\******************************************************************************/
535
 
 
536
 
void *process_queue(void *soap)
537
 
{
538
 
  struct soap *tsoap = (struct soap*)soap;
539
 
 
540
 
  for (;;)
541
 
  {
542
 
    tsoap->socket = dequeue();
543
 
    if (!soap_valid_socket(tsoap->socket))
544
 
    { if (options[OPTION_v].selected)
545
 
        fprintf(stderr, "Thread %d terminating\n", (int)tsoap->user);
546
 
      break;
547
 
    }
548
 
 
549
 
#ifdef WITH_OPENSSL
550
 
    if (secure && soap_ssl_accept(tsoap))
551
 
    {
552
 
      soap_print_fault(tsoap, stderr);
553
 
      fprintf(stderr, "SSL request failed, continue with next call...\n");
554
 
      soap_end(tsoap);
555
 
      soap_done(tsoap);
556
 
      continue;
557
 
    }
558
 
#endif
559
 
 
560
 
    if (options[OPTION_v].selected)
561
 
      fprintf(stderr, "Thread %d accepted a request\n", (int)tsoap->user);
562
 
    if (soap_serve(tsoap))
563
 
    {
564
 
      fprintf(stderr, "Thread %d finished serving request with failure %d\n", (int)tsoap->user, tsoap->error);
565
 
      soap_print_fault(tsoap, stderr);
566
 
    }
567
 
    else if (options[OPTION_v].selected)
568
 
      fprintf(stderr, "Thread %d finished serving request\n", (int)tsoap->user);
569
 
 
570
 
    soap_destroy(tsoap);
571
 
    soap_end(tsoap);
572
 
  }
573
 
 
574
 
  return NULL;
575
 
}
576
 
 
577
 
int enqueue(SOAP_SOCKET sock)
578
 
{
579
 
  int status = SOAP_OK;
580
 
  int next;
581
 
  int ret;
582
 
 
583
 
  if ((ret = MUTEX_LOCK(queue_cs)))
584
 
    fprintf(stderr, "MUTEX_LOCK error %d\n", ret);
585
 
 
586
 
  next = (tail + 1) % MAX_QUEUE;
587
 
  if (head == next)
588
 
  {
589
 
    /* don't block on full queue, return SOAP_EOM */
590
 
    status = SOAP_EOM;
591
 
  }
592
 
  else
593
 
  {
594
 
    queue[tail] = sock;
595
 
    tail = next;
596
 
 
597
 
    if (options[OPTION_v].selected)
598
 
      fprintf(stderr, "enqueue(%d)\n", sock);
599
 
 
600
 
    if ((ret = COND_SIGNAL(queue_cv)))
601
 
      fprintf(stderr, "COND_SIGNAL error %d\n", ret);
602
 
  }
603
 
 
604
 
  if ((ret = MUTEX_UNLOCK(queue_cs)))
605
 
    fprintf(stderr, "MUTEX_UNLOCK error %d\n", ret);
606
 
 
607
 
  return status;
608
 
}
609
 
 
610
 
SOAP_SOCKET dequeue()
611
 
{
612
 
  SOAP_SOCKET sock;
613
 
  int ret;
614
 
 
615
 
  if ((ret = MUTEX_LOCK(queue_cs)))
616
 
    fprintf(stderr, "MUTEX_LOCK error %d\n", ret);
617
 
 
618
 
  while (head == tail)
619
 
    if ((ret = COND_WAIT(queue_cv, queue_cs)))
620
 
      fprintf(stderr, "COND_WAIT error %d\n", ret);
621
 
 
622
 
  sock = queue[head];
623
 
  
624
 
  head = (head + 1) % MAX_QUEUE;
625
 
 
626
 
  if (options[OPTION_v].selected)
627
 
    fprintf(stderr, "dequeue(%d)\n", sock);
628
 
 
629
 
  if ((ret = MUTEX_UNLOCK(queue_cs)))
630
 
    fprintf(stderr, "MUTEX_UNLOCK error %d\n", ret);
631
 
 
632
 
  return sock;
633
 
}
634
 
 
635
 
/******************************************************************************\
636
 
 *
637
 
 *      SOAP/XML handling: calculator example
638
 
 *
639
 
\******************************************************************************/
640
 
 
641
 
int ns__add(struct soap *soap, double a, double b, double *c)
642
 
{
643
 
  *c = a + b;
644
 
  return SOAP_OK;
645
 
}
646
 
 
647
 
int ns__sub(struct soap *soap, double a, double b, double *c)
648
 
{
649
 
  *c = a - b;
650
 
  return SOAP_OK;
651
 
}
652
 
 
653
 
int ns__mul(struct soap *soap, double a, double b, double *c)
654
 
{
655
 
  *c = a * b;
656
 
  return SOAP_OK;
657
 
}
658
 
 
659
 
int ns__div(struct soap *soap, double a, double b, double *c)
660
 
{
661
 
  *c = a / b;
662
 
  return SOAP_OK;
663
 
}
664
 
 
665
 
/******************************************************************************\
666
 
 *
667
 
 *      Server dummy methods to avoid link errors
668
 
 *
669
 
\******************************************************************************/
670
 
 
671
 
int ns__addResponse_(struct soap *soap, double a)
672
 
{
673
 
  return SOAP_NO_METHOD; /* we don't use this: we use soap_send_ns__addResponse instead */
674
 
}
675
 
 
676
 
int ns__subResponse_(struct soap *soap, double a)
677
 
{
678
 
  return SOAP_NO_METHOD; /* we don't use this: we use soap_send_ns__subResponse instead */
679
 
}
680
 
 
681
 
int ns__mulResponse_(struct soap *soap, double a)
682
 
{
683
 
  return SOAP_NO_METHOD; /* we don't use this: we use soap_send_ns__mulResponse instead */
684
 
}
685
 
 
686
 
int ns__divResponse_(struct soap *soap, double a)
687
 
{
688
 
  return SOAP_NO_METHOD; /* we don't use this: we use soap_send_ns__divResponse instead */
689
 
}
690
 
 
691
 
/******************************************************************************\
692
 
 *
693
 
 *      HTTP GET handler for plugin
694
 
 *
695
 
\******************************************************************************/
696
 
 
697
 
int http_get_handler(struct soap *soap)
698
 
{
699
 
  /* gSOAP >=2.5 soap_response() will do this automatically for us, when sending SOAP_HTML or SOAP_FILE:
700
 
  if ((soap->omode & SOAP_IO) != SOAP_IO_CHUNK)
701
 
    soap_set_omode(soap, SOAP_IO_STORE); */ /* if not chunking we MUST buffer entire content when returning HTML pages to determine content length */
702
 
#ifdef WITH_ZLIB
703
 
  if (options[OPTION_z].selected && soap->zlib_out == SOAP_ZLIB_GZIP) /* client accepts gzip */
704
 
  { soap_set_omode(soap, SOAP_ENC_ZLIB); /* so we can compress content (gzip) */
705
 
    soap->z_level = 9; /* best compression */
706
 
  }
707
 
  else
708
 
    soap_clr_omode(soap, SOAP_ENC_ZLIB); /* so we can compress content (gzip) */
709
 
#endif
710
 
  /* Use soap->path (from request URL) to determine request: */
711
 
  if (options[OPTION_v].selected)
712
 
    fprintf(stderr, "HTTP GET Request: %s\n", soap->endpoint);
713
 
  /* Note: soap->path always starts with '/' */
714
 
  if (strchr(soap->path + 1, '/') || strchr(soap->path + 1, '\\'))      /* we don't like snooping in dirs */
715
 
    return 403; /* HTTP forbidden */
716
 
  if (!soap_tag_cmp(soap->path, "*.html"))
717
 
    return copy_file(soap, soap->path + 1, "text/html");
718
 
  if (!soap_tag_cmp(soap->path, "*.xml")
719
 
   || !soap_tag_cmp(soap->path, "*.xsd")
720
 
   || !soap_tag_cmp(soap->path, "*.wsdl"))
721
 
    return copy_file(soap, soap->path + 1, "text/xml");
722
 
  if (!soap_tag_cmp(soap->path, "*.jpg"))
723
 
    return copy_file(soap, soap->path + 1, "image/jpeg");
724
 
  if (!soap_tag_cmp(soap->path, "*.gif"))
725
 
    return copy_file(soap, soap->path + 1, "image/gif");
726
 
  if (!soap_tag_cmp(soap->path, "*.png"))
727
 
    return copy_file(soap, soap->path + 1, "image/png");
728
 
  if (!soap_tag_cmp(soap->path, "*.ico"))
729
 
    return copy_file(soap, soap->path + 1, "image/ico");
730
 
  if (!strncmp(soap->path, "/calc?", 6))
731
 
    return calcget(soap);
732
 
  if (!strncmp(soap->path, "/genivia", 8))
733
 
  { strcpy(soap->endpoint, "http://genivia.com"); /* redirect */
734
 
    strcat(soap->endpoint, soap->path + 8);
735
 
    return 307; /* Temporary Redirect */
736
 
  }
737
 
  /* Check requestor's authentication: */
738
 
  if (check_authentication(soap))
739
 
    return 401; /* HTTP not authorized */
740
 
  /* Return Web server status */
741
 
  if (soap->path[1] == '\0' || soap->path[1] == '?')
742
 
    return info(soap);
743
 
  return 404; /* HTTP not found */
744
 
}
745
 
 
746
 
int check_authentication(struct soap *soap)
747
 
{ if (soap->userid && soap->passwd)
748
 
  { if (!strcmp(soap->userid, AUTH_USERID) && !strcmp(soap->passwd, AUTH_PASSWD))
749
 
      return SOAP_OK;
750
 
  }
751
 
#ifdef HTTPDA_H
752
 
  else if (soap->authrealm && soap->userid)
753
 
  { if (!strcmp(soap->authrealm, AUTH_REALM) && !strcmp(soap->userid, AUTH_USERID))
754
 
      if (!http_da_verify_get(soap, AUTH_PASSWD))
755
 
        return SOAP_OK;
756
 
  }
757
 
#endif
758
 
  soap->authrealm = AUTH_REALM;
759
 
  return 401;
760
 
}
761
 
 
762
 
/******************************************************************************\
763
 
 *
764
 
 *      HTTP POST application/x-www-form-urlencoded handler for plugin
765
 
 *
766
 
\******************************************************************************/
767
 
 
768
 
int http_form_handler(struct soap *soap)
769
 
{
770
 
#ifdef WITH_ZLIB
771
 
  if (options[OPTION_z].selected && soap->zlib_out == SOAP_ZLIB_GZIP) /* client accepts gzip */
772
 
    soap_set_omode(soap, SOAP_ENC_ZLIB); /* so we can compress content (gzip) */
773
 
  soap->z_level = 9; /* best compression */
774
 
#endif
775
 
  /* Use soap->path (from request URL) to determine request: */
776
 
  if (options[OPTION_v].selected)
777
 
    fprintf(stderr, "HTTP POST Request: %s\n", soap->endpoint);
778
 
  /* Note: soap->path always starts with '/' */
779
 
  if (!strcmp(soap->path, "/calc"))
780
 
    return calcpost(soap);
781
 
  return 404; /* HTTP not found */
782
 
}
783
 
 
784
 
/******************************************************************************\
785
 
 *
786
 
 *      Copy static page
787
 
 *
788
 
\******************************************************************************/
789
 
 
790
 
int copy_file(struct soap *soap, const char *name, const char *type)
791
 
{ FILE *fd;
792
 
  size_t r;
793
 
  fd = fopen(name, "rb"); /* open file to copy */
794
 
  if (!fd)
795
 
    return 404; /* return HTTP not found */
796
 
  soap->http_content = type;
797
 
  if (soap_response(soap, SOAP_FILE)) /* OK HTTP response header */
798
 
  { soap_end_send(soap);
799
 
    fclose(fd);
800
 
    return soap->error;
801
 
  }
802
 
  for (;;)
803
 
  { r = fread(soap->tmpbuf, 1, sizeof(soap->tmpbuf), fd);
804
 
    if (!r)
805
 
      break;
806
 
    if (soap_send_raw(soap, soap->tmpbuf, r))
807
 
    { soap_end_send(soap);
808
 
      fclose(fd);
809
 
      return soap->error;
810
 
    }
811
 
  }
812
 
  fclose(fd);
813
 
  return soap_end_send(soap);
814
 
}
815
 
 
816
 
/******************************************************************************\
817
 
 *
818
 
 *      Example dynamic HTTP GET application/x-www-form-urlencoded calculator
819
 
 *
820
 
\******************************************************************************/
821
 
 
822
 
int calcget(struct soap *soap)
823
 
{ int o = 0, a = 0, b = 0, val;
824
 
  char buf[256];
825
 
  char *s = query(soap); /* get argument string from URL ?query string */
826
 
  while (s)
827
 
  { char *key = query_key(soap, &s); /* decode next query string key */
828
 
    char *val = query_val(soap, &s); /* decode next query string value (if any) */
829
 
    if (key && val)
830
 
    { if (!strcmp(key, "o"))
831
 
        o = val[0];
832
 
      else if (!strcmp(key, "a"))
833
 
        a = strtol(val, NULL, 10);
834
 
      else if (!strcmp(key, "b"))
835
 
        b = strtol(val, NULL, 10);
836
 
    }
837
 
  }
838
 
  switch (o)
839
 
  { case 'a':
840
 
      val = a + b;
841
 
      break;
842
 
    case 's':
843
 
      val = a - b;
844
 
      break;
845
 
    case 'm':
846
 
      val = a * b;
847
 
      break;
848
 
    case 'd':
849
 
      val = a / b;
850
 
      break;
851
 
    default:
852
 
      return soap_sender_fault(soap, "Unknown operation", NULL);
853
 
  }
854
 
  soap_response(soap, SOAP_HTML);
855
 
  sprintf(buf, "<html>value=%d</html>", val);
856
 
  soap_send(soap, buf);
857
 
  soap_end_send(soap);
858
 
  return SOAP_OK;
859
 
}
860
 
 
861
 
/******************************************************************************\
862
 
 *
863
 
 *      Example dynamic HTTP POST application/x-www-form-urlencoded calculator
864
 
 *
865
 
\******************************************************************************/
866
 
 
867
 
int calcpost(struct soap *soap)
868
 
{ int o = 0, a = 0, b = 0, val;
869
 
  char buf[256];
870
 
  char *s = form(soap); /* get form data from body */
871
 
  while (s)
872
 
  { char *key = query_key(soap, &s); /* decode next key */
873
 
    char *val = query_val(soap, &s); /* decode next value (if any) */
874
 
    if (key && val)
875
 
    { if (!strcmp(key, "o"))
876
 
        o = val[0];
877
 
      else if (!strcmp(key, "a"))
878
 
        a = strtol(val, NULL, 10);
879
 
      else if (!strcmp(key, "b"))
880
 
        b = strtol(val, NULL, 10);
881
 
    }
882
 
  }
883
 
  switch (o)
884
 
  { case 'a':
885
 
      val = a + b;
886
 
      break;
887
 
    case 's':
888
 
      val = a - b;
889
 
      break;
890
 
    case 'm':
891
 
      val = a * b;
892
 
      break;
893
 
    case 'd':
894
 
      val = a / b;
895
 
      break;
896
 
    default:
897
 
      return soap_sender_fault(soap, "Unknown operation", NULL);
898
 
  }
899
 
  soap_response(soap, SOAP_HTML);
900
 
  sprintf(buf, "<html>value=%d</html>", val);
901
 
  soap_send(soap, buf);
902
 
  soap_end_send(soap);
903
 
  return SOAP_OK;
904
 
}
905
 
 
906
 
/******************************************************************************\
907
 
 *
908
 
 *      Example dynamic HTTP POST multipart/form-data form-based calculator
909
 
 *
910
 
\******************************************************************************/
911
 
 
912
 
int f__form1(struct soap *soap)
913
 
{ int o = 0, a = 0, b = 0, val;
914
 
  char buf[256];
915
 
  struct soap_multipart *content;
916
 
  for (content = soap->mime.list; content; content = content->next)
917
 
  { if (content->id && content->ptr)
918
 
    { /* may have to check content->encoding to convert data when necessary! */
919
 
      if (!strcmp(content->id, "o"))
920
 
        o = content->ptr[0];
921
 
      else if (!strcmp(content->id, "a"))
922
 
        a = strtol(content->ptr, NULL, 10);
923
 
      else if (!strcmp(content->id, "b"))
924
 
        b = strtol(content->ptr, NULL, 10);
925
 
    }
926
 
  }
927
 
  switch (o)
928
 
  { case 'a':
929
 
      val = a + b;
930
 
      break;
931
 
    case 's':
932
 
      val = a - b;
933
 
      break;
934
 
    case 'm':
935
 
      val = a * b;
936
 
      break;
937
 
    case 'd':
938
 
      val = a / b;
939
 
      break;
940
 
    default:
941
 
      return soap_sender_fault(soap, "Unknown operation", NULL);
942
 
  }
943
 
  soap_response(soap, SOAP_HTML);
944
 
  sprintf(buf, "<html>value=%d</html>", val);
945
 
  soap_send(soap, buf);
946
 
  soap_end_send(soap);
947
 
  return SOAP_OK;
948
 
}
949
 
 
950
 
int f__form2(struct soap *soap, struct f__formResponse *response)
951
 
{ int o = 0, a = 0, b = 0;
952
 
  struct soap_multipart *content;
953
 
  for (content = soap->mime.list; content; content = content->next)
954
 
  { if (content->id && content->ptr)
955
 
    { /* may have to check content->encoding to convert data when necessary! */
956
 
      if (!strcmp(content->id, "o"))
957
 
        o = content->ptr[0];
958
 
      else if (!strcmp(content->id, "a"))
959
 
        a = strtol(content->ptr, NULL, 10);
960
 
      else if (!strcmp(content->id, "b"))
961
 
        b = strtol(content->ptr, NULL, 10);
962
 
    }
963
 
  }
964
 
  switch (o)
965
 
  { case 'a':
966
 
      response->result = a + b;
967
 
      break;
968
 
    case 's':
969
 
      response->result = a - b;
970
 
      break;
971
 
    case 'm':
972
 
      response->result = a * b;
973
 
      break;
974
 
    case 'd':
975
 
      response->result = a / b;
976
 
      break;
977
 
    default:
978
 
      return soap_sender_fault(soap, "Unknown operation", NULL);
979
 
  }
980
 
  return SOAP_OK;
981
 
}
982
 
 
983
 
/******************************************************************************\
984
 
 *
985
 
 *      Dynamic Web server info page
986
 
 *
987
 
\******************************************************************************/
988
 
 
989
 
int info(struct soap *soap)
990
 
{ struct http_get_data *getdata;
991
 
  struct logging_data *logdata;
992
 
  const char *t0, *t1, *t2, *t3, *t4, *t5, *t6, *t7;
993
 
  char buf[2048]; /* buffer large enough to hold HTML content */
994
 
  struct soap_plugin *p;
995
 
  time_t now = time(NULL), elapsed = now - start;
996
 
  query_options(soap, options);
997
 
  if (soap->omode & SOAP_IO_KEEPALIVE)
998
 
    t0 = "<td align='center' bgcolor='green'>YES</td>";
999
 
  else
1000
 
    t0 = "<td align='center' bgcolor='red'>NO</td>";
1001
 
#ifdef WITH_COOKIES
1002
 
  t1 = "<td align='center' bgcolor='green'>YES</td>";
1003
 
  /* soap_env_cookie_value() returns value of a cookie received (from client) */
1004
 
  if (soap_env_cookie_value(soap, "visit", NULL, NULL))
1005
 
    t2 = "<td align='center' bgcolor='green'>PASS</td>";
1006
 
  else
1007
 
    t2 = "<td align='center' bgcolor='yellow'>WAIT</td>";
1008
 
#else
1009
 
  t1 = "<td align='center' bgcolor='red'>NO</td>";
1010
 
  t2 = "<td align='center' bgcolor='blue'>N/A</td>";
1011
 
#endif
1012
 
  if (secure)
1013
 
  { t3 = "<td align='center' bgcolor='green'>YES</td>";
1014
 
    if (soap->imode & SOAP_ENC_SSL)
1015
 
      t4 = "<td align='center' bgcolor='green'>PASS</td>";
1016
 
    else
1017
 
      t4 = "<td align='center' bgcolor='red'><blink>FAIL</blink></td>";
1018
 
  }
1019
 
  else
1020
 
  { t3 = "<td align='center' bgcolor='red'>NO</td>";
1021
 
    t4 = "<td align='center' bgcolor='blue'>N/A</td>";
1022
 
  }
1023
 
#ifdef WITH_ZLIB
1024
 
  if (options[OPTION_z].selected)
1025
 
  { t5 = "<td align='center' bgcolor='green'>YES</td>";
1026
 
    if (soap->omode & SOAP_ENC_ZLIB)
1027
 
      t6 = "<td align='center' bgcolor='green'>PASS</td>";
1028
 
    else
1029
 
      t6 = "<td align='center' bgcolor='yellow'>WAIT</td>";
1030
 
  }
1031
 
  else
1032
 
  { t5 = "<td align='center' bgcolor='red'>NO</td>";
1033
 
    t6 = "<td align='center' bgcolor='blue'>N/A</td>";
1034
 
  }
1035
 
#else
1036
 
  t5 = "<td align='center' bgcolor='red'>NO</td>";
1037
 
  t6 = "<td align='center' bgcolor='blue'>N/A</td>";
1038
 
#endif
1039
 
  if (options[OPTION_c].selected || (soap->omode & SOAP_IO) == SOAP_IO_CHUNK)
1040
 
    t7 = "<td align='center' bgcolor='green'>YES</td>";
1041
 
  else
1042
 
    t7 = "<td align='center' bgcolor='red'>NO</td>";
1043
 
  if (soap_response(soap, SOAP_HTML))
1044
 
    return soap->error;
1045
 
  sprintf(buf, "\
1046
 
<html>\
1047
 
<head>\
1048
 
<meta name='Author' content='Robert A. van Engelen'>\
1049
 
<meta name='Generator' content='gSOAP'>\
1050
 
<meta http-equiv='Refresh' content='60'>\
1051
 
<style type='text/css' media='screen'><!-- table { background-color: #666 } td { color: white; font-size: 10px; line-height: 10px; font-family: Arial, Helvetica, Geneva, Swiss, SunSans-Regular } --></style>\
1052
 
<title>gSOAP Web Server Administration</title>\
1053
 
</head>\
1054
 
<body bgcolor='#FFFFFF'>\
1055
 
<h1>gSOAP Web Server Administration</h1>\
1056
 
<p>Server endpoint=%s client agent IP=%d.%d.%d.%d\
1057
 
<h2>Registered Plugins</h2>\
1058
 
", soap->endpoint, (int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF, (int)(soap->ip>>8)&0xFF, (int)soap->ip&0xFF);
1059
 
  if (soap_send(soap, buf))
1060
 
    return soap->error;
1061
 
  for (p = soap->plugins; p; p = p->next)
1062
 
  { sprintf(buf, "%s<br>", p->id);
1063
 
    if (soap_send(soap, buf))
1064
 
      return soap->error;
1065
 
  }
1066
 
  if (soap_send(soap, "<h2>Elapsed Time</h2>"))
1067
 
    return soap->error;
1068
 
  if (elapsed >= 86400)
1069
 
    html_hbar(soap, "Days:", 100, elapsed/86400, 0x000000);
1070
 
  if (elapsed >= 3600)
1071
 
    html_hbar(soap, "Hours:", 100, elapsed/3600%24, 0x000000);
1072
 
  html_hbar(soap, "Minutes:", 100, elapsed/60%60, 0x000000);
1073
 
  soap_send(soap, "<h2>Control Panel</h2>");
1074
 
  if (html_form_options(soap, options))
1075
 
    return soap->error;
1076
 
  sprintf(buf, "\
1077
 
<h2>Function Tests</h2>\
1078
 
<table border='0' cellspacing='0' cellpadding='0' bgcolor='#666666' nosave>\
1079
 
<tr height='10'><td height='10' background='bl.gif'></td><td height='10'><i>Function</i></td><td align='center' height='10'><i>Result</i></td><td height='10' background='obls.gif'></td></tr>\
1080
 
<tr><td background='bl.gif'></td><td>HTTP operational</td><td align='center' bgcolor='green'>YES</td><td width='10' background='ls.gif'></td></tr>\
1081
 
<tr><td background='bl.gif'></td><td>HTTP keep alive enabled</td>%s<td width='10' background='ls.gif'></td></tr>\
1082
 
<tr><td background='bl.gif'></td><td>HTTP cookies enabled</td>%s<td width='10' background='ls.gif'></td></tr>\
1083
 
<tr><td background='bl.gif'></td><td>HTTP cookies test</td>%s<td width='10' background='ls.gif'></td></tr>\
1084
 
<tr><td background='bl.gif'></td><td>HTTPS (OpenSSL) enabled</td>%s<td width='10' background='ls.gif'></td></tr>\
1085
 
<tr><td background='bl.gif'></td><td>HTTPS (OpenSSL) test</td>%s<td width='10' background='ls.gif'></td></tr>\
1086
 
<tr><td background='bl.gif'></td><td>HTTP compression enabled</td>%s<td width='10' background='ls.gif'></td></tr>\
1087
 
<tr><td background='bl.gif'></td><td>HTTP compression test</td>%s<td width='10' background='ls.gif'></td></tr>\
1088
 
<tr><td background='bl.gif'></td><td>HTTP chunking enabled</td>%s<td width='10' background='ls.gif'></td></tr>\
1089
 
<tr height='10'><td width='10' height='10' background=otrs.gif></td><td height='10' background='ts.gif'></td><td height='10' background='ts.gif'></td><td width='10' height='10' background='otls.gif'></td></tr>\
1090
 
</table>", t0, t1, t2, t3, t4, t5, t6, t7);
1091
 
  if (soap_send(soap, buf))
1092
 
    return soap->error;
1093
 
  getdata = (struct http_get_data*)soap_lookup_plugin(soap, http_get_id);
1094
 
  logdata = (struct logging_data*)soap_lookup_plugin(soap, logging_id);
1095
 
  soap_send(soap, "<h2>Usage Statistics</h2>");
1096
 
  if (getdata)
1097
 
  { html_hbar(soap, "HTTP&nbsp;GET", 120, getdata->stat_get, 0x0000FF);
1098
 
    html_hbar(soap, "HTTP&nbsp;POST", 120, getdata->stat_post, 0x00FF00);
1099
 
    html_hbar(soap, "HTTP&nbsp;FAIL", 120, getdata->stat_fail, 0xFF0000);
1100
 
  }
1101
 
  if (logdata)
1102
 
  { html_hbar(soap, "SENT(kB)", 120, logdata->stat_sent/1024, 0x00FFFF);
1103
 
    html_hbar(soap, "RECV(kB)", 120, logdata->stat_recv/1024, 0x00FFFF);
1104
 
    if (elapsed > 0)
1105
 
    { html_hbar(soap, "SENT(kB/s)", 120, logdata->stat_sent/elapsed/1024, 0x00FFFF);
1106
 
      html_hbar(soap, "RECV(kB/s)", 120, logdata->stat_recv/elapsed/1024, 0x00FFFF);
1107
 
    }
1108
 
  }
1109
 
  if (getdata)
1110
 
  { struct tm T;
1111
 
    T.tm_min = 99;
1112
 
    T.tm_hour = 99;
1113
 
    T.tm_yday = 999;
1114
 
#ifdef HAVE_LOCALTIME_R
1115
 
    localtime_r(&now, &T);
1116
 
#else
1117
 
    T = *localtime(&now);
1118
 
#endif
1119
 
    soap_send(soap, "<h2>Requests by the Minute</h2>");
1120
 
    html_hist(soap, "Minute", 12, 0, 60, minutes, getdata->min, T.tm_min);
1121
 
    soap_send(soap, "<h2>Requests by the Hour</h2>");
1122
 
    html_hist(soap, "Hour", 30, 0, 24, hours, getdata->hour, T.tm_hour);
1123
 
    soap_send(soap, "<h2>Requests by Day of the Year</h2>");
1124
 
    html_hist(soap, "Day", 2, 0, 365, NULL, getdata->day, T.tm_yday);
1125
 
  }
1126
 
  soap_send(soap, "\
1127
 
<p>This page will automatically reload every minute to refresh the statistics.\
1128
 
<br><br><br><img src='favicon.gif' align='absmiddle'>Powered by gSOAP\
1129
 
</body>\
1130
 
</HTML>");
1131
 
  return soap_end_send(soap);
1132
 
}
1133
 
 
1134
 
static size_t html_scaled(char *buf, size_t len)
1135
 
{ if (len > 1000000)
1136
 
  { sprintf(buf, "%.2f&#183;10<sup>6</sup>", (float)len/1000000.0);
1137
 
    return len / 1000000;
1138
 
  }
1139
 
  if (len > 1000)
1140
 
  { sprintf(buf, "%.2f&#183;10<sup>3</sup>", (float)len/1000.0);
1141
 
    return len / 1000;
1142
 
  }
1143
 
  sprintf(buf, "%lu", (unsigned long)len);
1144
 
  return len;
1145
 
}
1146
 
 
1147
 
int html_hbar(struct soap *soap, const char *title, size_t pix, size_t len, unsigned long color)
1148
 
{ char buf[2048]; /* buffer large enough to hold HTML content */
1149
 
  char lab[32];
1150
 
  len = html_scaled(lab, len);
1151
 
  sprintf(buf, "\
1152
 
<table border='0' cellspacing='0' cellpadding='0' height='30'>\
1153
 
<tr height='10'>\
1154
 
<td width='10' height='10' background='bl.gif'></td>\
1155
 
<td rowspan='2' bgcolor='#666666' width='%lu' height='20'>%s&nbsp;%s</td>\
1156
 
<td bgcolor='#%.6lx' width='%lu' height='10'></td>\
1157
 
<td width='10' height='10' background='obls.gif'></td>\
1158
 
</tr>\
1159
 
<tr height='10'>\
1160
 
<td width='10' height='10' background='bl.gif'></td>\
1161
 
<td height='10' background='ruler.gif'></td>\
1162
 
<td width='10' height='10' background='ls.gif'></td>\
1163
 
</tr>\
1164
 
<tr height='10'>\
1165
 
<td width='10' height='10' background='otrs.gif'></td>\
1166
 
<td colspan='2' height='10' background='ts.gif'></td>\
1167
 
<td width='10' height='10' background='otls.gif'></td>\
1168
 
</tr>\
1169
 
</table>", (unsigned long)pix, title ? title : "", lab, color, (unsigned long)len * 2);
1170
 
  return soap_send(soap, buf);
1171
 
}
1172
 
 
1173
 
int html_hist(struct soap *soap, const char *title, size_t barwidth, size_t height, size_t num, const char **key, size_t *val, size_t highlight)
1174
 
{ char buf[2048]; /* buffer large enough to hold HTML content */
1175
 
  char lab[32];
1176
 
  size_t i, max;
1177
 
  float scale;
1178
 
  max = 0;
1179
 
  for (i = 0; i < num; i++)
1180
 
  { if (val[i] > max)
1181
 
      max = val[i];
1182
 
  }
1183
 
  if (height < 20)
1184
 
  { height = max;
1185
 
    if (height < 20)
1186
 
      height = 20;
1187
 
    else if (height > 256)
1188
 
      height = 256;
1189
 
  }
1190
 
  scale = (float)height / (float)max;
1191
 
  html_scaled(lab, max);
1192
 
  sprintf(buf, "\
1193
 
<a name='%s'></a>\
1194
 
<table bgcolor='#FFFFFF' border='0' cellspacing='0' cellpadding='0' height='%lu' align='center'>\
1195
 
<tr height='10'>\
1196
 
<td width='10' height='10' background='btl.gif'></td><td colspan='%lu' height='10' background='bt.gif'></td><td width='10' height='10' background='btr.gif'></td><td width='10' height='10' background='obls.gif'></td>\
1197
 
</tr>\
1198
 
<tr height='%lu' align='center' valign='bottom'>\
1199
 
<td width='10' height='%lu' background='bl.gif'></td>\
1200
 
<td bgcolor='#666666' valign='top'>%s</td>", title ? title : "", (unsigned long)height + 50, (unsigned long)num + 1, (unsigned long)height, (unsigned long)height, lab);
1201
 
  if (soap_send(soap, buf))
1202
 
    return soap->error;
1203
 
  for (i = 0; i < num; i++)
1204
 
  { unsigned long bar = (scale * val[i] + 0.5);
1205
 
    if (bar >= 1)
1206
 
      sprintf(buf, "\
1207
 
<td bgcolor='#FFFFFF'><a onmouseover=\"window.status='%lu';return true\" onmouseout=\"window.status='';return true\" href='#%s'><img src='top.gif' alt='' width='%lu' height='1' align='bottom' border='0'><br><img src='bar.gif' alt='' width='%lu' height='%lu' align='bottom' border='0'></a></td>", (unsigned long)i, title ? title : "", (unsigned long)barwidth, (unsigned long)barwidth, bar - 1);
1208
 
    else
1209
 
      sprintf(buf, "\
1210
 
<td bgcolor='#FFFFFF'><img src='bar.gif' alt='' width='%lu' height='0' align='bottom' border='0'></td>", (unsigned long)barwidth);
1211
 
    if (soap_send(soap, buf))
1212
 
      return soap->error;
1213
 
  }
1214
 
  sprintf(buf, "\
1215
 
<td width='10' height='%lu' background='br.gif'></td>\
1216
 
<td width='10' height='%lu' background='ls.gif'></td>\
1217
 
</tr>\
1218
 
<tr bgcolor='#666666' height='20' align='center'>\
1219
 
<td width='10' height='20' background='bl.gif'></td>\
1220
 
<td bgcolor='#666666'>%s</td>", (unsigned long)height, (unsigned long)height, title ? title : "");
1221
 
  if (soap_send(soap, buf))
1222
 
    return soap->error;
1223
 
  for (i = 0; i < num; i++)
1224
 
  { sprintf(buf, "<td%s>%s</td>", (i == highlight) ? " bgcolor='#777777'" : "", key ? key[i] : "<img src='bar.gif'>");
1225
 
    if (soap_send(soap, buf))
1226
 
      return soap->error;
1227
 
  }
1228
 
  if (soap_send(soap, "\
1229
 
<td width='10' height='20' background='br.gif'></td>\
1230
 
<td width='10' height='20' background='ls.gif'></td>"))
1231
 
    return soap->error;
1232
 
  sprintf(buf, "\
1233
 
</tr>\
1234
 
<tr height='10'>\
1235
 
<td width='10' height='10' background='bbl.gif'></td><td colspan='%lu' height='10' background='bb.gif'></td><td width='10' height='10' background='bbr.gif'></td><td width='10' height='10' background='ls.gif'></td>\
1236
 
</tr>\
1237
 
<tr height='10'>\
1238
 
<td width='10' height='10' background='otrs.gif'></td>\
1239
 
<td colspan='%lu' height='10' background='ts.gif'></td>\
1240
 
<td width='10' height='10' background='otls.gif'></td>\
1241
 
</tr>\
1242
 
</table>", (unsigned long)num + 1, (unsigned long)num + 2);
1243
 
  return soap_send(soap, buf);
1244
 
}
1245
 
 
1246
 
/******************************************************************************\
1247
 
 *
1248
 
 *      OpenSSL
1249
 
 *
1250
 
\******************************************************************************/
1251
 
 
1252
 
#ifdef WITH_OPENSSL
1253
 
 
1254
 
struct CRYPTO_dynlock_value
1255
 
{ MUTEX_TYPE mutex;
1256
 
};
1257
 
 
1258
 
static MUTEX_TYPE *mutex_buf;
1259
 
 
1260
 
static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line)
1261
 
{ struct CRYPTO_dynlock_value *value;
1262
 
  value = (struct CRYPTO_dynlock_value*)malloc(sizeof(struct CRYPTO_dynlock_value));
1263
 
  if (value)
1264
 
    MUTEX_SETUP(value->mutex);
1265
 
  return value;
1266
 
}
1267
 
 
1268
 
static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
1269
 
{ if (mode & CRYPTO_LOCK)
1270
 
    MUTEX_LOCK(l->mutex);
1271
 
  else
1272
 
    MUTEX_UNLOCK(l->mutex);
1273
 
}
1274
 
 
1275
 
static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line)
1276
 
{ MUTEX_CLEANUP(l->mutex);
1277
 
  free(l);
1278
 
}
1279
 
 
1280
 
void locking_function(int mode, int n, const char *file, int line)
1281
 
{ if (mode & CRYPTO_LOCK)
1282
 
    MUTEX_LOCK(mutex_buf[n]);
1283
 
  else
1284
 
    MUTEX_UNLOCK(mutex_buf[n]);
1285
 
}
1286
 
 
1287
 
unsigned long id_function()
1288
 
{ return (unsigned long)THREAD_ID;
1289
 
}
1290
 
 
1291
 
int CRYPTO_thread_setup()
1292
 
{ int i;
1293
 
  mutex_buf = (MUTEX_TYPE*)malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
1294
 
  if (!mutex_buf)
1295
 
    return SOAP_EOM;
1296
 
  for (i = 0; i < CRYPTO_num_locks(); i++)
1297
 
    MUTEX_SETUP(mutex_buf[i]);
1298
 
  CRYPTO_set_id_callback(id_function);
1299
 
  CRYPTO_set_locking_callback(locking_function);
1300
 
  CRYPTO_set_dynlock_create_callback(dyn_create_function);
1301
 
  CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
1302
 
  CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
1303
 
  return SOAP_OK;
1304
 
}
1305
 
 
1306
 
void CRYPTO_thread_cleanup()
1307
 
{ int i;
1308
 
  if (!mutex_buf)
1309
 
    return;
1310
 
  CRYPTO_set_id_callback(NULL);
1311
 
  CRYPTO_set_locking_callback(NULL);
1312
 
  CRYPTO_set_dynlock_create_callback(NULL);
1313
 
  CRYPTO_set_dynlock_lock_callback(NULL);
1314
 
  CRYPTO_set_dynlock_destroy_callback(NULL);
1315
 
  for (i = 0; i < CRYPTO_num_locks(); i++)
1316
 
    MUTEX_CLEANUP(mutex_buf[i]);
1317
 
  free(mutex_buf);
1318
 
  mutex_buf = NULL;
1319
 
}
1320
 
 
1321
 
#endif
1322
 
 
1323
 
/******************************************************************************\
1324
 
 *
1325
 
 *      SIGPIPE
1326
 
 *
1327
 
\******************************************************************************/
1328
 
 
1329
 
void sigpipe_handle(int x) { }