source: branches/New_Config_Format-branch/gsdl/src/recpt/cgiwrapper.cpp@ 1279

Last change on this file since 1279 was 1279, checked in by sjboddie, 24 years ago

merged changes to trunk into New_Config_Format branch

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 24.3 KB
Line 
1/**********************************************************************
2 *
3 * cgiwrapper.cpp -- output pages using the cgi protocol
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * $Id: cgiwrapper.cpp 1279 2000-07-12 22:21:53Z sjboddie $
25 *
26 *********************************************************************/
27
28/*
29 $Log$
30 Revision 1.22.4.1 2000/07/12 22:21:35 sjboddie
31 merged changes to trunk into New_Config_Format branch
32
33 Revision 1.31 2000/07/12 04:51:05 nzdl
34 added an error message when no "valid" collections are available
35
36 Revision 1.30 2000/07/05 21:49:31 sjboddie
37 Receptionist now caches collection information to avoid making multiple
38 get_collectinfo calls to collection server
39
40 Revision 1.29 2000/06/29 03:57:14 sjboddie
41 Now append to error log (errout.txt) instead of overwriting it each time
42
43 Revision 1.28 2000/06/28 01:30:23 nzdl
44 *** empty log message ***
45
46 Revision 1.27 2000/06/28 01:24:59 sjboddie
47 got "POST" cgi data to work when using fastcgi
48
49 Revision 1.26 2000/05/12 03:09:26 sjboddie
50 minor modifications to get web library compiling under VC++ 6.0
51
52 Revision 1.25 2000/04/14 04:45:19 sjboddie
53 Modified the English of the debug output slightly
54
55 Revision 1.24 2000/04/14 03:10:35 sjboddie
56 tidied up a few issues concerning the new debug info which showed
57 up on windows
58
59 Revision 1.23 2000/04/14 02:52:05 sjboddie
60 tidied up error messaging and set up some debugging info to be output
61 when running library from command line
62
63 Revision 1.22 2000/02/21 21:56:46 sjboddie
64 gsdlhome now comes from gsdlsite.cfg
65
66 Revision 1.21 2000/01/25 22:45:59 sjboddie
67 few changes to get fastcgi to work properly
68
69 Revision 1.20 1999/09/07 04:56:53 sjboddie
70 added GPL notice
71
72 Revision 1.19 1999/09/02 00:24:36 rjmcnab
73 fixed bug in getting POST arguments
74
75 Revision 1.18 1999/08/20 01:02:07 sjboddie
76 added some usage logging
77
78 Revision 1.17 1999/07/15 06:03:15 rjmcnab
79 Moved the adding of the actions to librarymain so that they can be
80 overriden easily.
81
82 Revision 1.16 1999/07/14 08:31:05 rjmcnab
83 Fixed a small bug in the POST implementation.
84
85 Revision 1.15 1999/07/13 23:32:17 rjmcnab
86 Added authenaction and usersaction
87
88 Revision 1.14 1999/07/11 01:03:37 rjmcnab
89 Added ability to receive POST cgi form data.
90
91 Revision 1.13 1999/06/24 05:12:18 sjboddie
92 lots of small changes
93
94 Revision 1.12 1999/04/30 01:59:40 sjboddie
95 lots of stuff - getting documentaction working (documentaction replaces
96 old browseaction)
97
98 Revision 1.11 1999/03/25 03:12:01 sjboddie
99
100 subjectbrowseaction was replaced with browseaction
101
102 Revision 1.10 1999/03/05 03:53:54 sjboddie
103
104 fixed some bugs
105
106 Revision 1.9 1999/03/04 22:38:21 sjboddie
107
108 Added subjectbrowseaction. - Doesn't do anything yet.
109
110 Revision 1.8 1999/02/28 20:00:13 rjmcnab
111
112
113 Fixed a few things.
114
115 Revision 1.7 1999/02/21 22:33:53 rjmcnab
116
117 Lots of stuff :-)
118
119 Revision 1.6 1999/02/12 02:40:17 sjboddie
120
121 Added page action
122
123 Revision 1.5 1999/02/11 01:24:04 rjmcnab
124
125 Fixed a few compiler warnings.
126
127 Revision 1.4 1999/02/08 01:28:01 rjmcnab
128
129 Got the receptionist producing something using the statusaction.
130
131 Revision 1.3 1999/02/05 10:42:44 rjmcnab
132
133 Continued working on receptionist
134
135 Revision 1.2 1999/02/04 10:00:56 rjmcnab
136
137 Developed the idea of an "action" and having them define the cgi arguments
138 which they need and how those cgi arguments function.
139
140 Revision 1.1 1999/02/04 01:16:17 rjmcnab
141
142 Initial revision.
143
144 Revision 1.5 1999/01/19 01:38:18 rjmcnab
145
146 Made the source more portable.
147
148 Revision 1.4 1999/01/12 01:51:04 rjmcnab
149
150 Standard header.
151
152 */
153
154
155#include "gsdlconf.h"
156#include "cgiwrapper.h"
157#include "recptconfig.h"
158#include "fileutil.h"
159#include <stdlib.h>
160#include <assert.h>
161
162#if defined(GSDL_USE_OBJECTSPACE)
163# include <ospace/std/iostream>
164# include <ospace/std/fstream>
165#elif defined(GSDL_USE_IOS_H)
166# include <iostream.h>
167# include <fstream.h>
168#else
169# include <iostream>
170# include <fstream>
171#endif
172
173#ifdef USE_FASTCGI
174#include "fcgiapp.h"
175#endif
176
177
178#ifdef USE_FASTCGI
179// used to output the text from receptionist
180class fcgistreambuf : public streambuf {
181public:
182 fcgistreambuf ();
183 int sync ();
184 int overflow (int ch);
185 int underflow () {return EOF;}
186
187 void fcgisbreset() {fcgx_stream = NULL; other_ostream = NULL;};
188 void set_fcgx_stream(FCGX_Stream *newone) {fcgx_stream=newone;};
189 void set_other_ostream(ostream *newone) {other_ostream=newone;};
190
191private:
192 FCGX_Stream *fcgx_stream;
193 ostream *other_ostream;
194};
195
196fcgistreambuf::fcgistreambuf() {
197 fcgisbreset();
198 if (base() == ebuf()) allocate();
199 setp (base(), ebuf());
200};
201
202int fcgistreambuf::sync () {
203 if ((fcgx_stream != NULL) &&
204 (FCGX_PutStr (pbase(), out_waiting(), fcgx_stream) < 0)) {
205 fcgx_stream = NULL;
206 }
207
208 if (other_ostream != NULL) {
209 char *thepbase=pbase();
210 for (int i=0;i<out_waiting();i++) (*other_ostream).put(thepbase[i]);
211 }
212
213 setp (pbase(), epptr());
214
215 return 0;
216}
217
218int fcgistreambuf::overflow (int ch) {
219 if (sync () == EOF) return EOF;
220 if (ch != EOF) sputc (ch);
221 return 0;
222}
223
224#endif
225
226static void format_error_string (text_t &errorpage, const text_t &errortext, bool debug) {
227
228 errorpage.clear();
229
230 if (debug) {
231 errorpage += "\n";
232 errorpage += "ERROR: " + errortext;
233 errorpage += "\n";
234
235 } else {
236
237 errorpage += "Content-type: text/html\n\n";
238
239 errorpage += "<html>\n";
240 errorpage += "<head>\n";
241 errorpage += "<title>Error</title>\n";
242 errorpage += "</head>\n";
243 errorpage += "<body>\n";
244 errorpage += "<h2>Oops!</h2>\n";
245 errorpage += errortext;
246 errorpage += "</body>\n";
247 errorpage += "</html>\n";
248 }
249}
250
251static void page_errorcollect (const text_t &gsdlhome, text_t &errorpage, bool debug) {
252
253 text_t collectdir = filename_cat (gsdlhome, "collect");
254
255 text_t errortext = "No valid collections were found: Check that your collect directory\n";
256 errortext += "(" + collectdir + ") is readable and contains at least one valid collection.\n";
257 errortext += "Note that modelcol is NOT a valid collection.\n";
258 errortext += "If the path to your collect directory is wrong edit the 'gsdlhome' field\n";
259 errortext += "in your gsdlsite.cfg configuration file.\n";
260
261 format_error_string (errorpage, errortext, debug);
262}
263
264static void page_errorsitecfg (text_t &errorpage, bool debug, int mode) {
265
266 text_t errortext;
267
268 if (mode == 0) {
269 errortext += "The gsdlsite.cfg configuration file could not be found. This\n";
270 errortext += "file should contain configuration information relating to this\n";
271 errortext += "site's setup.\n";
272
273 } else if (mode == 1) {
274 errortext += "The gsdlsite.cfg configuration file does not contain a valid\n";
275 errortext += "gsdlhome entry.\n";
276 }
277
278 if (debug) {
279 errortext += "gsdlsite.cfg should reside in the directory from which the\n";
280 errortext += "library executable was run.\n";
281 } else {
282 errortext += "gsdlsite.cfg should reside in the same directory as the library\n";
283 errortext += "executable file.\n";
284 }
285
286 format_error_string (errorpage, errortext, debug);
287}
288
289
290static void page_errormaincfg (const text_t &gsdlhome, const text_t &collection,
291 bool debug, text_t &errorpage) {
292
293 text_t errortext;
294
295 if (collection.empty()) {
296 text_t main_cfg_file = filename_cat (gsdlhome, "etc", "main.cfg");
297 errortext += "The main.cfg configuration file could not be found. This file\n";
298 errortext += "should contain configuration information relating to the\n";
299 errortext += "setup of the interface. As this receptionist is not being run\n";
300 errortext += "in collection specific mode the file should reside at\n";
301 errortext += main_cfg_file + ".\n";
302 } else {
303 text_t collect_cfg_file = filename_cat (gsdlhome, "collect", collection, "etc", "collect.cfg");
304 text_t main_collect_cfg_file = filename_cat (gsdlhome, "etc", "collect.cfg");
305 text_t main_cfg_file = filename_cat (gsdlhome, "etc", "main.cfg");
306 errortext += "Either the collect.cfg or main.cfg configuration file could\n";
307 errortext += "not be found. This file should contain configuration information\n";
308 errortext += "relating to the setup of the interface. As this receptionist is\n";
309 errortext += "being run in collection specific mode the file should reside\n";
310 errortext += "at either " + collect_cfg_file + ",\n";
311 errortext += main_collect_cfg_file + " or " + main_cfg_file + ".\n";
312 }
313
314 format_error_string (errorpage, errortext, debug);
315}
316
317
318static void page_errorinit (const text_t &gsdlhome, bool debug, text_t &errorpage) {
319
320 text_t errortext = "An error occurred during the initialisation of the Greenstone Digital\n";
321 errortext += "Library software. It is likely that the software has not been setup\n";
322 errortext += "correctly.\n";
323
324 text_t init_file = filename_cat (gsdlhome, "etc", "initout.txt");
325 char *ifile = init_file.getcstr();
326 ifstream initin (ifile);
327 delete ifile;
328 if (initin) {
329 errortext += "The initialisation error log, " + init_file + ", contains the\n";
330 errortext += "following information:\n\n";
331 if (!debug) errortext += "<pre>\n";
332
333 char c;
334 initin.get(c);
335 while (!initin.eof ()) {
336 errortext.push_back(c);
337 initin.get(c);
338 }
339
340 if (!debug) errortext += "</pre>\n";
341
342 initin.close();
343
344 } else {
345 errortext += "Please consult " + init_file + " for more information.\n";
346 }
347
348 format_error_string (errorpage, errortext, debug);
349}
350
351static void page_errorparseargs (const text_t &gsdlhome, bool debug, text_t &errorpage) {
352
353 text_t errortext = "An error occurred during the parsing of the cgi arguments.\n";
354
355 text_t error_file = filename_cat (gsdlhome, "etc", "errout.txt");
356 char *efile = error_file.getcstr();
357 ifstream errin (efile);
358 delete efile;
359 if (errin) {
360 errortext += "The error log, " + error_file + ", contains the\n";
361 errortext += "following information:\n\n";
362 if (!debug) errortext += "<pre>\n";
363
364 char c;
365 errin.get(c);
366 while (!errin.eof ()) {
367 errortext.push_back(c);
368 errin.get(c);
369 }
370 if (!debug) errortext += "</pre>\n";
371 errin.close();
372
373 } else {
374 errortext += "Please consult " + error_file + " for more information.\n";
375 }
376
377 format_error_string (errorpage, errortext, debug);
378}
379
380static void page_errorcgipage (const text_t &gsdlhome, bool debug, text_t &errorpage) {
381
382 text_t errortext = "An error occurred during the construction of the cgi page.\n";
383
384 text_t error_file = filename_cat (gsdlhome, "etc", "errout.txt");
385 char *efile = error_file.getcstr();
386 ifstream errin (efile);
387 delete efile;
388 if (errin) {
389 errortext += "The error log, " + error_file + ", contains the\n";
390 errortext += "following information:\n\n";
391 if (!debug) errortext += "<pre>\n";
392
393 char c;
394 errin.get(c);
395 while (!errin.eof ()) {
396 errortext.push_back(c);
397 errin.get(c);
398 }
399 if (!debug) errortext += "</pre>\n";
400 errin.close();
401
402 } else {
403 errortext += "Please consult " + error_file + " for more information.\n";
404 }
405
406 format_error_string (errorpage, errortext, debug);
407}
408
409static void print_debug_info (receptionist &recpt) {
410
411 outconvertclass text_t2ascii;
412 recptconf configinfo = recpt.get_configinfo ();
413 text_t etc_dir = filename_cat (configinfo.gsdlhome, "etc");
414
415 cout << "\n";
416 cout << text_t2ascii
417 << "------------------------------------------------------------\n"
418 << "Configuration and initialization completed successfully.\n"
419 << " Note that more debug information may be available in the\n"
420 << " initialization and error logs initout.txt and errout.txt\n"
421 << " in " << etc_dir << ".\n"
422 << "------------------------------------------------------------\n\n";
423
424 bool colspec = false;
425 if (configinfo.collection.empty()) {
426 cout << "Receptionist is running in \"general\" (i.e. not \"collection\n"
427 << "specific\") mode.\n";
428 } else {
429 cout << text_t2ascii
430 << "Receptionist is running in \"collection specific\" mode.\n"
431 << " collection=" << configinfo.collection << "\n"
432 << " collection directory=" << configinfo.collectdir << "\n";
433 colspec = true;
434 }
435
436 cout << text_t2ascii << "gsdlhome=" << configinfo.gsdlhome << "\n";
437 if (!configinfo.gdbmhome.empty())
438 cout << text_t2ascii << "gdbmhome=" << configinfo.gdbmhome << "\n";
439 cout << text_t2ascii << "httpprefix=" << configinfo.httpprefix << "\n";
440 cout << text_t2ascii << "httpimg=" << configinfo.httpimg << "\n";
441 cout << text_t2ascii << "gwcgi=" << configinfo.gwcgi << "\n"
442 << " Note that unless gwcgi has been set from a configuration\n"
443 << " file it is dependent on environment variables set by your\n"
444 << " webserver. Therefore it may not have the same value when run\n"
445 << " from the command line as it would be when run from your\n"
446 << " web server.\n";
447 if (configinfo.usecookies)
448 cout << "cookies are enabled\n";
449 else
450 cout << "cookies are disabled\n";
451 if (configinfo.logcgiargs)
452 cout << "logging is enabled\n";
453 else
454 cout << "logging is disabled\n";
455 cout << "------------------------------------------------------------\n\n";
456
457 text_tset::const_iterator this_mfile = configinfo.macrofiles.begin();
458 text_tset::const_iterator end_mfile = configinfo.macrofiles.end();
459 cout << "Macro Files:\n"
460 << "------------\n";
461 text_t mfile;
462 bool found;
463 while (this_mfile != end_mfile) {
464 cout << text_t2ascii << *this_mfile;
465 int spaces = (22 - (*this_mfile).size());
466 if (spaces < 2) spaces = 2;
467 text_t outspaces;
468 for (int i = 0; i < spaces; i++) outspaces.push_back (' ');
469 cout << text_t2ascii << outspaces;
470
471 found = false;
472 if (colspec) {
473 // collection specific - try collectdir/macros first
474 mfile = filename_cat (configinfo.collectdir, "macros", *this_mfile);
475 if (file_exists (mfile)) {
476 cout << text_t2ascii << "found (" << mfile << ")\n";
477 found = true;
478 }
479 }
480
481 if (!found) {
482 // try main macro directory
483 mfile = filename_cat (configinfo.gsdlhome, "macros", *this_mfile);
484 if (file_exists (mfile)) {
485 cout << text_t2ascii << "found (" << mfile << ")\n";
486 found = true;
487 }
488 }
489
490 if (!found)
491 cout << text_t2ascii << "NOT FOUND\n";
492
493 this_mfile ++;
494 }
495
496 cout << "------------------------------------------------------------\n\n"
497 << "Collections:\n"
498 << "------------\n"
499 << " Note that collections will only appear as \"running\" if\n"
500 << " their build.cfg files exist, are readable, contain a valid\n"
501 << " builddate field (i.e. > 0), and are in the collection's\n"
502 << " index directory (i.e. NOT the building directory)\n\n";
503
504 recptprotolistclass *protos = recpt.get_recptprotolist_ptr();
505 recptprotolistclass::iterator rprotolist_here = protos->begin();
506 recptprotolistclass::iterator rprotolist_end = protos->end();
507 bool found_valid_col = false;
508 while (rprotolist_here != rprotolist_end) {
509 if ((*rprotolist_here).p != NULL) {
510
511 text_tarray collist;
512 comerror_t err;
513 (*rprotolist_here).p->get_collection_list (collist, err, cerr);
514 if (err == noError) {
515 text_tarray::iterator collist_here = collist.begin();
516 text_tarray::iterator collist_end = collist.end();
517
518 while (collist_here != collist_end) {
519
520 cout << text_t2ascii << *collist_here;
521
522 int spaces = (22 - (*collist_here).size());
523 if (spaces < 2) spaces = 2;
524 text_t outspaces;
525 for (int i = 0; i < spaces; i++) outspaces.push_back (' ');
526 cout << text_t2ascii << outspaces;
527
528 ColInfoResponse_t *cinfo = recpt.get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, cerr);
529 if (cinfo != NULL) {
530 if (cinfo->isPublic) cout << "public ";
531 else cout << "private";
532
533 if (cinfo->buildDate > 0) {
534 cout << " running ";
535 found_valid_col = true;
536 } else {
537 cout << " not running";
538 }
539 }
540
541 cout << "\n";
542
543 collist_here ++;
544 }
545 }
546 }
547 rprotolist_here ++;
548 }
549
550 if (!found_valid_col) {
551 cout << "WARNING: No \"running\" collections were found. You need to\n";
552 cout << " build one of the above collections\n";
553 }
554
555 cout << "\n------------------------------------------------------------\n";
556 cout << "------------------------------------------------------------\n\n";
557 cout << "receptionist running in command line debug mode\n";
558 cout << "enter cgi arguments as name=value pairs (e.g. 'a=p&p=home'):\n";
559
560}
561
562// cgiwrapper does everything necessary to output a page
563// using the cgi protocol. If this is being run for a particular
564// collection then "collection" should be set, otherwise it
565// should equal "".
566void cgiwrapper (receptionist &recpt, text_t collection) {
567
568 int numrequests = 0;
569 bool debug = false;
570 recptconf configinfo = recpt.get_configinfo ();
571
572 // find out whether this is being run as a cgi-script
573 // or a fastcgi script
574#ifdef USE_FASTCGI
575 fcgistreambuf outbuf;
576 int isfastcgi = !FCGX_IsCGI();
577 FCGX_Stream *fcgiin, *fcgiout, *fcgierr;
578 FCGX_ParamArray fcgienvp;
579#else
580 int isfastcgi = 0;
581#endif
582
583 // get the query string if it is not being run as a fastcgi
584 // script
585 text_t argstr = "";
586 cgiargsclass args;
587 char *aURIStr;
588 if (!isfastcgi) {
589 char *request_method_str = getenv("REQUEST_METHOD");
590 char *content_length_str = getenv("CONTENT_LENGTH");
591 if (request_method_str != NULL && strcmp(request_method_str, "POST") == 0 &&
592 content_length_str != NULL) {
593 // POST form data
594 int content_length = text_t(content_length_str).getint();
595 if (content_length > 0) {
596 char c;
597 do {
598 cin.get(c);
599 if (cin.eof()) break;
600 argstr.push_back (c);
601 content_length--;
602 } while (content_length > 0);
603 }
604
605 } else {
606 aURIStr = getenv("QUERY_STRING");
607 if ((request_method_str != NULL && strcmp(request_method_str, "GET") == 0)
608 || aURIStr != NULL) {
609 // GET form data
610 if (aURIStr != NULL) argstr = aURIStr;
611 } else {
612 // debugging from command line
613 debug = true;
614 }
615 }
616 }
617
618 if (debug) {
619 cout << "Configuring Greenstone...\n";
620 cout << flush;
621 }
622
623 // init stuff - we can't output error pages directly with
624 // fastcgi so the pages are stored until we can output them
625 text_t errorpage;
626 outconvertclass text_t2ascii;
627
628 // set defaults
629 int maxrequests = 10000;
630 recpt.configure ("collection", collection);
631 recpt.configure ("httpimg", "/gsdl/images");
632 char *script_name = getenv("SCRIPT_NAME");
633 if (script_name != NULL) recpt.configure("gwcgi", script_name);
634 else recpt.configure("gwcgi", "/cgi-bin/gw");
635
636 // read in the configuration files.
637 text_t gsdlhome;
638 if (!site_cfg_read (recpt, gsdlhome, maxrequests)) {
639 // couldn't find the site configuration file
640 page_errorsitecfg (errorpage, debug, 0);
641 } else if (gsdlhome.empty()) {
642 // no gsdlhome in gsdlsite.cfg
643 page_errorsitecfg (errorpage, debug, 1);
644 } else if (!main_cfg_read (recpt, gsdlhome, collection)) {
645 // couldn't find the main configuration file
646 page_errormaincfg (gsdlhome, collection, debug, errorpage);
647 } else if (configinfo.collectinfo.empty()) {
648 // don't have any collections
649 page_errorcollect (gsdlhome, errorpage, debug);
650 }
651
652 if (errorpage.empty()) {
653
654 // initialise the library software
655 if (debug) {
656 cout << "Initializing...\n";
657 cout << flush;
658 }
659
660 text_t init_file = filename_cat (gsdlhome, "etc", "initout.txt");
661 char *iout = init_file.getcstr();
662 ofstream initout (iout);
663 delete iout;
664 if (!recpt.init(initout)) {
665 // an error occurred during the initialisation
666 initout.close();
667 page_errorinit(gsdlhome, debug, errorpage);
668 }
669 initout.close();
670 }
671
672 if (debug && errorpage.empty()) {
673 // get query string from command line
674 print_debug_info (recpt);
675 char cinURIStr[1024];
676 cin.get(cinURIStr, 1024);
677 argstr = cinURIStr;
678 }
679
680 // cgi scripts only deal with one request
681 if (!isfastcgi) maxrequests = 1;
682
683 // Page-request loop. If this is not being run as a fastcgi
684 // process then only one request will be processed and then
685 // the process will exit.
686 while (numrequests < maxrequests) {
687#ifdef USE_FASTCGI
688 if (isfastcgi) {
689 if (FCGX_Accept(&fcgiin, &fcgiout, &fcgierr, &fcgienvp) < 0) break;
690
691 char *request_method_str = FCGX_GetParam ("REQUEST_METHOD", fcgienvp);
692 char *content_length_str = FCGX_GetParam ("CONTENT_LENGTH", fcgienvp);
693
694 if (request_method_str != NULL && strcmp(request_method_str, "POST") == 0 &&
695 content_length_str != NULL) {
696 // POST form data
697 int content_length = text_t(content_length_str).getint();
698 if (content_length > 0) {
699 argstr.clear();
700 int c;
701 do {
702 c = FCGX_GetChar (fcgiin);
703 if (c < 0) break;
704 argstr.push_back (c);
705 content_length--;
706 } while (content_length > 0);
707 }
708
709 } else {
710 // GET form data
711 aURIStr = FCGX_GetParam("QUERY_STRING", fcgienvp);
712 if (aURIStr != NULL) argstr = aURIStr;
713 else argstr = "";
714 }
715 }
716#endif
717
718 // get output streams ready
719#ifdef USE_FASTCGI
720 outbuf.fcgisbreset ();
721 if (isfastcgi) outbuf.set_fcgx_stream (fcgiout);
722 else outbuf.set_other_ostream (&cout);
723 ostream pageout (&outbuf);
724#else
725#define pageout cout
726#endif
727
728 // if using fastcgi we'll load environment into a map,
729 // otherwise simply pass empty map (can't get environment
730 // variables using getenv() while using FCGX versions
731 // of fastcgi - at least I can't ;-) - Stefan)
732 text_tmap fastcgienv;
733#ifdef USE_FASTCGI
734 if (isfastcgi) {
735 for(; *fcgienvp != NULL; fcgienvp++) {
736 text_t fvalue = *fcgienvp;
737 text_t::const_iterator begin = fvalue.begin();
738 text_t::const_iterator end = fvalue.end();
739 text_t::const_iterator equals_sign = findchar (begin, end, '=');
740 if (equals_sign != end)
741 fastcgienv[substr(begin, equals_sign)] = substr(equals_sign+1, end);
742 }
743 }
744#endif
745
746 // temporarily need to configure gwcgi here when using fastcgi as I can't
747 // get it to pass the SCRIPT_NAME environment variable to the initial
748 // environment (if anyone can work out how to do this using the apache
749 // server, let me know). Note that this overrides the gwcgi field in
750 // site.cfg (which it shouldn't do) but I can't at present set gwcgi
751 // from site.cfg as I have old receptionists laying around that wouldn't
752 // appreciate it. The following 5 lines of code should be deleted once
753 // I either a: get the server to pass SCRIPT_NAME at initialization
754 // time or b: convert all the collections using old receptionists over
755 // to this version and uncomment gwcgi in the site.cfg file -- Stefan.
756#ifdef USE_FASTCGI
757 if (isfastcgi) {
758 recpt.configure("gwcgi", fastcgienv["SCRIPT_NAME"]);
759 }
760#endif
761
762
763 if (errorpage.empty()) {
764 text_t error_file = filename_cat (gsdlhome, "etc", "errout.txt");
765 char *eout = error_file.getcstr();
766 ofstream errout (eout, ios::app);
767 delete eout;
768 cerr = errout;
769
770 // parse the cgi arguments and produce the resulting page if there
771 // has been no errors so far
772 if (!recpt.parse_cgi_args (argstr, args, errout, fastcgienv)) {
773 errout.close ();
774 page_errorparseargs(gsdlhome, debug, errorpage);
775 } else {
776 if (!recpt.produce_cgi_page (args, pageout, errout, fastcgienv)) {
777 errout.close ();
778 page_errorcgipage(gsdlhome, debug, errorpage);
779 }
780 recpt.log_cgi_args (args, errout, fastcgienv);
781 errout.close ();
782 }
783 }
784 // there was an error, output the error page
785 if (!errorpage.empty()) {
786 pageout << text_t2ascii << errorpage;
787 errorpage.clear();
788 numrequests = maxrequests; // make this the last page
789 }
790 pageout << flush;
791
792 // finish with the output streams
793#ifdef USE_FASTCGI
794 if (isfastcgi) FCGX_Finish();
795#endif
796
797 numrequests++;
798 }
799
800 return;
801}
802
Note: See TracBrowser for help on using the repository browser.