source: trunk/gsdl/src/w32server/cgiwrapper.cpp@ 1011

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

tidied up w32server

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 21.5 KB
Line 
1#include <windows.h>
2#include <string.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <assert.h>
6#include <direct.h>
7#include "cgiwrapper.h"
8#include "netio.h"
9#include "wincgiutils.h"
10#include "settings.h"
11#include "fileutil.h"
12
13#include "gsdlconf.h"
14#include "recptconfig.h"
15
16#if defined (GSDL_USE_OBJECTSPACE)
17#include <ospace\std\iostream>
18#include <ospace\std\fstream>
19#elif defined (GSDL_USE_IOS_H)
20#include <iostream.h>
21#include <fstream.h>
22#else
23#include <iostream>
24#include <fstream>
25#endif
26
27#include "receptionist.h"
28#include "nullproto.h"
29#include "collectserver.h"
30#include "infodbclass.h"
31#include "mggdbmsource.h"
32
33// actions
34#include "action.h"
35#include "statusaction.h"
36#include "pageaction.h"
37#include "pingaction.h"
38#include "queryaction.h"
39#include "documentaction.h"
40#include "authenaction.h"
41#include "usersaction.h"
42#include "extlinkaction.h"
43//#include "buildaction.h"
44#include "delhistoryaction.h"
45
46// browsers
47#include "browserclass.h"
48#include "vlistbrowserclass.h"
49#include "hlistbrowserclass.h"
50#include "datelistbrowserclass.h"
51#include "invbrowserclass.h"
52#include "pagedbrowserclass.h"
53#include "htmlbrowserclass.h"
54
55// filters
56#include "filter.h"
57#include "browsefilter.h"
58#include "queryfilter.h"
59#include "phrasequeryfilter.h"
60
61// the number of times the library has been accessed
62int libaccessnum = 0;
63
64// used to output the text from receptionist
65class textstreambuf : public streambuf
66{
67public:
68 textstreambuf ();
69 int sync ();
70 int overflow (int ch);
71 int underflow () {return EOF;}
72
73 void tsbreset() {RInfo=NULL;casostr=NULL;}
74 void setrequestinfo (RequestInfoT *theRInfo) {RInfo=theRInfo;}
75 void cascadeoutput (ostream *thecasostr) {casostr=thecasostr;}
76
77private:
78 RequestInfoT *RInfo;
79 ostream *casostr;
80};
81
82textstreambuf::textstreambuf() {
83 tsbreset();
84 if (base() == ebuf()) allocate();
85 setp (base(), ebuf());
86};
87
88int textstreambuf::sync () {
89 if ((RInfo != NULL) &&
90 (Send_String_N(pbase(), out_waiting(), RInfo) < 0)) {
91 RInfo = NULL;
92 }
93
94 if (casostr != NULL) {
95 char *thepbase=pbase();
96 for (int i=0;i<out_waiting();i++) (*casostr).put(thepbase[i]);
97 }
98
99 setp (pbase(), epptr());
100
101 return 0;
102}
103
104int textstreambuf::overflow (int ch) {
105 if (sync () == EOF) return EOF;
106 if (ch != EOF) sputc (ch);
107 return 0;
108}
109
110
111// used to output all the log and error messages
112// from receptionist
113class logstreambuf : public streambuf
114{
115public:
116 logstreambuf ();
117 int sync ();
118 int overflow (int ch);
119 int underflow () {return EOF;}
120};
121
122logstreambuf::logstreambuf () {
123 if (base() == ebuf()) allocate();
124 setp (base(), ebuf());
125}
126
127int logstreambuf::sync () {
128 if (gsdl_keep_log || gsdl_show_console) {
129 log_message ("LOCAL LIB MESSAGE: ");
130 log_message_N (pbase(), out_waiting());
131 }
132
133 setp (pbase(), epptr());
134 return 0;
135}
136
137int logstreambuf::overflow (int ch) {
138 if (sync () == EOF) return EOF;
139 if (ch != EOF) sputc (ch);
140 return 0;
141}
142
143
144
145#ifndef MAX_FILENAME_SIZE
146#define MAX_FILENAME_SIZE 2048
147#endif
148
149
150receptionist recpt;
151nullproto nproto;
152textstreambuf textstream;
153logstreambuf logstream;
154DWORD lastlibaccesstime;
155DWORD baseavailvirtual;
156
157static void page_errorsitecfg (const text_t &gsdlhome, const text_t &collection) {
158
159 text_t message = "Error\n\n"
160 "The site.cfg configuration file could not be found. This file\n"
161 "should contain configuration information relating to this sites\n"
162 "setup.\n";
163
164 if (collection.empty()) {
165 message += "As this program is not being run in collection specific mode,\n"
166 "the file should reside at " + gsdlhome + "\\etc\\site.cfg.\n";
167 } else {
168 message += "As this program is being run in collection specific mode,\n"
169 "the file can reside at " + gsdlhome + "\\collect\\" + collection +
170 "\\etc\\site.cfg or " + gsdlhome + "\\etc\\site.cfg.\n";
171 }
172
173 MessageBox(NULL, message.getcstr(),
174 "Greenstone Digital Library Software"
175 ,MB_OK|MB_SYSTEMMODAL);
176}
177
178static void page_errormaincfg (const text_t &gsdlhome, const text_t &collection) {
179
180 if (collection.empty()) {
181 text_t message = "Error\n\n"
182 "The main.cfg configuration file could not be found. This file\n"
183 "should contain configuration information relating to the\n"
184 "setup of the interface. As this program is not being run\n"
185 "in collection specific mode the file should reside at\n" +
186 gsdlhome + "\\etc\\main.cfg.\n";
187
188 MessageBox(NULL, message.getcstr(),
189 "Greenstone Digital Library Software"
190 ,MB_OK|MB_SYSTEMMODAL);
191 } else {
192 text_t message = "Neither the collect.cfg or main.cfg configuration files could\n"
193 "be found. This file should contain configuration information\n"
194 "relating to the setup of the interface. As this cgi script is\n"
195 "being run in collection specific mode the file should reside\n"
196 "at either " + gsdlhome + "\\collect\\" + collection + "\\etc\\collect.cfg,\n" +
197 gsdlhome + "\\etc\\collect.cfg or " + gsdlhome + "\\etc\\main.cfg.\n";
198
199 MessageBox(NULL, message.getcstr(),
200 "Greenstone Digital Library Software"
201 ,MB_OK|MB_SYSTEMMODAL);
202 }
203}
204
205static void page_errorinit (const text_t &/*gsdlhome*/) {
206
207 text_t message = "Error\n\n"
208 "An error occurred during the initialisation of the Greenstone Digital\n"
209 "Library software. It is likely that the software has not been setup\n"
210 "correctly.\n";
211
212 MessageBox(NULL, message.getcstr(),
213 "Greenstone Digital Library Software"
214 ,MB_OK|MB_SYSTEMMODAL);
215}
216
217static void page_errorparseargs (const text_t &gsdlhome) {
218
219 text_t message = "Error\n\n"
220 "An error occurred during the parsing of the cgi arguments.\n";
221
222 MessageBox(NULL, message.getcstr(),
223 "Greenstone Digital Library Software"
224 ,MB_OK|MB_SYSTEMMODAL);
225}
226
227static void page_errorcgipage (const text_t &gsdlhome) {
228
229 text_t message = "Error\n\n"
230 "An error occurred during the construction of the cgi page.\n";
231
232 MessageBox(NULL, message.getcstr(),
233 "Greenstone Digital Library Software"
234 ,MB_OK|MB_SYSTEMMODAL);
235}
236
237// returns 0 if the directories can't be found
238// and the user wants to quit (it returns 1
239// if everything is ok)
240int checkdir (const text_t &thedir) {
241 UINT curerrormode;
242 int drive = _getdrive();
243 char cwd[1024];
244 char rootpath[4];
245 UINT drivetype;
246 char *cstrthedir = thedir.getcstr();
247 int returnvalue = 1;
248
249 // make sure no rude error messages are presented to the user
250 curerrormode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
251
252 // get the drive name
253 if (thedir.size() >= 2 && thedir[1] == ':') {
254 if (thedir[0] >= 'a' && thedir[0] <= 'z') {
255 drive = thedir[0] - 'a' + 1;
256
257 } else if (thedir[0] >= 'A' && thedir[0] <= 'Z') {
258 drive = thedir[0] - 'A' + 1;
259 }
260 }
261
262 // find the drive type
263 rootpath[0] = drive + 'A' - 1;
264 rootpath[1] = ':';
265 rootpath[2] = '\\';
266 rootpath[3] = '\0';
267 drivetype = GetDriveType (rootpath);
268
269 // try and set this directory to be the current working
270 // directory
271 _getcwd(cwd, 1024);
272 while (_chdir(cstrthedir) != 0) {
273 // failed
274 if (drivetype == DRIVE_CDROM) {
275 // message to insert the cdrom
276 if (MessageBox (NULL,
277 "Please insert the Greenstone Digital Library\n"
278 "CD-ROM into the CD-ROM drive and press 'OK'.\n\n"
279 "If you don't have the CD-ROM press 'Cancel' to exit\n"
280 "this program.", "Greenstone Digital Library Software",
281 MB_OKCANCEL | MB_TASKMODAL) == IDCANCEL) {
282
283 returnvalue = 0;
284 break;
285 }
286
287 } else {
288 // message saying that the system was unable
289 // to find a certain directory
290 text_t message = "Failed to find the directory:\n\n" + thedir;
291 message += "\n\n"
292 "This directory is needed for the successful operation\n"
293 "of this software. Make sure it hasn't been deleted or\n"
294 "moved, and restart the software. You may need to\n"
295 "reinstall this software to correct the problem.";
296 char *cstrmessage = message.getcstr();
297
298 MessageBox (NULL, cstrmessage, "Greenstone Digital Library Software",
299 MB_OK | MB_TASKMODAL);
300
301 delete cstrmessage;
302
303 returnvalue = 0;
304 break;
305 }
306 }
307
308 // revert to the previous error and cwd states
309 _chdir(cwd);
310 SetErrorMode(curerrormode);
311
312 // free the allocated C string
313 delete cstrthedir;
314
315 return returnvalue;
316}
317
318
319// c-string version of checkdir for the outside
320// world
321int cstrcheckdir (char *cstrthedir) {
322 return checkdir (cstrthedir);
323}
324
325
326// returns 1 if successful, 0 if unsuccessful
327int gsdl_init () {
328 cerr = &logstream;
329 cout = &textstream;
330
331 // collection should be set to "" unless in
332 // collection specific mode
333 text_t collection = "";
334 text_tset gsdlhomes;
335 text_tarray collections;
336 colinfo_tmap::const_iterator this_info = gsdl_collectinfo.begin();
337 colinfo_tmap::const_iterator end_info = gsdl_collectinfo.end();
338
339 // note the current time
340 lastlibaccesstime = GetTickCount();
341
342 // before we do the init we should make sure
343 // that we can find the relevant directories
344 if (!checkdir (gsdl_gsdlhome + "\\")) return 0;
345 if (!checkdir (gsdl_gsdlhome + "\\macros\\")) return 0;
346
347 if (collection.empty()) {
348
349 // get all collections from each gsdlhome (this relies
350 // on there not being more than one collection with the same
351 // name)
352 read_dir (filename_cat (gsdl_gsdlhome, "collect"), collections);
353 gsdlhomes.insert (gsdl_gsdlhome);
354 while (this_info != end_info) {
355 if (gsdlhomes.find ((*this_info).second.gsdl_gsdlhome) == gsdlhomes.end()) {
356 read_dir (filename_cat ((*this_info).second.gsdl_gsdlhome, "collect"), collections);
357 gsdlhomes.insert ((*this_info).second.gsdl_gsdlhome);
358 }
359 this_info ++;
360 }
361 } else {
362 collections.push_back (collection);
363 }
364
365 text_tarray::const_iterator thiscol = collections.begin();
366 text_tarray::const_iterator endcol = collections.end();
367
368 while (thiscol != endcol) {
369
370 // this memory is created but never destroyed
371 // we're also not doing any error checking to make sure we didn't
372 // run out of memory
373 collectserver *cserver = new collectserver();
374 gdbmclass *gdbmhandler = new gdbmclass();
375 mgsearchclass *mgsearch = new mgsearchclass();
376
377 // add a null filter
378 filterclass *filter = new filterclass();
379 cserver->add_filter (filter);
380
381 // add a browse filter
382 browsefilterclass *browsefilter = new browsefilterclass();
383 browsefilter->set_gdbmptr (gdbmhandler);
384 cserver->add_filter (browsefilter);
385
386 // add a query filter
387 queryfilterclass *queryfilter = new queryfilterclass();
388 queryfilter->set_gdbmptr (gdbmhandler);
389 queryfilter->set_mgsearchptr (mgsearch);
390 cserver->add_filter (queryfilter);
391
392 // add an mg and gdbm source
393 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass();
394 mggdbmsource->set_gdbmptr (gdbmhandler);
395 mggdbmsource->set_mgsearchptr (mgsearch);
396 cserver->add_source (mggdbmsource);
397
398 // inform collection server and everything it contains about
399 // its collection name
400 cserver->configure ("collection", *thiscol);
401
402 nproto.add_collectserver (cserver);
403
404 thiscol ++;
405 }
406
407 // add the protocol to the receptionist
408 recpt.add_protocol (&nproto);
409
410 // add other converters
411 utf8inconvertclass *utf8inconvert = new utf8inconvertclass();
412 utf8outconvertclass *utf8outconvert = new utf8outconvertclass();
413 recpt.add_converter ("u", utf8inconvert, utf8outconvert);
414
415 mapinconvertclass *gbinconvert = new mapinconvertclass();
416 gbinconvert->setmapfile (gsdl_gsdlhome, "gbku", 0x25a1);
417 mapoutconvertclass *gboutconvert = new mapoutconvertclass();
418 gboutconvert->setmapfile (gsdl_gsdlhome, "ugbk", 0xa1f5);
419 recpt.add_converter ("g", gbinconvert, gboutconvert);
420
421 // the list of actions.
422 statusaction *astatusaction = new statusaction();
423 astatusaction->set_receptionist (&recpt);
424 recpt.add_action (astatusaction);
425
426 pageaction *apageaction = new pageaction();
427 recpt.add_action (apageaction);
428
429 pingaction *apingaction = new pingaction();
430 recpt.add_action (apingaction);
431
432 queryaction *aqueryaction = new queryaction();
433 recpt.add_action (aqueryaction);
434
435 documentaction *adocumentaction = new documentaction();
436 recpt.add_action (adocumentaction);
437
438 usersaction *ausersaction = new usersaction();
439 recpt.add_action (ausersaction);
440
441 extlinkaction *anextlinkaction = new extlinkaction();
442 recpt.add_action (anextlinkaction);
443
444 // buildaction *abuildaction = new buildaction();
445 // abuildaction->set_receptionist (&recpt);
446 // recpt.add_action (abuildaction);
447
448 authenaction *aauthenaction = new authenaction();
449 aauthenaction->set_receptionist(&recpt);
450 recpt.add_action (aauthenaction);
451
452 delhistoryaction adelhistoryaction;
453 recpt.add_action(&adelhistoryaction);
454
455
456 // list of browsers
457 vlistbrowserclass *avlistbrowserclass = new vlistbrowserclass();
458 recpt.add_browser (avlistbrowserclass);
459 recpt.setdefaultbrowser ("VList");
460
461 hlistbrowserclass *ahlistbrowserclass = new hlistbrowserclass();
462 recpt.add_browser (ahlistbrowserclass);
463
464 datelistbrowserclass *adatelistbrowserclass = new datelistbrowserclass();
465 recpt.add_browser (adatelistbrowserclass);
466
467 invbrowserclass *ainvbrowserclass = new invbrowserclass();
468 recpt.add_browser (ainvbrowserclass);
469
470 pagedbrowserclass *apagedbrowserclass = new pagedbrowserclass();
471 recpt.add_browser (apagedbrowserclass);
472
473 htmlbrowserclass *ahtmlbrowserclass = new htmlbrowserclass();
474 recpt.add_browser (ahtmlbrowserclass);
475
476 // set defaults
477 recpt.configure ("gsdlhome", gsdl_gsdlhome);
478 recpt.configure ("collection", collection);
479
480 int maxrequests = 1;
481 text_tset seenhomes;
482 this_info = gsdl_collectinfo.begin();
483
484 // configure any collections with gsdlhome (or gdbmhome)
485 // different from the default
486 while (this_info != end_info) {
487 if (((*this_info).second.gsdl_gsdlhome != gsdl_gsdlhome) ||
488 ((*this_info).second.gsdl_gdbmhome != gsdl_gdbmhome) &&
489 (seenhomes.find ((*this_info).second.gsdl_gsdlhome +
490 (*this_info).second.gsdl_gdbmhome) == seenhomes.end())) {
491 text_tarray tmpconf;
492 tmpconf.push_back ((*this_info).first);
493 tmpconf.push_back ((*this_info).second.gsdl_gsdlhome);
494 tmpconf.push_back ((*this_info).second.gsdl_gdbmhome);
495 recpt.configure ("collectinfo", tmpconf);
496 seenhomes.insert ((*this_info).second.gsdl_gsdlhome +
497 (*this_info).second.gsdl_gdbmhome);
498 }
499 this_info ++;
500 }
501
502 // read in config files of each gsdlhome (in no particular order)
503 // those read in last will override those read earlier
504 // collections being used together in this way should be
505 // careful not to have site.cfg or main.cfg files that might
506 // screw with each other.
507 text_tset::const_iterator thome = gsdlhomes.begin();
508 text_tset::const_iterator ehome = gsdlhomes.end();
509 while (thome != ehome) {
510 // TODO: should only need to do this once now I think
511 // gsdlsite.cfg will need to be installed along with executable
512 // if (!site_cfg_read (recpt, *thome, maxrequests)) {
513 // couldn't find the site configuration file
514 // page_errorsitecfg (*thome, collection);
515 // return 0;
516 // } else
517 if (!main_cfg_read (recpt, *thome, collection)) {
518 // couldn't find the main configuration file
519 page_errormaincfg (*thome, collection);
520 return 0;
521 }
522 thome ++;
523 }
524
525 // w32server relies on gwcgi being set to "gw"
526 recpt.configure ("gwcgi", "gw");
527
528 // initialise the library software
529 if (!recpt.init(cerr)) {
530 // an error occurred during the initialisation
531 page_errorinit(gsdl_gsdlhome);
532 return 0;
533 }
534
535 // get memory information
536 MEMORYSTATUS memstatus;
537 memstatus.dwLength = sizeof(MEMORYSTATUS);
538 GlobalMemoryStatus(&memstatus);
539 baseavailvirtual = memstatus.dwAvailVirtual; // save for later comparison
540
541 return 1;
542}
543
544
545static void rememberpref (char *tailstr) {
546
547 // gsdl_enterlib = tailstr;
548}
549
550
551static void send_file_from_disk(char *filename,
552 RequestInfoT *RInfo,
553 RequestFieldsT *RFields)
554{
555 int len, nr; char *tail, *kind;
556 FILE *thefile;
557
558 // select appropriate mime type from file name
559 len = strlen(filename);
560 while (len > 0 && filename[len-1] != '.') len--;
561 kind = "unknown";
562 if (len > 0) {
563 tail = &filename[len];
564 if (stricmp("gif",tail) == 0) kind = "image/gif";
565 else if (stricmp("jpg",tail) == 0 ||
566 stricmp("jpeg",tail) == 0) kind = "image/jpeg";
567 else if (stricmp("htm",tail) == 0 ||
568 stricmp("html",tail) == 0) kind = "text/html";
569 }
570
571 // set up file name
572 text_t filenamet = text_t(gsdl_gsdlhome) + filename;
573 text_t::iterator here = filenamet.begin();
574 text_t::iterator end = filenamet.end();
575 while (here != end) {
576 if (*here == '/') *here = '\\';
577 here ++;
578 }
579
580 filename = filenamet.getcstr();
581
582 // try to open it
583 thefile = fopen(filename, "rb");
584 if (thefile == NULL) {
585 log_message("file not found\n");
586 send_retrieve_error(404, "File not found",
587 "Could not find the local file requested", RInfo);
588 return;
589 }
590
591 char buffer[2048];
592 // send back required information
593 if (send_header(kind, RInfo) >= 0) {
594 if (strcmpi(RFields->MethodStr, "HEAD") != 0) {
595 for (;;) {
596 nr = fread(buffer, 1, 2048, thefile);
597 if (nr <= 0) break;
598 if (SendData(RInfo->ClientSocket,
599 (BYTE *)buffer, nr,
600 RInfo->ThreadNum) < 0) break;
601 }
602 }
603 }
604 fclose(thefile);
605}
606
607static void handle_library_request(char *TailStr, RequestInfoT *RInfo,
608 RequestFieldsT *RequestFields) {
609 // check for a "?" at the start of the tail string
610 if (*TailStr == '?') TailStr++;
611
612 outconvertclass text_t2ascii;
613
614 // parse the cgi arguments and produce the resulting page if there
615 // has been no errors so far
616 cgiargsclass args;
617 text_tmap empty; // don't use this (it's for fastcgi on unix)
618 if (!recpt.parse_cgi_args (TailStr, args, cerr, empty)) {
619 page_errorparseargs(gsdl_gsdlhome);
620 return;
621 }
622
623 // produce cgi header
624 response_t response;
625 text_t response_data;
626
627 recpt.get_cgihead_info (args, response, response_data, cerr, empty);
628
629 if (response == location) {
630 // location response
631 response_data = "@" + recpt.expandmacros (response_data, args, cerr);
632 char *response_data_c = response_data.getcstr();
633 send_header(response_data_c, RInfo);
634 delete response_data_c;
635 return;
636 } else if (response == content) {
637 // content response
638 char *response_data_c = response_data.getcstr();
639 if (send_header(response_data_c, RInfo) < 0) {
640 delete response_data_c;
641 return;
642 }
643 delete response_data_c;
644 } else {
645 // unknown response
646 cerr << "Error: get_cgihead_info returned an unknown response type.\n";
647 return;
648 }
649
650 textstream.tsbreset();
651 textstream.setrequestinfo (RInfo);
652
653 if (!recpt.produce_content (args, cout, cerr)) {
654 page_errorcgipage(gsdl_gsdlhome);
655 return;
656 }
657 recpt.log_cgi_args (args, cerr, empty);
658
659 cout << flush;
660 cerr << flush;
661
662 libaccessnum++;
663}
664
665static void handle_server_request(char *initialTailStr,
666 RequestInfoT *RequestInfo,
667 RequestFieldsT *RequestFields) {
668 char tmpstr[1024];
669 char tailstr[MAX_URL_SIZE];
670
671 // do any url adjustments necessary
672 if (strcmp(initialTailStr, "/") == 0) {
673 strcpy (tailstr, "/cgi-bin/gw");
674 } else strcpy (tailstr, initialTailStr);
675
676 // test to see if this is a library request or a local
677 // file request
678 if ((strncmp(tailstr, "/cgi-bin/gw", 11) == 0) &&
679 ((tailstr[11] == '\0') || (tailstr[11] == '?'))) {
680 // library request
681
682 // log the difference in access times
683 DWORD thislibaccesstime = GetTickCount();
684 if (gsdl_keep_log||gsdl_show_console) {
685 sprintf(tmpstr, "DELTA LIB ACCESS TIME: %i\n", (int)(thislibaccesstime - lastlibaccesstime));
686 log_message (tmpstr);
687 }
688 lastlibaccesstime = thislibaccesstime;
689
690 // log this request
691 if (gsdl_keep_log||gsdl_show_console) {
692 sprintf (tmpstr, "LOCAL LIB: %s\n", tailstr);
693 log_message (tmpstr);
694 }
695
696 handle_library_request (&tailstr[11], RequestInfo, RequestFields);
697
698 // remember the preferences
699 rememberpref (tailstr);
700
701 // log memory information
702 if (gsdl_keep_log||gsdl_show_console) {
703 MEMORYSTATUS memstatus;
704 memstatus.dwLength = sizeof(MEMORYSTATUS);
705 GlobalMemoryStatus(&memstatus);
706 sprintf (tmpstr, "BDELTA AVAIL VIRTUAL: %i K\n",
707 (int)((baseavailvirtual - memstatus.dwAvailVirtual)/1024));
708 log_message (tmpstr);
709 }
710
711 } else {
712 // local file
713 if (gsdl_keep_log||gsdl_show_console) {
714 sprintf (tmpstr, "LOCAL FILE: %s\n", tailstr);
715 log_message (tmpstr);
716 }
717 send_file_from_disk (tailstr, RequestInfo, RequestFields);
718 }
719}
720
721static void fix_prefix(char *dest, char *pref, char *suff)
722{
723 strcpy(dest,pref);
724 if (*suff != '/') strcat(dest,"/");
725 if (strlen(dest) + strlen(suff) + 1 > MAX_URL_SIZE)
726 strcpy(dest,"http://gsdl/name-too-long");
727 else
728 strcat(dest,suff);
729}
730
731int ExamineURIStr(char *URIStr,RequestInfoT *RequestInfo,
732 RequestFieldsT *RequestFields)
733{
734 char *protocol, *machine, *rest; int port;
735 char URICopyA[MAX_URL_SIZE], URICopyB[MAX_URL_SIZE];
736 strcpy(URICopyA,URIStr);
737
738 if (parse_url(URICopyA,&protocol,&machine,&port,&rest)!=http_ok) {
739 /* Alter local file request to address 'gsdl' */
740 fix_prefix(URICopyB, "http://gsdl", URIStr);
741 URIStr = URICopyB;
742 strcpy(URICopyA, URICopyB);
743 parse_url(URICopyA,&protocol,&machine,&port,&rest);
744 }
745
746 if (strncmp(machine, "gsdl", 5) == 0) {
747 // a local file request
748 handle_server_request(rest, RequestInfo, RequestFields);
749
750 } else {
751 send_retrieve_error(404, "File not found",
752 "Could not find the local file requested", RequestInfo);
753 }
754
755 return 1;
756}
Note: See TracBrowser for help on using the repository browser.