Annotation of Amaya/amaya/query.c, revision 1.186
1.14 cvs 1: /*
2: *
3: * (c) COPYRIGHT MIT and INRIA, 1996.
4: * Please first read the full copyright statement in file COPYRIGHT.
1.156 cvs 5: *
1.14 cvs 6: */
1.4 cvs 7:
1.19 cvs 8: /*
1.83 cvs 9: * query.c : contains all the functions for requesting and publishing
1.19 cvs 10: * URLs via libwww. It handles any eventual HTTP error code
11: * (redirection, authentication needed, not found, etc.)
12: *
1.69 cvs 13: * Author: J. Kahan
1.92 cvs 14: * J. Kahan/R. Guetari Windows 95/NT routines
1.19 cvs 15: */
1.17 cvs 16:
1.44 cvs 17: #ifndef AMAYA_JAVA
18:
1.116 cvs 19: /* defines to include elsewhere
20: *********************************/
21:
1.185 cvs 22: #ifdef _WINDOWS
23: #include <string.h>
1.130 cvs 24: #endif /* !_WINDOWS */
1.116 cvs 25: #define AMAYA_WWW_CACHE
1.168 cvs 26: #define AMAYA_LOST_UPDATE
1.116 cvs 27:
1.185 cvs 28: #define CACHE_DIR_NAME DIR_STR"libwww-cache"DIR_STR
1.176 cvs 29: #define DEFAULT_CACHE_SIZE 10
30: #define DEFAULT_MAX_CACHE_ENTRY_SIZE 3
1.177 cvs 31: #define DEFAULT_MAX_SOCKET 32
1.176 cvs 32: #define DEFAULT_DNS_TIMEOUT 1800L
1.151 cvs 33: #define DEFAULT_PERSIST_TIMEOUT 60L
1.165 cvs 34: #define DEFAULT_NET_EVENT_TIMEOUT 60000
1.116 cvs 35:
1.12 cvs 36: /* Amaya includes */
1.25 cvs 37: #define THOT_EXPORT extern
1.4 cvs 38: #include "amaya.h"
1.130 cvs 39: #include <sys/types.h>
1.70 cvs 40: #include <fcntl.h>
1.140 cvs 41: #include "HTEvtLst.h"
1.157 cvs 42: #include "HTAABrow.h"
1.7 cvs 43:
1.141 cvs 44: #if defined(__svr4__) || defined (_AIX)
1.4 cvs 45: #define CATCH_SIG
46: #endif
47:
48: /* local structures coming from libwww and which are
1.17 cvs 49: not found in any .h file
1.7 cvs 50: */
1.68 cvs 51:
1.7 cvs 52: struct _HTStream
53: {
1.15 cvs 54: const HTStreamClass *isa;
55: FILE *fp;
1.45 cvs 56: BOOL leave_open; /* Close file when TtaFreeMemory? */
1.15 cvs 57: char *end_command; /* Command to execute */
58: BOOL remove_on_close; /* Remove file? */
59: char *filename; /* Name of file */
60: HTRequest *request; /* saved for callback */
61: HTRequestCallback *callback;
1.7 cvs 62: };
63:
1.15 cvs 64:
1.7 cvs 65: struct _HTError
66: {
67: HTErrorElement element; /* Index number into HTError */
68: HTSeverity severity; /* A la VMS */
69: BOOL ignore; /* YES if msg should not go to user */
70: void *par; /* Explanation, e.g. filename */
71: int length; /* For copying by generic routine */
72: char *where; /* Which function */
73: };
74:
1.4 cvs 75: /* Type definitions and global variables etc. local to this module */
76:
1.17 cvs 77: /*----------------------------------------------------------------------*/
78:
1.4 cvs 79: /*** private variables ***/
1.17 cvs 80:
1.4 cvs 81: static HTList *converters = NULL; /* List of global converters */
1.27 cvs 82: static HTList *acceptTypes = NULL; /* List of types for the Accept header */
1.151 cvs 83: static HTList *transfer_encodings = NULL;
84: static HTList *content_encodings = NULL;
1.16 cvs 85: static int object_counter = 0; /* loaded objects counter */
1.140 cvs 86: static boolean AmayaAlive_flag; /* set to 1 if the application is active;
87: 0 if we have killed */
88: static boolean CanDoStop_flag; /* set to 1 if we can do a stop, 0
89: if we're inside a critical section */
1.128 cvs 90: #ifdef AMAYA_WWW_CACHE
1.130 cvs 91: static int fd_cachelock; /* open handle to the .lock cache file */
92: #endif /* AMAYA_WWW_CACHE */
1.4 cvs 93:
1.15 cvs 94: #include "answer_f.h"
95: #include "query_f.h"
96: #include "AHTURLTools_f.h"
97: #include "AHTBridge_f.h"
98: #include "AHTMemConv_f.h"
99: #include "AHTFWrite_f.h"
1.4 cvs 100:
1.116 cvs 101: /* prototypes */
102:
103: #ifdef __STDC__
1.128 cvs 104: static void RecCleanCache (char *dirname);
1.123 cvs 105: #ifdef _WINDOWS
1.70 cvs 106: int WIN_Activate_Request (HTRequest* , HTAlertOpcode, int, const char*, void*, HTAlertPar*);
1.116 cvs 107: #endif /* _WINDOWS */
1.70 cvs 108: #else
1.128 cvs 109: static void RecCleanCache (/* char *dirname */);
1.123 cvs 110: #ifdef _WINDOWS
1.128 cvs 111: int WIN_Activate_Request (/* HTRequest* , HTAlertOpcode, int, const char*, void*, HTAlertPar* */);
1.116 cvs 112: #endif /* _WINDOWS */
1.70 cvs 113: #endif /* __STDC__ */
1.116 cvs 114:
1.15 cvs 115:
1.130 cvs 116: #ifdef AMAYA_WWW_CACHE
117: /***************************************************************
118: lock functions, used to avoid concurrent use of the cache
119: Mostly based on W. Richard Stevens' APUE book.
120: ***************************************************************/
121: /*----------------------------------------------------------------------
122: set_cachelock
123: sets a write lock on filename.
124: Returns -1 in case of failure, otherwise, it'll open a handle on
125: filename and fd_cachelock will take its value.
126: ----------------------------------------------------------------------*/
127: #ifdef __STDC__
128: static int set_cachelock (char *filename)
129: #else
130: static int set_cachelock (filename)
131: char *filename;
132: #endif /* __STDC__ */
133: {
134: #ifdef _WINDOWS
1.185 cvs 135: return ((TtaFileExist (filename)) ? 0 : -1);
1.130 cvs 136: #else
137: int status;
138: struct flock lock;
139:
140: lock.l_type = F_WRLCK;
141: lock.l_start = 0;
142: lock.l_whence = SEEK_SET;
143: lock.l_len = 0;
144:
145: fd_cachelock = open (filename, O_WRONLY);
146:
147: if (fd_cachelock == -1)
148: status = -1;
149: else
150: status = fcntl(fd_cachelock, F_SETLK, &lock);
151:
152: if (status == -1)
1.183 cvs 153: {
1.179 cvs 154: if (fd_cachelock > 0)
1.183 cvs 155: close (fd_cachelock);
1.179 cvs 156: fd_cachelock = 0;
1.178 cvs 157: }
1.130 cvs 158: return (status);
159: #endif /* _WINDOWS */
160: }
161:
162: /*----------------------------------------------------------------------
163: clear_cachelock
164: remove the write lock set on a filename.
165: It'll close the fd handle on filename and reset *fd to 0.
166: ----------------------------------------------------------------------*/
167: #ifdef __STDC__
168: static int clear_cachelock (void)
169: #else
170: static int clear_cachelock ()
171: int *fd;
172: #endif /* __STDC__ */
173: {
174: #ifdef _WINDOWS
175: return 0;
176: #else
177: int status;
178:
1.178 cvs 179: if (!fd_cachelock)
1.130 cvs 180: return (-1);
181:
1.178 cvs 182: status = close (fd_cachelock);
1.130 cvs 183: fd_cachelock = 0;
184:
185: return (status);
186: #endif /* _WINDOWS */
187: }
188:
189: /*----------------------------------------------------------------------
190: test_cachelock
191: returns 0 if a fd is not locked by other process, otherwise
192: returns the pid of the process who has the lock
193: ----------------------------------------------------------------------*/
194: #ifdef __STDC__
195: static int test_cachelock (char *filename)
196: #else
197: static int test_cachelock (filename)
198: char *filename;
199: #endif __STDC__
200: {
201: #ifdef _WINDOWS
1.185 cvs 202: /* if the lock is set, we can't unlink the file under Windows */
203: if (unlink (filename))
204: return -1;
1.130 cvs 205: else
1.185 cvs 206: return 0;
1.130 cvs 207: #else
208: struct flock lock;
209: int fd, status;
210:
211: lock.l_type = F_WRLCK;
212: lock.l_start = 0;
213: lock.l_whence = SEEK_SET;
214: lock.l_len = 0;
215:
216: fd = open (filename, O_WRONLY);
217:
218: if (fd < 0)
219: return (-1);
220: /* is this file locked ? */
221: status = fcntl (fd, F_GETLK, &lock);
222: close (fd);
223:
224: if (status < 0)
225: return (-1);
226:
227: if (lock.l_type == F_UNLCK)
228: return (0); /* false, region is not locked by another proc */
229: return (lock.l_pid); /* true, return pid of lock owner */
230: #endif /* _WINDOWS */
231: }
232:
233: #endif /* AMAYA_WWW_CACHE */
234:
1.15 cvs 235: /*----------------------------------------------------------------------
1.17 cvs 236: GetDocIdStatus
237: gets the status associated to a docid
1.15 cvs 238: ----------------------------------------------------------------------*/
239: #ifdef __STDC__
240: AHTDocId_Status *GetDocIdStatus (int docid, HTList * documents)
241: #else
242: AHTDocID_Status *GetDocIdStatus (docid, documents)
243: int docid;
244: HTList *documents;
245:
246: #endif
247: {
248: AHTDocId_Status *me;
249: HTList *cur;
250:
251: if (documents)
252: {
253: cur = documents;
254:
255: while ((me = (AHTDocId_Status *) HTList_nextObject (cur)))
256: {
257: if (me->docid == docid)
258: return (me);
1.18 cvs 259: }
260: }
1.15 cvs 261: return (AHTDocId_Status *) NULL;
262:
263: }
264:
1.5 cvs 265: /*----------------------------------------------------------------------
1.27 cvs 266: AHTGuessAtom_for
267: Converts an Amaya type descriptor into the equivalent MIME type.
268: ----------------------------------------------------------------------*/
269: #ifdef __STDC__
270: static HTAtom *AHTGuessAtom_for (char *urlName, PicType contentType)
271: #else
272: static HTAtom *AHTGuessAtom_for (urlName, contentType)
273: char *urlName;
274: PicType contentType;
275: #endif
276: {
277: HTAtom *atom;
278: char *filename;
1.160 cvs 279: HTEncoding enc = NULL;
280: HTEncoding cte = NULL;
281: HTLanguage lang = NULL;
1.50 cvs 282: double quality = 1.0;
1.27 cvs 283:
284: switch (contentType)
285: {
286: case xbm_type:
287: atom = HTAtom_for("image/xbm");
288: break;
289: case eps_type:
1.35 cvs 290: atom = HTAtom_for("application/postscript");
1.27 cvs 291: break;
292: case xpm_type:
293: atom = HTAtom_for("image/xpm");
294: break;
295: case gif_type:
296: atom = HTAtom_for("image/gif");
297: break;
298: case jpeg_type:
299: atom = HTAtom_for("image/jpeg");
300: break;
301: case png_type:
302: atom = HTAtom_for("image/png");
303: break;
304: case unknown_type:
305: default:
306: /*
307: ** Amaya could not detect the type, so
308: ** we try to use the filename's suffix to do so.
309: */
1.45 cvs 310: filename = AmayaParseUrl (urlName, "", AMAYA_PARSE_PATH | AMAYA_PARSE_PUNCTUATION);
1.27 cvs 311: HTBind_getFormat (filename, &atom, &enc, &cte, &lang, &quality);
1.45 cvs 312: TtaFreeMemory (filename);
1.27 cvs 313: if (atom == WWW_UNKNOWN)
314: /*
315: ** we could not identify the suffix, so we assign it
316: ** a default type
317: */
318: atom = HTAtom_for ("text/html");
319: break;
320: }
321:
322: return atom;
323: }
324:
325: /*----------------------------------------------------------------------
1.17 cvs 326: AHTReqContext_new
327: create a new Amaya Context Object and update the global Amaya
328: request status.
1.5 cvs 329: ----------------------------------------------------------------------*/
1.4 cvs 330: #ifdef __STDC__
331: static AHTReqContext *AHTReqContext_new (int docid)
332: #else
333: static AHTReqContext *AHTReqContext_new (docid)
334: int docid;
335:
336: #endif
337: {
338: AHTReqContext *me;
339: AHTDocId_Status *docid_status;
340:
341: if ((me = (AHTReqContext *) TtaGetMemory (sizeof (AHTReqContext))) == NULL)
1.116 cvs 342: outofmem (__FILE__, "AHTReqContext_new");
343:
344: /* clear the structure */
345: memset ((void *) me, 0, sizeof (AHTReqContext));
1.4 cvs 346:
1.81 cvs 347: /* Bind the Context object together with the Request Object */
348: me->request = HTRequest_new ();
349:
1.80 cvs 350: /* clean the associated file structure) */
1.79 cvs 351: HTRequest_setOutputStream (me->request, NULL);
1.81 cvs 352:
1.4 cvs 353: /* Initialize the other members of the structure */
1.17 cvs 354: me->reqStatus = HT_NEW; /* initial status of a request */
1.4 cvs 355: me->docid = docid;
356: HTRequest_setMethod (me->request, METHOD_GET);
357: HTRequest_setOutputFormat (me->request, WWW_SOURCE);
358: HTRequest_setContext (me->request, me);
1.116 cvs 359:
1.36 cvs 360: /* experimental */
361: me->read_sock = INVSOC;
362: me->write_sock = INVSOC;
363: me->except_sock = INVSOC;
1.4 cvs 364:
365: /* Update the global context */
366: HTList_appendObject (Amaya->reqlist, (void *) me);
367:
368: docid_status = GetDocIdStatus (docid, Amaya->docid_status);
369:
1.7 cvs 370: if (docid_status == NULL)
371: {
1.116 cvs 372: docid_status = (AHTDocId_Status *)
373: TtaGetMemory (sizeof (AHTDocId_Status));
1.7 cvs 374: docid_status->docid = docid;
375: docid_status->counter = 1;
376: HTList_addObject (Amaya->docid_status, (void *) docid_status);
377: }
378: else
1.4 cvs 379: docid_status->counter++;
380:
381: Amaya->open_requests++;
382:
1.74 cvs 383: #ifdef DEBUG_LIBWWW
384: fprintf (stderr, "AHTReqContext_new: Created object %p\n", me);
385: #endif
1.116 cvs 386:
1.4 cvs 387: return me;
388: }
389:
1.5 cvs 390: /*----------------------------------------------------------------------
1.17 cvs 391: AHTReqContext_delete
392: Delete an Amaya Context Object and update the global Amaya request
393: status.
1.5 cvs 394: ----------------------------------------------------------------------*/
1.4 cvs 395:
396: #ifdef __STDC__
1.15 cvs 397: boolean AHTReqContext_delete (AHTReqContext * me)
1.4 cvs 398: #else
1.15 cvs 399: boolean AHTReqContext_delete (me)
1.4 cvs 400: AHTReqContext *me;
401:
402: #endif
403: {
404: AHTDocId_Status *docid_status;
405:
1.7 cvs 406: if (me)
407: {
1.74 cvs 408: #ifdef DEBUG_LIBWWW
1.138 cvs 409: fprintf (stderr, "AHTReqContext_delete: Deleting object %p\n", me);
1.74 cvs 410: #endif
1.138 cvs 411: if (Amaya->reqlist)
412: HTList_removeObject (Amaya->reqlist, (void *) me);
413:
414: docid_status = GetDocIdStatus (me->docid, Amaya->docid_status);
415: if (docid_status)
416: {
417: docid_status->counter--;
418:
419: if (docid_status->counter == 0)
420: {
421: HTList_removeObject (Amaya->docid_status, (void *) docid_status);
422: TtaFreeMemory ((void *) docid_status);
423: }
424: }
425: if (me->method != METHOD_PUT && HTRequest_outputStream (me->request))
1.154 cvs 426: AHTFWriter_FREE (HTRequest_outputStream (me->request));
1.138 cvs 427:
428: HTRequest_delete (me->request);
429:
430: if (me->output && me->output != stdout)
431: {
1.85 cvs 432: #ifdef DEBUG_LIBWWW
1.138 cvs 433: fprintf (stderr, "AHTReqContext_delete: URL is %s, closing "
434: "FILE %p\n", me->urlName, me->output);
1.85 cvs 435: #endif
1.138 cvs 436: fclose (me->output);
437: me->output = NULL;
438: }
1.79 cvs 439:
1.138 cvs 440: if (me->error_stream != (char *) NULL)
441: HT_FREE (me->error_stream);
442: #ifndef _WINDOWS
443: #ifdef WWW_XWINDOWS
444: if (me->read_xtinput_id || me->write_xtinput_id ||
445: me->except_xtinput_id)
446: RequestKillAllXtevents(me);
447: #endif /* WWW_XWINDOWS */
448: #endif /* !_WINDOWS */
449:
450: if (me->reqStatus == HT_ABORT)
451: {
452: if (me->outputfile && me->outputfile[0] != EOS)
453: {
454: TtaFileUnlink (me->outputfile);
455: me->outputfile[0] = EOS;
456: }
457: }
458:
459: if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC))
460: /* for the ASYNC mode, free the memory we allocated in GetObjectWWW
461: or in PutObjectWWW */
462: {
463: if (me->urlName)
464: TtaFreeMemory (me->urlName);
465: if (me->outputfile)
466: TtaFreeMemory (me->outputfile);
467: }
468:
469: if (me->content_type)
470: TtaFreeMemory (me->content_type);
471:
472: if (me->formdata)
473: HTAssocList_delete (me->formdata);
474:
475: /* to trace bugs */
476: memset ((void *) me, 0, sizeof (AHTReqContext));
477:
478: TtaFreeMemory ((void *) me);
479:
480: Amaya->open_requests--;
481:
482: return TRUE;
1.7 cvs 483: }
1.15 cvs 484: return FALSE;
1.4 cvs 485: }
486:
487:
1.15 cvs 488: /*----------------------------------------------------------------------
1.17 cvs 489: Thread_deleteAll
490: this function deletes the whole list of active threads.
1.5 cvs 491: ----------------------------------------------------------------------*/
1.4 cvs 492: #ifdef __STDC__
493: static void Thread_deleteAll (void)
494: #else
495: static void Thread_deleteAll ()
496: #endif
497: {
1.21 cvs 498: HTList *cur;
499: AHTReqContext *me;
500: AHTDocId_Status *docid_status;
501:
1.74 cvs 502: if (Amaya && Amaya->reqlist)
503: {
504: if (Amaya->open_requests > 0)
505: #ifdef DEBUG_LIBWWW
506: fprintf (stderr, "Thread_deleteAll: Killing %d outstanding "
507: "requests\n", Amaya->open_requests);
508: #endif
509: {
510: cur = Amaya->reqlist;
511:
512: /* erase the requests */
513: while ((me = (AHTReqContext *) HTList_removeLastObject (cur)))
514: {
515: if (me->request)
516: {
1.142 cvs 517: #ifndef _WINDOWS
518: #ifdef WWW_XWINDOWS
1.74 cvs 519: RequestKillAllXtevents (me);
1.142 cvs 520: #endif /* WWW_XWINDOWS */
1.138 cvs 521: #endif /* !_WINDOWS */
1.140 cvs 522: if (!HTRequest_kill (me->request))
523: AHTReqContext_delete (me);
1.74 cvs 524: }
525: } /* while */
526:
527: /* erase the docid_status entities */
528: while ((docid_status = (AHTDocId_Status *) HTList_removeLastObject ((void *) Amaya->docid_status)))
529: TtaFreeMemory ((void *) docid_status);
530:
531: } /* if */
1.84 cvs 532:
1.74 cvs 533: }
1.4 cvs 534: }
535:
1.5 cvs 536: /*----------------------------------------------------------------------
1.83 cvs 537: AHTOpen_file
538: ----------------------------------------------------------------------*/
539: #ifdef __STDC__
1.85 cvs 540: int AHTOpen_file (HTRequest * request)
1.83 cvs 541: #else
1.85 cvs 542: int AHTOpen_file (request)
1.83 cvs 543: HTRequest *request;
544:
545: #endif /* __STDC__ */
546: {
547: AHTReqContext *me; /* current request */
548:
549: me = HTRequest_context (request);
550:
1.93 cvs 551: if (!me)
552: return HT_ERROR;
553:
1.83 cvs 554: #ifdef DEBUG_LIBWWW
1.116 cvs 555: fprintf(stderr, "AHTOpen_file: start for object : %p\n", me);
1.85 cvs 556: #endif /* DEBUG_LIBWWW */
557:
558: if (me->reqStatus == HT_ABORT)
559: {
560: #ifdef DEBUG_LIBWWW
561: fprintf(stderr, "AHTOpen_file: caught an abort request, skipping it\n");
1.83 cvs 562: #endif /* DEBUG_LIBWWW */
563:
1.85 cvs 564: return HT_OK;
565: }
566:
1.136 cvs 567: if (me->method == METHOD_PUT)
568: {
569: me->reqStatus = HT_WAITING;
570: return HT_OK;
571: }
572:
1.85 cvs 573: if (HTRequest_outputStream (me->request))
574: {
575:
576: #ifdef DEBUG_LIBWWW
577: fprintf(stderr, "AHTOpen_file: output stream already existed for url %s\n", me->urlName);
578: #endif /* DEBUG_LIBWWW */
579: return HT_OK;
580: }
581:
582: #ifdef DEBUG_LIBWWW
583: fprintf(stderr, "AHTOpen_file: opening output stream for url %s\n", me->urlName);
584: #endif /* DEBUG_LIBWWW */
585:
1.83 cvs 586: if (!(me->output) &&
587: (me->output != stdout) &&
588: #ifndef _WINDOWS
589: (me->output = fopen (me->outputfile, "w")) == NULL)
590: {
1.116 cvs 591: #else /* !_WINDOWS */
1.83 cvs 592: (me->output = fopen (me->outputfile, "wb")) == NULL)
593: {
594: #endif /* !_WINDOWS */
595:
1.131 cvs 596: me->outputfile[0] = EOS; /* file could not be opened */
1.85 cvs 597: #ifdef DEBUG_LIBWWW
598: fprintf(stderr, "AHTOpen_file: couldn't open output stream for url %s\n", me->urlName);
599: #endif
1.83 cvs 600: TtaSetStatus (me->docid, 1,
601: TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),
602: me->outputfile);
603: me->reqStatus = HT_ERR;
604: return (HT_ERROR);
605: }
606:
607: HTRequest_setOutputStream (me->request,
608: AHTFWriter_new (me->request,
609: me->output, YES));
610: me->reqStatus = HT_WAITING;
611:
612: return HT_OK;
613: }
614:
615: /*----------------------------------------------------------------------
1.17 cvs 616: redirection_handler
617: this function is registered to handle permanent and temporary
618: redirections.
619: ----------------------------------------------------------------------*/
1.4 cvs 620: #ifdef __STDC__
1.7 cvs 621: static int redirection_handler (HTRequest * request, HTResponse * response, void *param, int status)
1.4 cvs 622: #else
623: static int redirection_handler (request, context, status)
624: HTRequest *request;
625: HTResponse *response;
626: void *param;
627: int status;
628:
629: #endif
630: {
631:
632: HTAnchor *new_anchor = HTResponse_redirection (response);
1.7 cvs 633: AHTReqContext *me = HTRequest_context (request);
1.4 cvs 634: HTMethod method = HTRequest_method (request);
1.98 cvs 635: char *ref;
636: char *tmp;
1.4 cvs 637:
1.153 cvs 638: if (!me)
639: /* if the redirect doesn't come from Amaya, we call libwww's standard
640: redirect filter */
641: return (HTRedirectFilter (request, response, param, status));
642:
1.7 cvs 643: if (!new_anchor)
644: {
645: if (PROT_TRACE)
646: HTTrace ("Redirection. No destination\n");
647: return HT_OK;
648: }
1.4 cvs 649:
650: /*
1.166 cvs 651: ** Only do redirect on GET and HEAD
1.4 cvs 652: */
1.7 cvs 653: if (!HTMethod_isSafe (method))
654: {
1.130 cvs 655: /*
656: ** If we got a 303 See Other then change the method to GET.
657: ** Otherwise ask the user whether we should continue.
658: */
659: if (status == HT_SEE_OTHER)
660: {
661: if (PROT_TRACE)
662: HTTrace("Redirection. Changing method from %s to GET\n",
663: HTMethod_name(method));
664: HTRequest_setMethod(request, METHOD_GET);
665: }
666: else
667: {
668: HTAlertCallback *prompt = HTAlert_find (HT_A_CONFIRM);
669: if (prompt)
670: {
671: if ((*prompt) (request, HT_A_CONFIRM, HT_MSG_REDIRECTION,
672: NULL, NULL, NULL) != YES)
1.153 cvs 673: return HT_OK;
1.130 cvs 674: }
675: }
1.7 cvs 676: }
1.4 cvs 677: /*
678: ** Start new request with the redirect anchor found in the headers.
679: ** Note that we reuse the same request object which means that we must
680: ** keep this around until the redirected request has terminated. It also
681: ** allows us in an easy way to keep track of the number of redirections
682: ** so that we can detect endless loops.
683: */
1.166 cvs 684:
1.7 cvs 685: if (HTRequest_doRetry (request))
686: {
1.174 cvs 687: /*
688: ** Start request with new credentials
689: */
690:
1.166 cvs 691: /* only do a redirect using a network protocol understood by Amaya */
692: if (IsValidProtocol (new_anchor->parent->address))
1.7 cvs 693: {
1.166 cvs 694: /* if it's a valid URL, we try to normalize it */
695: /* We use the pre-redirection anchor as a base name */
1.74 cvs 696: ref = AmayaParseUrl (new_anchor->parent->address,
697: me->urlName, AMAYA_PARSE_ALL);
1.7 cvs 698: if (ref)
699: {
1.98 cvs 700: HT_FREE (new_anchor->parent->address);
701: tmp = NULL;
702: HTSACopy (&tmp, ref);
703: new_anchor->parent->address = tmp;
704: TtaFreeMemory (ref);
1.7 cvs 705: }
1.98 cvs 706: else
1.166 cvs 707: return HT_OK; /* We can't redirect anymore */
1.7 cvs 708: }
1.166 cvs 709: else
710: return HT_OK; /* We can't redirect anymore */
1.7 cvs 711:
712: /* update the current file name */
1.130 cvs 713: if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC))
1.7 cvs 714: {
1.130 cvs 715: TtaFreeMemory (me->urlName);
716: me->urlName = TtaStrdup (new_anchor->parent->address);
1.7 cvs 717: }
718: else
1.130 cvs 719: /* it's a SYNC mode, so we should keep the urlName */
720: {
721: strncpy (me->urlName, new_anchor->parent->address,
722: MAX_LENGTH - 1);
723: me->urlName[MAX_LENGTH - 1] = EOS;
724: }
1.38 cvs 725: ChopURL (me->status_urlName, me->urlName);
1.116 cvs 726:
1.183 cvs 727: /* clean the output stream */
728: if (HTRequest_outputStream (me->request) != NULL) {
729: AHTFWriter_FREE (HTRequest_outputStream (me->request));
1.85 cvs 730: if (me->output != stdout) { /* Are we writing to a file? */
1.74 cvs 731: #ifdef DEBUG_LIBWWW
1.130 cvs 732: fprintf (stderr, "redirection_handler: New URL is %s, closing "
733: "FILE %p\n", me->urlName, me->output);
1.74 cvs 734: #endif
1.79 cvs 735: fclose (me->output);
736: me->output = NULL;
737: }
1.64 cvs 738: }
1.68 cvs 739:
1.174 cvs 740: /* tell the user what we're doing */
741: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_RED_FETCHING),
742: me->status_urlName);
743:
744:
1.171 cvs 745: /*
746: ** launch the request
747: */
1.174 cvs 748: /* reset the request status */
1.116 cvs 749: me->reqStatus = HT_NEW;
1.105 cvs 750: /* clear the errors */
1.116 cvs 751: HTError_deleteAll (HTRequest_error (request));
1.105 cvs 752: HTRequest_setError (request, NULL);
1.174 cvs 753: /* clear the authentication credentials */
754: HTRequest_deleteCredentialsAll (request);
755:
1.171 cvs 756: if (me->method == METHOD_POST
757: || me->method == METHOD_PUT) /* PUT, POST etc. */
758: status = HTLoadAbsolute (me->urlName, request);
1.7 cvs 759: else
1.74 cvs 760: HTLoadAnchor (new_anchor, request);
1.7 cvs 761: }
762: else
1.68 cvs 763: {
1.74 cvs 764: HTRequest_addError (request, ERR_FATAL, NO, HTERR_MAX_REDIRECT,
765: NULL, 0, "HTRedirectFilter");
766: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REDIRECTIONS_LIMIT),
767: NULL);
1.173 cvs 768: /* so that we can show the error message */
1.74 cvs 769: if (me->error_html)
1.173 cvs 770: DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR;
771: me->reqStatus = HT_ERR;
1.68 cvs 772: }
773:
1.4 cvs 774: /*
1.74 cvs 775: ** By returning HT_ERROR we make sure that this is the last handler to be
776: ** called. We do this as we don't want any other filter to delete the
777: ** request object now when we have just started a new one ourselves
778: */
1.4 cvs 779: return HT_ERROR;
780: }
781:
1.151 cvs 782: #ifdef AMAYA_LOST_UPDATE
783: /*----------------------------------------------------------------------
784: precondition_handler
785: 412 "Precondition failed" handler
786: ----------------------------------------------------------------------*/
787: #if __STDC__
788: static int precondition_handler (HTRequest * request, HTResponse * response, void *context, int status)
789: #else
790: static int precondition_handler (request, response, context, status)
791: HTRequest *request;
792: HTResponse *response;
793: void *context;
794: int status;
795: #endif /* __STDC__ */
796: {
1.168 cvs 797: AHTReqContext *me = (AHTReqContext *) HTRequest_context (request);
798: HTAlertCallback *prompt = HTAlert_find (HT_A_CONFIRM);
799: boolean force_put;
1.151 cvs 800:
801: if (!me)
802: return HT_OK; /* not an Amaya request */
803:
1.168 cvs 804: if (prompt)
805: force_put = (*prompt) (request, HT_A_CONFIRM, HT_MSG_RULES,
806: NULL, NULL, NULL);
807: else
808: force_put = NO;
809:
810: if (force_put)
811: {
812: /* start a new PUT request without preconditions */
813: /* @@ do we need to kill the request? */
814: if (me->output && me->output != stdout)
815: {
816: fclose (me->output);
817: me->output = NULL;
818: }
819: /*
820: ** reset the Amaya and libwww request status
821: */
1.176 cvs 822:
823: /* start with a new, clean request structure */
824: HTRequest_delete (me->request);
825: me->request = HTRequest_new ();
826: /* clean the associated file structure) */
827: HTRequest_setOutputStream (me->request, NULL);
828: /* Initialize the other members of the structure */
1.171 cvs 829: HTRequest_setMethod (me->request, METHOD_GET);
1.176 cvs 830: HTRequest_setOutputFormat (me->request, WWW_SOURCE);
831: HTRequest_setContext (me->request, me);
832: HTRequest_setPreemptive (me->request, NO);
833: /*
834: ** Make sure that the first request is flushed immediately and not
835: ** buffered in the output buffer
836: */
837: if (me->mode & AMAYA_FLUSH_REQUEST)
838: HTRequest_setFlush(me->request, YES);
839:
1.171 cvs 840: /* turn off preconditions */
841: HTRequest_setPreconditions(me->request, HT_NO_MATCH);
842: me->reqStatus = HT_NEW;
843: /* make the request */
1.176 cvs 844: status = HTPutDocumentAnchor (HTAnchor_parent (me->source),
845: me->dest, me->request);
1.168 cvs 846: /* stop here */
847: return HT_ERROR;
848: }
849: else
850: {
851: /* abort the request */
852: /* @@ should we call StopRequest here? */
853: me->reqStatus = HT_ABORT;
854: /* stop here */
855: return HT_ERROR;
856: }
857: }
1.151 cvs 858:
1.168 cvs 859: /*----------------------------------------------------------------------
860: check_handler
861: Request HEAD checker filter
862: ----------------------------------------------------------------------*/
863: static int check_handler (HTRequest * request, HTResponse * response,
1.151 cvs 864: void * param, int status)
865: {
1.168 cvs 866: AHTReqContext *me = (AHTReqContext *) HTRequest_context (request);
867: HTAlertCallback *prompt = HTAlert_find (HT_A_CONFIRM);
868: boolean force_put;
869:
870: if (!me)
871: return HT_OK; /* not an Amaya request */
872:
873: HTRequest_deleteAfter(me->request, check_handler);
874: /*
875: ** If head request showed that the document doesn't exist
876: ** then just go ahead and PUT it. Otherwise ask for help
877: */
878: if (status == HT_ERROR || status == HT_INTERRUPTED || status == HT_TIMEOUT)
879: {
880: /* we'd need to call terminate_handler, to free the resources */
881: /* abort the request */
882: /* @@ should we call StopRequest here? */
883: me->reqStatus = HT_ABORT;
884: /* stop here */
885: return HT_ERROR;
886: }
887: else if (status == HT_NO_ACCESS || status == HT_NO_PROXY_ACCESS)
888: {
889: /* we'd need to call terminate_handler, to free the resources */
890: /* abort the request */
891: /* @@ should we call StopRequest here? */
892: me->reqStatus = HT_ABORT;
893: /* stop here */
894: return HT_ERROR;
895: }
896: else if ( (abs(status)/100) != 2)
897: {
1.176 cvs 898: /* start with a new, clean request structure */
899: HTRequest_delete (me->request);
900: me->request = HTRequest_new ();
901: /* clean the associated file structure) */
902: HTRequest_setOutputStream (me->request, NULL);
903: /* Initialize the other members of the structure */
1.171 cvs 904: HTRequest_setMethod (me->request, METHOD_GET);
1.176 cvs 905: HTRequest_setOutputFormat (me->request, WWW_SOURCE);
906: HTRequest_setContext (me->request, me);
907: HTRequest_setPreemptive (me->request, NO);
908: /*
909: ** Make sure that the first request is flushed immediately and not
910: ** buffered in the output buffer
911: */
912: if (me->mode & AMAYA_FLUSH_REQUEST)
913: HTRequest_setFlush(me->request, YES);
914:
915: /* turn on the special preconditions, to avoid having this
916: ressource appear before we do the PUT */
1.168 cvs 917: HTRequest_setPreconditions(me->request, HT_DONT_MATCH_ANY);
1.171 cvs 918: me->reqStatus = HT_NEW;
1.168 cvs 919: status = HTPutDocumentAnchor (HTAnchor_parent (me->source), me->dest, me->request);
920: return HT_ERROR; /* stop here */
1.176 cvs 921: }
1.168 cvs 922: else
923: {
924: if (prompt)
925: force_put = (*prompt) (request, HT_A_CONFIRM, HT_MSG_FILE_REPLACE,
926: NULL, NULL, NULL);
927: else
928: force_put = FALSE;
929:
930: if (force_put)
1.151 cvs 931: {
932: /* Start a new PUT request without preconditions */
1.176 cvs 933:
934: /* get a new, clean request structure */
935: HTRequest_delete (me->request);
936: me->request = HTRequest_new ();
937: /* clean the associated file structure) */
938: HTRequest_setOutputStream (me->request, NULL);
939: /* Initialize the other members of the structure */
1.171 cvs 940: HTRequest_setMethod (me->request, METHOD_GET);
1.176 cvs 941: HTRequest_setOutputFormat (me->request, WWW_SOURCE);
942: HTRequest_setContext (me->request, me);
943: HTRequest_setPreemptive (me->request, NO);
944: /*
945: ** Make sure that the first request is flushed immediately and not
946: ** buffered in the output buffer
947: */
948: if (me->mode & AMAYA_FLUSH_REQUEST)
949: HTRequest_setFlush(me->request, YES);
950: /* remove the preconditions */
1.168 cvs 951: HTRequest_setPreconditions(me->request, HT_NO_MATCH);
1.171 cvs 952: me->reqStatus = HT_NEW;
1.176 cvs 953: status = HTPutDocumentAnchor (HTAnchor_parent (me->source),
954: me->dest, me->request);
1.168 cvs 955: return HT_ERROR; /* stop here */
1.151 cvs 956: }
1.168 cvs 957: else
958: {
959: /* we'd need to call terminate_handler, to free the resources */
960: /* abort the request */
961: /* @@ should we call StopRequest here? */
962: me->reqStatus = HT_ABORT;
963: /* stop here */
964: return HT_ERROR;
965: }
966: }
967: return HT_ERROR;
1.151 cvs 968: }
969: #endif /* AMAYA_LOST_UPDATE */
970:
1.5 cvs 971: /*----------------------------------------------------------------------
1.17 cvs 972: terminate_handler
973: this function is registered to handle the result of the request
1.5 cvs 974: ----------------------------------------------------------------------*/
1.4 cvs 975: #if __STDC__
1.7 cvs 976: static int terminate_handler (HTRequest * request, HTResponse * response, void *context, int status)
1.4 cvs 977: #else
978: static int terminate_handler (request, response, context, status)
979: HTRequest *request;
980: HTResponse *response;
981: void *context;
982: int status;
1.123 cvs 983: #endif /* __STDC__ */
1.4 cvs 984: {
1.116 cvs 985: AHTReqContext *me = (AHTReqContext *) HTRequest_context (request);
986: boolean error_flag;
987: char *content_type;
1.184 cvs 988: HTParentAnchor *anchor;
1.116 cvs 989:
990: if (!me)
1.153 cvs 991: return HT_ERROR; /* not an Amaya request */
1.116 cvs 992:
993: if (me->reqStatus == HT_END)
994: /* we have already processed this request! */
995: return HT_OK;
996:
997: /* if Amaya was killed, treat with this request as if it were
998: issued by a Stop button event */
999:
1000: if (!AmayaIsAlive ())
1.80 cvs 1001: me->reqStatus = HT_ABORT;
1.74 cvs 1002:
1.77 cvs 1003: if (status == HT_LOADED ||
1004: status == HT_CREATED ||
1.79 cvs 1005: status == HT_NO_DATA ||
1.160 cvs 1006: /* kludge for work around libwww problem */
1007: (status == HT_INTERRUPTED && me->method == METHOD_PUT) ||
1.116 cvs 1008: #ifdef AMAYA_WWW_CACHE
1009: /* what status to use to know we're downloading from a cache? */
1010: status == HT_NOT_MODIFIED ||
1011: #endif /* AMAYA_WWW_CACHE */
1.79 cvs 1012: me->reqStatus == HT_ABORT)
1.74 cvs 1013: error_flag = FALSE;
1.13 cvs 1014: else
1.74 cvs 1015: error_flag = TRUE;
1.130 cvs 1016:
1.4 cvs 1017: /* output any errors from the server */
1.130 cvs 1018:
1.77 cvs 1019: /*
1.74 cvs 1020: ** me->output = output file which will receive an html file
1021: ** me->error_html = yes, output HTML errors in the screen
1022: ** request->error_stack == if there are any errors, they will be here
1023: ** me->error_stream_size If it's != 0 means an error message has already
1024: ** been written to the stack
1025: */
1026:
1.4 cvs 1027: /* First, we verify if there are any errors and if they are not
1.17 cvs 1028: ** yet written to the error stack. If no, then let's try to write them
1029: ** ourselves
1030: */
1.74 cvs 1031:
1032: #ifdef DEBUG_LIBWWW
1033: fprintf (stderr, "terminate_handler: URL is "
1034: "%s, closing FILE %p status is %d\n", me->urlName, me->output,
1035: status);
1.69 cvs 1036: #endif
1.74 cvs 1037:
1.69 cvs 1038: if (me->output && me->output != stdout)
1039: {
1.74 cvs 1040: /* we are writing to a file */
1041: if (me->reqStatus != HT_ABORT)
1042: { /* if the request was not aborted and */
1.80 cvs 1043: if (error_flag &&
1044: me->error_html == TRUE)
1045: /* there were some errors and we want to print them */
1046: {
1047: if (me->error_stream_size == 0)/* and the stream is empty */
1048: AHTError_MemPrint (request); /* copy errors from
1.74 cvs 1049: **the error stack
1.77 cvs 1050: ** into the error stream */
1.80 cvs 1051: if (me->error_stream)
1052: { /* if the stream is non-empty */
1053: fprintf (me->output, me->error_stream);/* output the errors */
1.85 cvs 1054: /* Clear the error context, so that we can deal with
1055: this answer as if it were a normal reply */
1056: HTError_deleteAll( HTRequest_error (request));
1057: HTRequest_setError (request, NULL);
1058: error_flag = 0;
1.74 cvs 1059: }
1060: } /* if error_stack */
1.85 cvs 1061: }
1062:
1063: /* if != HT_ABORT */
1064:
1065: #ifdef DEBUG_LIBWWW
1066: fprintf (stderr, "terminate_handler: URL is %s, closing "
1067: "FILE %p\n", me->urlName, me->output);
1068: #endif
1.74 cvs 1069: fclose (me->output);
1070: me->output = NULL;
1.69 cvs 1071: }
1.80 cvs 1072:
1073: if (error_flag)
1074: me->reqStatus = HT_ERR;
1075: else if (me->reqStatus != HT_ABORT)
1076: me->reqStatus = HT_END;
1.151 cvs 1077:
1.116 cvs 1078: /* copy the content_type */
1.151 cvs 1079: if (!me->content_type)
1.88 cvs 1080: {
1.184 cvs 1081: anchor = HTRequest_anchor (request);
1082: if (anchor && HTAnchor_format (anchor))
1083: content_type = HTAtom_name (HTAnchor_format (anchor));
1.154 cvs 1084: else
1085: content_type = "www/unknown";
1086:
1.151 cvs 1087: if (content_type && content_type [0] != EOS)
1088: {
1089: /* libwww gives www/unknown when it gets an error. As this is
1090: an HTML test, we force the type to text/html */
1091: if (!strcmp (content_type, "www/unknown"))
1092: me->content_type = TtaStrdup ("text/html");
1093: else
1094: me->content_type = TtaStrdup (content_type);
1095:
1096: /* Content-Type can be specified by an httpd server's admin.
1097: To be on the safe side, we normalize its case */
1098: ConvertToLowerCase (me->content_type);
1099:
1.88 cvs 1100: #ifdef DEBUG_LIBWWW
1.151 cvs 1101: fprintf (stderr, "content type is: %s\n", me->content_type);
1.88 cvs 1102: #endif /* DEBUG_LIBWWW */
1.151 cvs 1103: }
1104: }
1.114 cvs 1105:
1.115 cvs 1106: /* to avoid a hangup while downloading css files */
1.140 cvs 1107: if (AmayaAlive_flag && (me->mode & AMAYA_LOAD_CSS))
1.116 cvs 1108: TtaSetStatus (me->docid, 1,
1109: TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),
1110: me->status_urlName);
1111:
1112: /* don't remove or Xt will hang up during the PUT */
1113: if (AmayaIsAlive () && ((me->method == METHOD_POST) ||
1114: (me->method == METHOD_PUT)))
1.7 cvs 1115: {
1.80 cvs 1116: PrintTerminateStatus (me, status);
1117: }
1.114 cvs 1118:
1.111 cvs 1119: ProcessTerminateRequest (request, response, context, status);
1.116 cvs 1120:
1.151 cvs 1121: /* stop here */
1.150 cvs 1122: return HT_ERROR;
1.4 cvs 1123: }
1124:
1.5 cvs 1125: /*----------------------------------------------------------------------
1.17 cvs 1126: AHTLoadTerminate_handler
1.74 cvs 1127: this is an application "AFTER" Callback. It's called by the library
1128: when a request has ended, so that we can setup the correct status.
1.5 cvs 1129: ----------------------------------------------------------------------*/
1.4 cvs 1130:
1131: #ifdef __STDC__
1.111 cvs 1132: int AHTLoadTerminate_handler (HTRequest * request, HTResponse * response, void *param, int status)
1.4 cvs 1133: #else
1.111 cvs 1134: int AHTLoadTerminate_handler (request, response, param, status)
1.4 cvs 1135: HTRequest *request;
1136: HTResponse *response;
1137: void *param;
1138: int status;
1.69 cvs 1139:
1.4 cvs 1140: #endif
1141: {
1.116 cvs 1142:
1143: /** @@@@ use this with printstatus ?? */
1144:
1.4 cvs 1145: AHTReqContext *me = HTRequest_context (request);
1146: HTAlertCallback *cbf;
1147: AHTDocId_Status *docid_status;
1148:
1.7 cvs 1149: switch (status)
1.116 cvs 1150: {
1151: case HT_LOADED:
1152: if (PROT_TRACE)
1153: HTTrace ("Load End.... OK: `%s\' has been accessed\n",
1154: me->status_urlName);
1.4 cvs 1155:
1.116 cvs 1156: docid_status = GetDocIdStatus (me->docid,
1157: Amaya->docid_status);
1.7 cvs 1158:
1.116 cvs 1159: if (docid_status != NULL && docid_status->counter > 1)
1160: TtaSetStatus (me->docid, 1,
1161: TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),
1.74 cvs 1162: me->status_urlName);
1.7 cvs 1163: break;
1.116 cvs 1164:
1165: case HT_NO_DATA:
1166: if (PROT_TRACE)
1167: HTTrace ("Load End.... OK BUT NO DATA: `%s\'\n",
1168: me->status_urlName);
1169: TtaSetStatus (me->docid, 1,
1170: TtaGetMessage (AMAYA, AM_LOADED_NO_DATA),
1171: me->status_urlName);
1172: break;
1173:
1174: case HT_INTERRUPTED:
1175: if (PROT_TRACE)
1176: HTTrace ("Load End.... INTERRUPTED: `%s\'\n",
1177: me->status_urlName);
1178: TtaSetStatus (me->docid, 1,
1179: TtaGetMessage (AMAYA, AM_LOAD_ABORT),
1180: NULL);
1181: break;
1.7 cvs 1182:
1.116 cvs 1183: case HT_RETRY:
1184: if (PROT_TRACE)
1185: HTTrace ("Load End.... NOT AVAILABLE, RETRY AT %ld\n",
1186: HTResponse_retryTime (response));
1187: TtaSetStatus (me->docid, 1,
1188: TtaGetMessage (AMAYA, AM_NOT_AVAILABLE_RETRY),
1189: me->status_urlName);
1190: break;
1.7 cvs 1191:
1.116 cvs 1192: case HT_ERROR:
1193: cbf = HTAlert_find (HT_A_MESSAGE);
1194: if (cbf)
1195: (*cbf) (request, HT_A_MESSAGE, HT_MSG_NULL, NULL,
1196: HTRequest_error (request), NULL);
1197: break;
1198:
1199: if (PROT_TRACE)
1200: HTTrace ("Load End.... ERROR: Can't access `%s\'\n",
1201: me->status_urlName ? me->status_urlName :"<UNKNOWN>");
1202: TtaSetStatus (me->docid, 1,
1203: TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
1204: me->status_urlName ? me->status_urlName : "<UNKNOWN>");
1205: break;
1206: default:
1207: if (PROT_TRACE)
1208: HTTrace ("Load End.... UNKNOWN RETURN CODE %d\n", status);
1209: break;
1210: }
1211:
1212: return HT_OK;
1213: }
1.7 cvs 1214:
1.116 cvs 1215: #ifdef DEBUG_LIBWWW
1216: static int LineTrace (const char * fmt, va_list pArgs)
1217: {
1218: return (vfprintf(stderr, fmt, pArgs));
1.4 cvs 1219: }
1.116 cvs 1220: #endif DEBUG_LIBWWW
1.4 cvs 1221:
1.27 cvs 1222: /*----------------------------------------------------------------------
1223: AHTAcceptTypesInit
1.74 cvs 1224: This function prepares the Accept header used by Amaya during
1225: the HTTP content negotiation phase
1.27 cvs 1226: ----------------------------------------------------------------------*/
1227: #ifdef __STDC__
1228: static void AHTAcceptTypesInit (HTList *c)
1229: #else /* __STDC__ */
1230: static void AHTAcceptTypesInit (c)
1231: HTList *c;
1232: #endif /* __STDC__ */
1233: {
1234: if (c == (HTList *) NULL)
1235: return;
1236:
1237: /* define here all the mime types that Amaya can accept */
1238:
1.74 cvs 1239: HTConversion_add (c, "image/png", "www/present",
1240: HTThroughLine, 1.0, 0.0, 0.0);
1241: HTConversion_add (c, "image/jpeg", "www/present",
1242: HTThroughLine, 1.0, 0.0, 0.0);
1243: HTConversion_add (c, "image/gif", "www/present",
1244: HTThroughLine, 1.0, 0.0, 0.0);
1245: HTConversion_add (c, "image/xbm", "www/present",
1246: HTThroughLine, 1.0, 0.0, 0.0);
1247: HTConversion_add (c, "image/xpm", "www/present",
1248: HTThroughLine, 1.0, 0.0, 0.0);
1.183 cvs 1249:
1.27 cvs 1250: /* Define here the equivalences between MIME types and file extensions for
1251: the types that Amaya can display */
1252:
1.176 cvs 1253: /* Initialize suffix bindings for local files */
1254: HTBind_init();
1255:
1.27 cvs 1256: /* Register the default set of file suffix bindings */
1257: HTFileInit ();
1258:
1259: /* Don't do any case distinction */
1260: HTBind_caseSensitive (FALSE);
1261: }
1.4 cvs 1262:
1.5 cvs 1263: /*----------------------------------------------------------------------
1.17 cvs 1264: AHTConverterInit
1265: Bindings between a source media type and a destination media type
1266: (conversion).
1.5 cvs 1267: ----------------------------------------------------------------------*/
1.15 cvs 1268: #ifdef __STDC__
1269: static void AHTConverterInit (HTList *c)
1270: #else /* __STDC__ */
1271: static void AHTConverterInit (c)
1272: HTList *c;
1273: #endif /* __STDC__ */
1.4 cvs 1274: {
1275:
1276: /* Handler for custom http error messages */
1.7 cvs 1277: HTConversion_add (c, "*/*", "www/debug", AHTMemConverter, 1.0, 0.0, 0.0);
1.4 cvs 1278:
1279: /*
1280: ** These are converters that converts to something other than www/present,
1281: ** that is not directly outputting someting to the user on the screen
1282: */
1283:
1.116 cvs 1284: HTConversion_add (c, "message/rfc822", "*/*", HTMIMEConvert,
1285: 1.0, 0.0, 0.0);
1.4 cvs 1286: HTConversion_add (c, "message/x-rfc822-foot", "*/*", HTMIMEFooter,
1287: 1.0, 0.0, 0.0);
1288: HTConversion_add (c, "message/x-rfc822-head", "*/*", HTMIMEHeader,
1289: 1.0, 0.0, 0.0);
1.116 cvs 1290: HTConversion_add(c,"message/x-rfc822-cont", "*/*", HTMIMEContinue,
1291: 1.0, 0.0, 0.0);
1292: HTConversion_add(c,"message/x-rfc822-partial","*/*", HTMIMEPartial,
1293: 1.0, 0.0, 0.0);
1.4 cvs 1294: HTConversion_add (c, "multipart/*", "*/*", HTBoundary,
1295: 1.0, 0.0, 0.0);
1296: HTConversion_add (c, "text/plain", "text/html", HTPlainToHTML,
1297: 1.0, 0.0, 0.0);
1298:
1299: /*
1.116 cvs 1300: ** The following conversions are converting ASCII output from various
1301: ** protocols to HTML objects.
1302: */
1.4 cvs 1303: HTConversion_add (c, "text/x-http", "*/*", HTTPStatus_new,
1304: 1.0, 0.0, 0.0);
1305:
1306: /*
1.116 cvs 1307: ** We also register a special content type guess stream that can figure out
1308: ** the content type by reading the first bytes of the stream
1309: */
1.4 cvs 1310: HTConversion_add (c, "www/unknown", "*/*", HTGuess_new,
1311: 1.0, 0.0, 0.0);
1312:
1.116 cvs 1313: #ifdef AMAYA_WWW_CACHE
1.4 cvs 1314: /*
1.116 cvs 1315: ** Register a persistent cache stream which can save an object to local
1316: ** file
1317: */
1.4 cvs 1318: HTConversion_add (c, "www/cache", "*/*", HTCacheWriter,
1319: 1.0, 0.0, 0.0);
1.116 cvs 1320: HTConversion_add(c,"www/cache-append", "*/*", HTCacheAppend,
1321: 1.0, 0.0, 0.0);
1322: #endif AMAYA_WWW_CACHE
1.4 cvs 1323:
1324: /*
1.116 cvs 1325: ** This dumps all other formats to local disk without any further
1326: ** action taken
1327: */
1.4 cvs 1328: HTConversion_add (c, "*/*", "www/present", HTSaveLocally,
1329: 0.3, 0.0, 0.0);
1.116 cvs 1330:
1.4 cvs 1331: }
1332:
1.27 cvs 1333:
1.15 cvs 1334: /*----------------------------------------------------------------------
1.17 cvs 1335: AHTProtocolInit
1336: Registers all amaya supported protocols.
1.15 cvs 1337: ----------------------------------------------------------------------*/
1.4 cvs 1338: static void AHTProtocolInit (void)
1339: {
1.116 cvs 1340: char *strptr;
1.4 cvs 1341:
1.116 cvs 1342: /*
1343: NB. Preemptive == YES means Blocking requests
1344: Non-preemptive == NO means Non-blocking requests
1345: */
1346: HTTransport_add("tcp", HT_TP_SINGLE, HTReader_new, HTWriter_new);
1347: HTTransport_add("buffered_tcp", HT_TP_SINGLE, HTReader_new,
1348: HTBufferWriter_new);
1349: HTProtocol_add ("http", "buffered_tcp", HTTP_PORT, NO, HTLoadHTTP, NULL);
1.136 cvs 1350: #ifdef _WINDOWS
1351: HTProtocol_add ("file", "local", 0, YES, HTLoadFile, NULL);
1352: #else
1.116 cvs 1353: HTProtocol_add ("file", "local", 0, NO, HTLoadFile, NULL);
1.136 cvs 1354: #endif _WINDOWS
1.116 cvs 1355: #ifdef AMAYA_WWW_CACHE
1356: HTProtocol_add("cache", "local", 0, YES, HTLoadCache, NULL);
1357: #endif /* AMAYA_WWW_CACHE */
1.103 cvs 1358: #if 0 /* experimental code */
1.116 cvs 1359: HTProtocol_add ("ftp", "tcp", FTP_PORT, NO, HTLoadFTP, NULL);
1.17 cvs 1360: #endif
1.116 cvs 1361:
1362: /* initialize pipelining */
1.168 cvs 1363: strptr = (char *) TtaGetEnvString ("ENABLE_PIPELINING");
1.116 cvs 1364: if (strptr && *strptr && strcasecmp (strptr,"yes" ))
1365: HTTP_setConnectionMode (HTTP_11_NO_PIPELINING);
1.4 cvs 1366: }
1367:
1.15 cvs 1368: /*----------------------------------------------------------------------
1.17 cvs 1369: AHTNetInit
1370: Reegisters "before" and "after" request filters.
1.15 cvs 1371: ----------------------------------------------------------------------*/
1.4 cvs 1372: static void AHTNetInit (void)
1373: {
1374:
1375: /* Register BEFORE filters
1.74 cvs 1376: ** The BEFORE filters handle proxies, caches, rule files etc.
1377: ** The filters are called in the order by which the are registered
1378: ** Not done automaticly - may be done by application!
1379: */
1.4 cvs 1380:
1.183 cvs 1381: #ifdef AMAYA_WWW_CACHE
1382: HTNet_addBefore (HTCacheFilter, "http://*", NULL, HT_FILTER_MIDDLE);
1383: #endif /* AMAYA_WWW_CACHE */
1.116 cvs 1384: HTNet_addBefore (HTCredentialsFilter, "http://*", NULL, HT_FILTER_LATE);
1385: HTNet_addBefore (HTProxyFilter, NULL, NULL, HT_FILTER_LATE);
1.85 cvs 1386: HTHost_setActivateRequestCallback (AHTOpen_file);
1.4 cvs 1387:
1388: /* register AFTER filters
1.74 cvs 1389: ** The AFTER filters handle error messages, logging, redirection,
1390: ** authentication etc.
1391: ** The filters are called in the order by which the are registered
1392: ** Not done automaticly - may be done by application!
1393: */
1.4 cvs 1394:
1.116 cvs 1395: HTNet_addAfter (HTAuthFilter, "http://*", NULL, HT_NO_ACCESS,
1396: HT_FILTER_MIDDLE);
1397: HTNet_addAfter(HTAuthFilter, "http://*", NULL, HT_REAUTH,
1398: HT_FILTER_MIDDLE);
1399: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_PERM_REDIRECT,
1400: HT_FILTER_MIDDLE);
1401: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_FOUND,
1402: HT_FILTER_MIDDLE);
1403: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_SEE_OTHER,
1404: HT_FILTER_MIDDLE);
1405: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_TEMP_REDIRECT,
1406: HT_FILTER_MIDDLE);
1.168 cvs 1407: HTNet_addAfter(HTAuthInfoFilter, "http://*", NULL, HT_ALL,
1408: HT_FILTER_MIDDLE);
1.116 cvs 1409: HTNet_addAfter (HTUseProxyFilter, "http://*", NULL, HT_USE_PROXY,
1410: HT_FILTER_MIDDLE);
1.183 cvs 1411: #ifdef AMAYA_WWW_CACHE
1412: HTNet_addAfter (HTCacheUpdateFilter, "http://*", NULL, HT_NOT_MODIFIED,
1413: HT_FILTER_MIDDLE);
1414: #endif /* AMAYA_WWW_CACHE */
1.151 cvs 1415: #ifdef AMAYA_LOST_UPDATE
1416: HTNet_addAfter (precondition_handler, NULL, NULL, HT_PRECONDITION_FAILED,
1417: HT_FILTER_MIDDLE);
1418: #endif /* AMAYA_LOST_UPDATE */
1.111 cvs 1419: #ifndef _WINDOWS
1.116 cvs 1420: HTNet_addAfter (AHTLoadTerminate_handler, NULL, NULL, HT_ALL,
1421: HT_FILTER_LAST);
1.111 cvs 1422: #endif /* !_WINDOWS */
1.116 cvs 1423: /**** for later ?? ****/
1424: /* HTNet_addAfter(HTInfoFilter, NULL, NULL, HT_ALL, HT_FILTER_LATE); */
1.51 cvs 1425: /* handles all errors */
1.116 cvs 1426: HTNet_addAfter (terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST);
1.4 cvs 1427: }
1428:
1.15 cvs 1429: /*----------------------------------------------------------------------
1.17 cvs 1430: AHTAlertInit
1431: Register alert messages and their callbacks.
1.15 cvs 1432: ----------------------------------------------------------------------*/
1433: #ifdef __STDC__
1434: static void AHTAlertInit (void)
1435: #else
1436: static void AHTAlertInit ()
1437: #endif
1438: {
1439: HTAlert_add (AHTProgress, HT_A_PROGRESS);
1.120 cvs 1440: #ifdef __WINDOWS
1.70 cvs 1441: HTAlert_add ((HTAlertCallback *) WIN_Activate_Request, HT_PROG_CONNECT);
1.116 cvs 1442: #endif /* _WINDOWS */
1.15 cvs 1443: HTAlert_add (AHTError_print, HT_A_MESSAGE);
1.48 cvs 1444: HTError_setShow (~((unsigned int) 0 ) & ~((unsigned int) HT_ERR_SHOW_DEBUG)); /* process all messages except debug ones*/
1.15 cvs 1445: HTAlert_add (AHTConfirm, HT_A_CONFIRM);
1446: HTAlert_add (AHTPrompt, HT_A_PROMPT);
1447: HTAlert_add (AHTPromptUsernameAndPassword, HT_A_USER_PW);
1.116 cvs 1448: }
1449:
1.128 cvs 1450: /*----------------------------------------------------------------------
1451: libwww_CleanCache
1452: frontend to the recursive cache cleaning function
1453: ----------------------------------------------------------------------*/
1454: #ifdef __STDC__
1455: void libwww_CleanCache (void)
1456: #else
1457: void libwww_CleanCache ()
1458: Document doc;
1459: View view;
1460: #endif /* __STDC__ */
1461: {
1.130 cvs 1462: #ifdef AMAYA_WWW_CACHE
1.185 cvs 1463: char *real_dir;
1464: char *cache_dir;
1.183 cvs 1465: char *strptr;
1.128 cvs 1466: int cache_size;
1.177 cvs 1467: int cache_expire;
1468: int cache_disconnect;
1.185 cvs 1469: int i;
1470: boolean error;
1471: STRING ptr;
1.130 cvs 1472:
1.128 cvs 1473: if (!HTCacheMode_enabled ())
1.183 cvs 1474: /* don't do anything if we're not using a cache */
1475: return;
1.128 cvs 1476: /* temporarily close down the cache, purge it, then restart */
1.130 cvs 1477: cache_dir = TtaStrdup ( (char *) HTCacheMode_getRoot ());
1.128 cvs 1478: cache_size = HTCacheMode_maxSize ();
1.177 cvs 1479: cache_expire = HTCacheMode_expires ();
1480: cache_disconnect = HTCacheMode_disconnected ();
1481:
1.185 cvs 1482: /* get something we can work on :) */
1483: real_dir = TtaGetMemory (strlen (cache_dir) + 20);
1484: #ifdef _WINDOWS
1485: if (!_strnicmp (cache_dir, "file:", 5))
1486: #else
1487: if (!strncasecmp (cache_dir, "file:", 5))
1488: #endif /* _WINDOWS */
1489: {
1490: strptr = strchr (cache_dir, ':');
1491: strptr++;
1492: strptr++;
1493: }
1494:
1495: /* convert libwww's internal's cache dir name to one
1496: corresponding to the filesystem */
1497: i = 0;
1498: while (cache_dir[i])
1499: {
1500: if (cache_dir[i] == '/')
1501: real_dir[i] = DIR_SEP;
1502: else
1503: real_dir[i] = cache_dir[i];
1504: i++;
1505: }
1506:
1507: /* safeguard... abort the operation if cache_dir doesn't end with
1508: CACHE_DIR_NAME */
1509: error = TRUE;
1510: ptr = strrchr (real_dir, DIR_SEP);
1511: #ifdef _WINDOWS
1512: if (ptr && *ptr && !_stricmp (ptr, CACHE_DIR_NAME))
1513: #else
1514: if (ptr && *ptr && !strcasecmp (ptr, CACHE_DIR_NAME))
1515: #endif /* _WINDOWS */
1516: error = FALSE;
1517: if (error)
1518: return;
1519:
1.130 cvs 1520: /* remove the concurrent cache lock */
1521: #ifdef DEBUG_LIBWWW
1522: fprintf (stderr, "Clearing the cache lock\n");
1523: #endif /* DEBUG_LIBWWW */
1524: clear_cachelock ();
1.128 cvs 1525: HTCacheTerminate ();
1.185 cvs 1526: HTCacheMode_setEnabled (FALSE);
1527:
1528: RecCleanCache (real_dir);
1.128 cvs 1529:
1.177 cvs 1530: HTCacheMode_setExpires (cache_expire);
1531: HTCacheMode_setDisconnected (cache_disconnect);
1.183 cvs 1532: HTCacheInit (cache_dir, cache_size);
1.130 cvs 1533: /* set a new concurrent cache lock */
1.185 cvs 1534: strcat (real_dir, ".lock");
1535: if (set_cachelock (real_dir) == -1)
1.130 cvs 1536: /* couldn't open the .lock file, so, we close the cache to
1537: be in the safe side */
1538: {
1539: #ifdef DEBUG_LIBWWW
1540: fprintf (stderr, "couldnt set the cache lock\n");
1541: #endif /* DEBUG_LIBWWW */
1542: HTCacheTerminate ();
1.185 cvs 1543: HTCacheMode_setEnabled (FALSE);
1.130 cvs 1544: }
1545: #ifdef DEBUG_LIBWWW
1546: fprintf (stderr, "set a cache lock\n");
1547: #endif /* DEBUG_LIBWWW */
1.185 cvs 1548: TtaFreeMemory (real_dir);
1.128 cvs 1549: TtaFreeMemory (cache_dir);
1550: #endif /* AMAYA_WWW_CACHE */
1551: }
1552:
1.118 cvs 1553: #ifdef AMAYA_WWW_CACHE
1554: /*----------------------------------------------------------------------
1.128 cvs 1555: RecCleanCache
1.118 cvs 1556: Clears an existing cache directory
1557: ----------------------------------------------------------------------*/
1558: #ifdef __STDC__
1.128 cvs 1559: static void RecCleanCache (char *dirname)
1.118 cvs 1560: #else
1.128 cvs 1561: static void RecCleanCache (char *dirname)
1562: Document doc;
1563: View view;
1.118 cvs 1564: #endif /* __STDC__ */
1.128 cvs 1565:
1566: #ifdef _WINDOWS
1567: {
1568: HANDLE hFindFile;
1569: boolean status;
1570: WIN32_FIND_DATA ffd;
1571:
1572: char t_dir [MAX_LENGTH];
1.130 cvs 1573: char *ptr;
1.128 cvs 1574:
1.130 cvs 1575: /* create a t_dir name to start searching for files */
1.128 cvs 1576: if ((strlen (dirname) + 10) > MAX_LENGTH)
1577: /* ERROR: directory name is too big */
1578: return;
1579:
1580: strcpy (t_dir, dirname);
1.130 cvs 1581: /* save the end of the dirname. We'll use it to make
1582: a complete pathname when erasing files */
1583: ptr = &t_dir[strlen (t_dir)];
1584: strcat (t_dir, "*");
1.128 cvs 1585:
1.130 cvs 1586: hFindFile = FindFirstFile (t_dir, &ffd);
1.128 cvs 1587:
1588: if (hFindFile == INVALID_HANDLE_VALUE)
1589: /* nothing to erase? */
1590: return;
1591:
1592: status = TRUE;
1.130 cvs 1593: while (status)
1594: {
1595: if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1.133 cvs 1596: {
1597: /* it's a directory, erase it recursively */
1598: if (strcmp (ffd.cFileName, "..") && strcmp (ffd.cFileName, "."))
1599: {
1600: strcpy (ptr, ffd.cFileName);
1601: strcat (ptr, DIR_STR);
1602: RecCleanCache (t_dir);
1.137 cvs 1603: # ifdef _WINDOWS
1604: _rmdir (t_dir);
1605: # else /* !_WINDOWS */
1.133 cvs 1606: rmdir (t_dir);
1.137 cvs 1607: # endif /* _WINDOWS */
1.133 cvs 1608: }
1609: }
1610: else
1.130 cvs 1611: {
1.133 cvs 1612: /* it's a file, erase it */
1.130 cvs 1613: strcpy (ptr, ffd.cFileName);
1.133 cvs 1614: TtaFileUnlink (t_dir);
1.130 cvs 1615: }
1616: status = FindNextFile (hFindFile, &ffd);
1617: }
1.128 cvs 1618: FindClose (hFindFile);
1619: }
1620:
1621: #else /* _WINDOWS */
1.118 cvs 1622: {
1623: DIR *dp;
1624: struct stat st;
1625: #ifdef HAVE_DIRENT_H
1626: struct dirent *d;
1627: #else
1628: struct direct *d;
1629: #endif /* HAVE_DIRENT_H */
1.128 cvs 1630: char filename[BUFSIZ+1];
1.118 cvs 1631:
1632: if ((dp = opendir (dirname)) == NULL)
1633: {
1634: /* @@@ we couldn't open the directory ... we need some msg */
1635: perror (dirname);
1.176 cvs 1636: return;
1.118 cvs 1637: }
1638:
1639: while ((d = readdir (dp)) != NULL)
1640: {
1641: /* skip the UNIX . and .. links */
1642: if (!strcmp (d->d_name, "..")
1643: || !strcmp (d->d_name, "."))
1644: continue;
1645:
1.128 cvs 1646: sprintf (filename, "%s"DIR_STR"%s", dirname, d->d_name);
1.118 cvs 1647: if (lstat (filename, &st) < 0 )
1648: {
1649: /* @@2 need some error message */
1650: perror (filename);
1651: continue;
1652: }
1653:
1654: switch (st.st_mode & S_IFMT)
1655: {
1656: case S_IFDIR:
1657: /* if we find a directory, we erase it, recursively */
1.128 cvs 1658: strcat (filename, DIR_STR);
1659: RecCleanCache (filename);
1660: rmdir (filename);
1.118 cvs 1661: break;
1662: case S_IFLNK:
1663: /* skip any links we find */
1664: continue;
1665: break;
1666: default:
1667: /* erase the filename */
1668: TtaFileUnlink (filename);
1669: break;
1670: }
1671: }
1672: closedir (dp);
1673: }
1.128 cvs 1674: #endif /* _WINDOWS */
1.118 cvs 1675: #endif /* AMAYA_WWW_CACHE */
1676:
1.116 cvs 1677: /*----------------------------------------------------------------------
1678: CacheInit
1679: Reads the cache settings from the thot.ini file.
1680: ----------------------------------------------------------------------*/
1.118 cvs 1681: #ifdef __STDC__
1.116 cvs 1682: static void CacheInit (void)
1.118 cvs 1683: #else
1684: static void Cacheinit ()
1685: #endif
1686:
1.116 cvs 1687: {
1688: #ifndef AMAYA_WWW_CACHE
1689: HTCacheMode_setEnabled (NO);
1690:
1691: #else /* AMAYA_WWW_CACHE */
1692: char *strptr;
1693: char *cache_dir = NULL;
1.185 cvs 1694: char *real_dir = NULL;
1.130 cvs 1695: char *cache_lockfile;
1696: int cache_size;
1.176 cvs 1697: int cache_entry_size;
1.130 cvs 1698: boolean cache_enabled;
1699: boolean cache_locked;
1.177 cvs 1700: boolean tmp_bool;
1.130 cvs 1701:
1.185 cvs 1702: int i;
1703:
1.116 cvs 1704: /* activate cache? */
1.165 cvs 1705: strptr = (char *) TtaGetEnvString ("ENABLE_CACHE");
1.152 cvs 1706: if (strptr && *strptr && strcasecmp (strptr, "yes" ))
1.130 cvs 1707: cache_enabled = NO;
1.116 cvs 1708: else
1.130 cvs 1709: cache_enabled = YES;
1.116 cvs 1710:
1.151 cvs 1711: /* cache protected documents? */
1.152 cvs 1712: strptr = (char *) TtaGetEnvString ("CACHE_PROTECTED_DOCS");
1713: if (strptr && *strptr && !strcasecmp (strptr, "yes" ))
1.151 cvs 1714: HTCacheMode_setProtected (YES);
1715: else
1716: HTCacheMode_setProtected (NO);
1717:
1.116 cvs 1718: /* get the cache dir (or use a default one) */
1719: strptr = (char *) TtaGetEnvString ("CACHE_DIR");
1720: if (strptr && *strptr)
1721: {
1.185 cvs 1722: real_dir = TtaGetMemory (strlen (strptr) + strlen (CACHE_DIR_NAME) + 20);
1723: strcpy (real_dir, strptr);
1724: if (*(real_dir + strlen (real_dir) - 1) != DIR_SEP)
1725: strcat (real_dir, DIR_STR);
1.116 cvs 1726: }
1727: else
1728: {
1.185 cvs 1729: real_dir = TtaGetMemory (strlen (TempFileDirectory)
1730: + strlen (CACHE_DIR_NAME) + 20);
1.186 ! cvs 1731: sprintf (real_dir, "%s%s", TempFileDirectory, CACHE_DIR_NAME);
1.185 cvs 1732: }
1733:
1734: /* compatiblity with previous versions of Amaya: does real_dir
1735: include CACHE_DIR_NAME? If not, add it */
1736: strptr = strstr (real_dir, CACHE_DIR_NAME);
1737: if (!strptr)
1738: {
1739: strcat (real_dir, CACHE_DIR_NAME);
1740: }
1741: else
1742: {
1743: i = strlen (CACHE_DIR_NAME);
1744: if (strptr[i] != EOS)
1745: strcat (real_dir, CACHE_DIR_NAME);
1.116 cvs 1746: }
1.185 cvs 1747:
1748:
1749: cache_dir = TtaGetMemory (strlen (real_dir) + 10);
1750: strcpy (cache_dir, real_dir);
1.116 cvs 1751:
1752: /* get the cache size (or use a default one) */
1.185 cvs 1753: strptr = (char *) TtaGetEnvString ("CACHE_SIZE");
1.116 cvs 1754: if (strptr && *strptr)
1.185 cvs 1755: cache_size = atoi (strptr);
1.116 cvs 1756: else
1757: cache_size = DEFAULT_CACHE_SIZE;
1758:
1.176 cvs 1759: /* get the max cached file size (or use a default one) */
1760: if (!TtaGetEnvInt ("MAX_CACHE_ENTRY_SIZE", &cache_entry_size))
1761: cache_entry_size = DEFAULT_MAX_CACHE_ENTRY_SIZE;
1762:
1.130 cvs 1763: if (cache_enabled)
1.116 cvs 1764: {
1765: /* how to remove the lock? force remove it? */
1.185 cvs 1766: cache_lockfile = TtaGetMemory (strlen (real_dir) + 20);
1767: strcpy (cache_lockfile, real_dir);
1.186 ! cvs 1768: strcat (cache_lockfile, ".lock");
1.130 cvs 1769: cache_locked = FALSE;
1770: if (TtaFileExist (cache_lockfile)
1771: && !(cache_locked = test_cachelock (cache_lockfile)))
1.116 cvs 1772: {
1.130 cvs 1773: #ifdef DEBUG_LIBWWW
1774: fprintf (stderr, "found a stale cache, removing it\n");
1775: #endif /* DEBUG_LIBWWW */
1776: /* remove the lock and clean the cache (the clean cache
1777: will remove all, making the following call unnecessary */
1778: /* little trick to win some memory */
1779: strptr = strrchr (cache_lockfile, '.');
1780: *strptr = EOS;
1781: RecCleanCache (cache_lockfile);
1782: *strptr = '.';
1.116 cvs 1783: }
1784:
1.130 cvs 1785: if (!cache_locked)
1786: {
1787: /* initialize the cache if there's no other amaya
1788: instance running */
1.177 cvs 1789: HTCacheMode_setMaxCacheEntrySize (cache_entry_size);
1790: if (TtaGetEnvBoolean ("CACHE_EXPIRE_IGNORE", &tmp_bool)
1791: && tmp_bool)
1792: HTCacheMode_setExpires (HT_EXPIRES_IGNORE);
1793: else
1794: HTCacheMode_setExpires (HT_EXPIRES_AUTO);
1795: TtaGetEnvBoolean ("CACHE_DISCONNECTED_MODE", &tmp_bool);
1796: if (tmp_bool)
1797: HTCacheMode_setDisconnected (HT_DISCONNECT_NORMAL);
1798: else
1799: HTCacheMode_setDisconnected (HT_DISCONNECT_NONE);
1.130 cvs 1800: HTCacheInit (cache_dir, cache_size);
1801: if (set_cachelock (cache_lockfile) == -1)
1802: /* couldn't open the .lock file, so, we close the cache to
1803: be in the safe side */
1804: {
1805: HTCacheTerminate ();
1.185 cvs 1806: HTCacheMode_setEnabled (FALSE);
1.130 cvs 1807: #ifdef DEBUG_LIBWWW
1808: fprintf (stderr, "couldnt set the cache lock\n");
1809: #endif /* DEBUG_LIBWWW */
1810: }
1811: #ifdef DEBUG_LIBWWW
1812: else
1813: fprintf (stderr, "created the cache lock\n");
1814: #endif /* DEBUG_LIBWWW */
1815: }
1816: else
1817: {
1.185 cvs 1818: HTCacheMode_setEnabled (FALSE);
1.130 cvs 1819: #ifdef DEBUG_LIBWWW
1820: fprintf (stderr, "lock detected, starting libwww without a cache/n");
1821: #endif /* DEBUG_LIBWWW */
1822: }
1823: TtaFreeMemory (cache_lockfile);
1.116 cvs 1824: }
1825: else
1.185 cvs 1826: {
1827: HTCacheMode_setEnabled (FALSE);
1828: }
1.116 cvs 1829: if (cache_dir)
1830: TtaFreeMemory (cache_dir);
1.185 cvs 1831: /* warn the user if the cache isn't active */
1832: if (cache_enabled && !HTCacheMode_enabled ())
1833: {
1834: #ifdef _WINDOWS
1835: MessageBox (NULL, TtaGetMessage (AMAYA, AM_CANT_CREATE_CACHE),
1836: "query.c:InitCache", MB_OK);
1837: #else /* !_WINDOWS */
1838: TtaDisplayMessage (CONFIRM, TtaGetMessage (AMAYA, AM_CANT_CREATE_CACHE),
1839: NULL);
1840: #endif /* _WINDOWS */
1841: }
1.116 cvs 1842: #endif /* AMAYA_WWW_CACHE */
1.15 cvs 1843: }
1844:
1845: /*----------------------------------------------------------------------
1.97 cvs 1846: ProxyInit
1847: Reads any proxies settings which may be declared as environmental
1848: variables or in the thot.ini file. The former overrides the latter.
1849: ----------------------------------------------------------------------*/
1.118 cvs 1850: #ifdef __STDC__
1.97 cvs 1851: static void ProxyInit (void)
1.118 cvs 1852: #else
1853: static void ProxyInit ()
1854: #endif /* __STDC__ */
1.97 cvs 1855: {
1856: char *strptr;
1857: char *str = NULL;
1858: char *name;
1859:
1860: /* get the proxy settings from the thot.ini file */
1861: strptr = (char *) TtaGetEnvString ("HTTP_PROXY");
1862: if (strptr && *strptr)
1863: HTProxy_add ("http", strptr);
1864: /* get the no_proxy settings from the thot.ini file */
1865: strptr = (char *) TtaGetEnvString ("NO_PROXY");
1866: if (strptr && *strptr)
1867: {
1868: str = TtaStrdup (strptr); /* Get copy we can mutilate */
1869: strptr = str;
1870: while ((name = HTNextField (&strptr)) != NULL) {
1871: char *portstr = strchr (name, ':');
1872: unsigned port=0;
1873: if (portstr) {
1874: *portstr++ = '\0';
1.116 cvs 1875: if (*portstr) port = (unsigned) atoi (portstr);
1.97 cvs 1876: }
1877: /* Register it for all access methods */
1878: HTNoProxy_add (name, NULL, port);
1879: }
1880: TtaFreeMemory (str);
1881: }
1882:
1883: /* use libw3's routine to get all proxy settings from the environment */
1884: HTProxy_getEnvVar ();
1885: }
1886:
1887:
1888: /*----------------------------------------------------------------------
1.17 cvs 1889: AHTProfile_newAmaya
1890: creates the Amaya client profile for libwww.
1.15 cvs 1891: ----------------------------------------------------------------------*/
1892: #ifdef __STDC__
1893: static void AHTProfile_newAmaya (char *AppName, char *AppVersion)
1894: #else /* __STDC__ */
1895: static void AHTProfile_newAmaya (AppName, AppVersion)
1896: char *AppName;
1897: char *AppVersion;
1898: #endif /* __STDC__ */
1.4 cvs 1899: {
1.158 cvs 1900: char * strptr;
1901:
1.4 cvs 1902: /* If the Library is not already initialized then do it */
1903: if (!HTLib_isInitialized ())
1904: HTLibInit (AppName, AppVersion);
1905:
1906: if (!converters)
1907: converters = HTList_new ();
1.27 cvs 1908: if (!acceptTypes)
1909: acceptTypes = HTList_new ();
1.151 cvs 1910: if (!transfer_encodings)
1911: transfer_encodings = HTList_new ();
1912: if (!content_encodings)
1913: content_encodings = HTList_new ();
1.4 cvs 1914:
1.169 cvs 1915: /* inhibits libwww's automatic file_suffix_binding */
1916: HTFile_doFileSuffixBinding (FALSE);
1917:
1.4 cvs 1918: /* Register the default set of transport protocols */
1919: HTTransportInit ();
1920:
1921: /* Register the default set of application protocol modules */
1922: AHTProtocolInit ();
1923:
1.116 cvs 1924: /* Register the default set of messages and dialog functions */
1925: AHTAlertInit ();
1926: HTAlert_setInteractive (YES);
1927:
1928: #ifdef AMAYA_WWW_CACHE
1929: /* Enable the persistent cache */
1930: CacheInit ();
1931: #else
1932: HTCacheMode_setEnabled (NO);
1933: #endif /* AMAYA_WWW_CACHE */
1.4 cvs 1934:
1935: /* Register the default set of BEFORE and AFTER filters */
1936: AHTNetInit ();
1937:
1938: /* Set up the default set of Authentication schemes */
1.167 cvs 1939: HTAA_newModule ("basic", HTBasic_generate, HTBasic_parse, NULL,
1940: HTBasic_delete);
1.158 cvs 1941: /* activate MDA by defaul */
1942: strptr = (char *) TtaGetEnvString ("ENABLE_MDA");
1943: if (!strptr || (strptr && *strptr && strcasecmp (strptr, "no" )))
1944: HTAA_newModule ("digest", HTDigest_generate, HTDigest_parse,
1.167 cvs 1945: HTDigest_updateInfo, HTDigest_delete);
1.4 cvs 1946:
1.97 cvs 1947: /* Get any proxy settings */
1948: ProxyInit ();
1.4 cvs 1949:
1950: /* Register the default set of converters */
1951: AHTConverterInit (converters);
1.151 cvs 1952: HTFormat_setConversion (converters);
1.27 cvs 1953: AHTAcceptTypesInit (acceptTypes);
1.4 cvs 1954:
1955: /* Register the default set of transfer encoders and decoders */
1.151 cvs 1956: HTTransferEncoderInit (transfer_encodings);
1.183 cvs 1957: /* ignore all other encoding formats (or libwww will send them
1.181 cvs 1958: thru a blackhole otherwise */
1959: HTCoding_add (content_encodings, "*", NULL, HTIdentityCoding, 1.0);
1.183 cvs 1960:
1961: HTFormat_setTransferCoding(transfer_encodings);
1962:
1963: /* Register the default set of content encoders and decoders */
1964: HTContentEncoderInit(content_encodings);
1.151 cvs 1965: if (HTList_count(content_encodings) > 0)
1966: HTFormat_setContentCoding(content_encodings);
1967: else
1968: {
1969: HTList_delete(content_encodings);
1970: content_encodings = NULL;
1971: }
1.4 cvs 1972:
1973: /* Register the default set of MIME header parsers */
1.74 cvs 1974: HTMIMEInit (); /* must be called again for language selector */
1.4 cvs 1975:
1976: /* Register the default set of Icons for directory listings */
1.27 cvs 1977: /*HTIconInit(NULL); *//* experimental */
1.4 cvs 1978: }
1979:
1.5 cvs 1980: /*----------------------------------------------------------------------
1.17 cvs 1981: AHTProfile_delete
1982: deletes the Amaya client profile.
1.5 cvs 1983: ----------------------------------------------------------------------*/
1.4 cvs 1984: #ifdef __STDC__
1985: static void AHTProfile_delete (void)
1986: #else
1987: static void AHTProfile_delete ()
1.7 cvs 1988: #endif /* __STDC__ */
1.4 cvs 1989: {
1.22 cvs 1990:
1991: /* free the Amaya global context */
1.151 cvs 1992:
1993: /* Clean up all the registred converters */
1994: HTFormat_deleteAll ();
1995: if (acceptTypes)
1.74 cvs 1996: HTConversion_deleteAll (acceptTypes);
1.151 cvs 1997:
1.74 cvs 1998: HTList_delete (Amaya->docid_status);
1999: HTList_delete (Amaya->reqlist);
2000: TtaFreeMemory (Amaya);
1.61 cvs 2001:
1.151 cvs 2002: if (HTLib_isInitialized ())
1.74 cvs 2003:
1.120 cvs 2004: #ifdef _WINDOWS
1.151 cvs 2005: HTEventTerminate ();
1.120 cvs 2006: #endif _WINDOWS;
1.74 cvs 2007:
1.151 cvs 2008: /* Clean up the persistent cache (if any) */
1.116 cvs 2009: #ifdef AMAYA_WWW_CACHE
1.151 cvs 2010: clear_cachelock ();
2011: HTCacheTerminate ();
1.116 cvs 2012: #endif /* AMAYA_WWW_CACHE */
1.74 cvs 2013:
1.151 cvs 2014: /* Terminate libwww */
2015: HTLibTerminate ();
1.4 cvs 2016: }
2017:
1.5 cvs 2018: /*----------------------------------------------------------------------
1.116 cvs 2019: AmayacontextInit
2020: initializes an internal Amaya context for our libwww interface
2021: ----------------------------------------------------------------------*/
2022: #ifdef __STDC__
2023: static void AmayaContextInit ()
2024: #else
2025: static void AmayaContextInit ()
2026: #endif
2027:
2028: {
1.140 cvs 2029: AmayaAlive_flag = TRUE;
1.116 cvs 2030: /* Initialization of the global context */
2031: Amaya = (AmayaContext *) TtaGetMemory (sizeof (AmayaContext));
2032: Amaya->reqlist = HTList_new ();
2033: Amaya->docid_status = HTList_new ();
2034: Amaya->open_requests = 0;
2035: }
2036:
2037: /*----------------------------------------------------------------------
1.17 cvs 2038: QueryInit
2039: initializes the libwww interface
1.5 cvs 2040: ----------------------------------------------------------------------*/
1.4 cvs 2041: #ifdef __STDC__
2042: void QueryInit ()
2043: #else
2044: void QueryInit ()
2045: #endif
2046: {
1.151 cvs 2047: char *strptr;
2048: int tmp_i;
2049: long tmp_l;
1.4 cvs 2050:
1.116 cvs 2051: AmayaContextInit ();
1.4 cvs 2052: AHTProfile_newAmaya (HTAppName, HTAppVersion);
1.140 cvs 2053: CanDoStop_set (TRUE);
1.4 cvs 2054:
1.116 cvs 2055: #ifdef _WINDOWS
1.125 cvs 2056: HTEventInit ();
1.116 cvs 2057: #endif /* _WINDOWS */
1.72 cvs 2058:
1.123 cvs 2059: #ifndef _WINDOWS
1.116 cvs 2060: HTEvent_setRegisterCallback ((void *) AHTEvent_register);
2061: HTEvent_setUnregisterCallback ((void *) AHTEvent_unregister);
1.120 cvs 2062: HTTimer_registerSetTimerCallback ((void *) AMAYA_SetTimer);
2063: HTTimer_registerDeleteTimerCallback ((void *) AMAYA_DeleteTimer);
1.116 cvs 2064: #endif /* !_WINDOWS */
1.148 cvs 2065:
1.176 cvs 2066: WWW_TraceFlag = 0;
1.74 cvs 2067: #ifdef DEBUG_LIBWWW
1.116 cvs 2068: /* forwards error messages to our own function */
2069: WWW_TraceFlag = THD_TRACE;
1.138 cvs 2070: HTTrace_setCallback(LineTrace);
1.4 cvs 2071: /* Trace activation (for debugging) */
1.148 cvs 2072: /***
1.138 cvs 2073: WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_THREAD_TRACE | SHOW_PROTOCOL_TRACE;
2074: WWW_TraceFlag |= 0xFFFFFFFFl;
2075: ***/
1.152 cvs 2076: #endif
2077:
1.148 cvs 2078: /* Setting up different network parameters */
1.151 cvs 2079:
1.148 cvs 2080: /* Maximum number of simultaneous open sockets */
1.151 cvs 2081: strptr = (char *) TtaGetEnvString ("MAX_SOCKET");
2082: if (strptr && *strptr)
2083: tmp_i = atoi (strptr);
2084: else
2085: tmp_i = DEFAULT_MAX_SOCKET;
2086: HTNet_setMaxSocket (tmp_i);
2087:
1.148 cvs 2088: /* different network services timeouts */
1.151 cvs 2089: /* dns timeout */
2090: strptr = (char *) TtaGetEnvString ("DNS_TIMEOUT");
2091: if (strptr && *strptr)
2092: tmp_i = atoi (strptr);
2093: else
2094: tmp_i = DEFAULT_DNS_TIMEOUT;
2095: HTDNS_setTimeout (tmp_i);
2096:
2097: /* persistent connections timeout */
1.152 cvs 2098: strptr = (char *) TtaGetEnvString ("PERSIST_CX_TIMEOUT");
1.151 cvs 2099: if (strptr && *strptr)
2100: tmp_l = atol (strptr);
2101: else
2102: tmp_l = DEFAULT_PERSIST_TIMEOUT;
2103: HTHost_setPersistTimeout (tmp_l);
2104:
1.148 cvs 2105: /* default timeout in ms */
1.151 cvs 2106: strptr = (char *) TtaGetEnvString ("NET_EVENT_TIMEOUT");
2107: if (strptr && *strptr)
2108: tmp_i = atoi (strptr);
2109: else
2110: tmp_i = DEFAULT_NET_EVENT_TIMEOUT;
2111: HTHost_setEventTimeout (tmp_i);
2112:
1.173 cvs 2113: HTRequest_setMaxRetry (8);
1.4 cvs 2114: #ifdef CATCH_SIG
1.148 cvs 2115: signal (SIGPIPE, SIG_IGN);
1.4 cvs 2116: #endif
1.15 cvs 2117: }
2118:
2119: /*----------------------------------------------------------------------
1.17 cvs 2120: LoopForStop
1.136 cvs 2121: a copy of the Thop event loop so we can handle the stop button in Unix
2122: and preemptive requests under Windows
1.15 cvs 2123: ----------------------------------------------------------------------*/
2124: #ifdef __STDC__
2125: static int LoopForStop (AHTReqContext * me)
2126: #else
2127: static int LoopForStop (AHTReqContext * me)
2128: #endif
2129: {
1.136 cvs 2130: #ifdef _WINDOWS
2131: MSG msg;
2132: unsigned long libwww_msg;
2133: HWND old_active_window, libwww_window;
2134: int status_req = HT_OK;
2135:
2136: old_active_window = GetActiveWindow ();
2137: libwww_window = HTEventList_getWinHandle (&libwww_msg);
1.137 cvs 2138:
1.149 cvs 2139: while (me->reqStatus != HT_END && me->reqStatus != HT_ERR
2140: && me->reqStatus != HT_ABORT && AmayaIsAlive () &&
2141: GetMessage (&msg, NULL, 0, 0))
2142: {
2143: if (msg.message != WM_QUIT)
2144: {
2145: TranslateMessage (&msg);
2146: DispatchMessage (&msg);
2147: }
2148: else
2149: break;
2150: }
1.136 cvs 2151: if (!AmayaIsAlive ())
2152: /* Amaya was killed by one of the callback handlers */
2153: exit (0);
2154: #else /* _WINDOWS */
1.25 cvs 2155: extern ThotAppContext app_cont;
1.51 cvs 2156: XEvent ev;
2157: XtInputMask status;
1.17 cvs 2158: int status_req = HT_OK;
1.15 cvs 2159:
2160: /* to test the async calls */
1.17 cvs 2161: /* Loop while waiting for new events, exists when the request is over */
1.15 cvs 2162: while (me->reqStatus != HT_ABORT &&
2163: me->reqStatus != HT_END &&
1.69 cvs 2164: me->reqStatus != HT_ERR) {
1.116 cvs 2165: if (!AmayaIsAlive ())
1.69 cvs 2166: /* Amaya was killed by one of the callback handlers */
2167: exit (0);
2168:
2169: status = XtAppPending (app_cont);
1.144 cvs 2170: if (status & XtIMXEvent)
2171: {
2172: XtAppNextEvent (app_cont, &ev);
2173: TtaHandleOneEvent (&ev);
2174: }
2175: else if (status != 0)
2176: XtAppProcessEvent (app_cont, XtIMAll);
1.69 cvs 2177: }
1.136 cvs 2178: #endif /* _WINDOWS */
1.69 cvs 2179: switch (me->reqStatus) {
2180: case HT_ERR:
2181: case HT_ABORT:
1.130 cvs 2182: status_req = NO;
1.15 cvs 2183: break;
2184:
1.69 cvs 2185: case HT_END:
1.130 cvs 2186: status_req = YES;
1.15 cvs 2187: break;
2188:
1.69 cvs 2189: default:
1.15 cvs 2190: break;
1.69 cvs 2191: }
1.15 cvs 2192: return (status_req);
1.4 cvs 2193: }
2194:
1.5 cvs 2195: /*----------------------------------------------------------------------
1.15 cvs 2196: QueryClose
1.21 cvs 2197: closes all existing threads, frees all non-automatically deallocated
2198: memory and then ends libwww.
1.5 cvs 2199: ----------------------------------------------------------------------*/
1.116 cvs 2200: void QueryClose ()
1.4 cvs 2201: {
1.24 cvs 2202:
1.140 cvs 2203: AmayaAlive_flag = FALSE;
1.24 cvs 2204:
1.116 cvs 2205: /* remove all the handlers and callbacks that may output a message to
2206: a non-existent Amaya window */
1.130 cvs 2207: #ifndef _WINDOWS
1.116 cvs 2208: HTNet_deleteAfter (AHTLoadTerminate_handler);
1.130 cvs 2209: #endif _WINDOWS
1.116 cvs 2210: HTNet_deleteAfter (redirection_handler);
2211: HTAlertCall_deleteAll (HTAlert_global () );
2212: HTAlert_setGlobal ((HTList *) NULL);
2213: HTEvent_setRegisterCallback ((HTEvent_registerCallback *) NULL);
2214: HTEvent_setUnregisterCallback ((HTEvent_unregisterCallback *) NULL);
2215: #ifndef _WINDOWS
2216: /** need to erase all existing timers too **/
2217: HTTimer_registerSetTimerCallback (NULL);
2218: HTTimer_registerDeleteTimerCallback (NULL);
2219: #endif /* !_WINDOWS */
2220: HTHost_setActivateRequestCallback (NULL);
2221: Thread_deleteAll ();
1.21 cvs 2222:
1.116 cvs 2223: HTProxy_deleteAll ();
2224: HTNoProxy_deleteAll ();
2225: HTGateway_deleteAll ();
2226: AHTProfile_delete ();
2227: }
2228:
2229: /*----------------------------------------------------------------------
2230: NextNameValue
2231: ---------------------------------------------------------------------*/
2232: #ifdef __STDC__
2233: static char * NextNameValue (char ** pstr, char **name, char **value)
2234: #else
2235: static char * NextNameValue (pstr, name, value);
2236: char ** pstr;
2237: char **name;
2238: char **value;
2239: #endif /* __STDC__ */
2240: {
2241: char * p = *pstr;
2242: char * start = NULL;
2243: if (!pstr || !*pstr) return NULL;
2244:
2245: if (!*p) {
2246: *pstr = p;
2247: *name = NULL;
2248: *value = NULL;
2249: return NULL; /* No field */
2250: }
2251:
2252: /* Now search for the next '&' and ';' delimitators */
2253: start = p;
2254: while (*p && *p != '&' && *p != ';') p++;
2255: if (*p)
2256: *p++ = '\0';
2257: *pstr = p;
2258:
2259: /* Search for the name and value */
2260: *name = start;
2261: p = start;
2262:
2263: while(*p && *p != '=')
2264: p++;
2265: if (*p)
2266: *p++ = '\0';
2267: *value = p;
2268:
2269: return start;
2270: }
2271:
2272: /*----------------------------------------------------------------------
2273: PrepareFormdata
2274: ---------------------------------------------------------------------*/
2275: #ifdef __STDC__
2276: static HTAssocList * PrepareFormdata (char *string)
2277: #else
2278: static HTAssocList * PrepareFormdata (string)
2279: char *string;
2280: #endif /* __STDC__ */
2281: {
2282: char * tmp_string, * tmp_string_ptr;
2283: char * name;
2284: char * value;
2285: HTAssocList * formdata;
2286:
2287: if (!string)
2288: return NULL;
2289:
2290: /* store the ptr in another variable, as the original address will
2291: change
2292: */
2293:
2294: tmp_string_ptr = tmp_string = TtaStrdup (string);
2295: formdata = HTAssocList_new();
2296:
2297: while (*tmp_string)
2298: {
2299: NextNameValue (&tmp_string, &name, &value);
2300: HTAssocList_addObject(formdata,
2301: name, value);
2302: }
2303:
2304: TtaFreeMemory (tmp_string_ptr);
2305: return formdata;
1.4 cvs 2306: }
2307:
1.99 cvs 2308:
2309: /*----------------------------------------------------------------------
2310: InvokeGetObjectWWW_callback
2311: A simple function to invoke a callback function whenever there's an error
2312: in GetObjectWWW
2313: ---------------------------------------------------------------------*/
2314:
1.116 cvs 2315: #ifdef __STDC__
2316: void InvokeGetObjectWWW_callback (int docid, char *urlName, char *outputfile, TTcbf *terminate_cbf, void *context_tcbf, int status)
1.99 cvs 2317: #else
1.111 cvs 2318: void InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf, context_tcbf, status)
1.99 cvs 2319: int docid;
2320: char *urlName;
2321: char *outputfile;
2322: TTcbf *terminate_cbf;
2323: void *context_tcbf;
1.116 cvs 2324: #endif /* __STDC__ */
1.99 cvs 2325: {
2326: if (!terminate_cbf)
2327: return;
2328:
1.116 cvs 2329: (*terminate_cbf) (docid, status, urlName, outputfile,
1.99 cvs 2330: NULL, context_tcbf);
2331: }
2332:
2333:
2334:
1.5 cvs 2335: /*----------------------------------------------------------------------
1.15 cvs 2336: GetObjectWWW
1.17 cvs 2337: this function requests a resource designated by a URLname into a
2338: temporary filename. The download can come from a simple GET operation,
2339: or can come from POSTING/GETTING a form. In the latter
2340: case, the function receives a query string to send to the server.
2341:
1.5 cvs 2342: 4 file retrieval modes are proposed:
2343: AMAYA_SYNC : blocking mode
2344: AMAYA_ISYNC : incremental, blocking mode
2345: AMAYA_ASYNC : non-blocking mode
2346: AMAYA_IASYNC : incremental, non-blocking mode
2347:
2348: In the incremental mode, each time a package arrives, it will be
2349: stored in the temporary file. In addition, if an
2350: incremental_callback function is defined, this function will be
2351: called and handled a copy of the newly received data package.
2352: Finally, if a terminate_callback function is defined, it will be
2353: invoked when the request terminates. The caller of this function
1.4 cvs 2354: can define two different contexts to be passed to the callback
2355: functions.
2356:
2357: When the function is called with the SYNC mode, the function will
2358: return only when the requested file has been loaded.
2359: The ASYNC mode will immediately return after setting up the
2360: call.
2361:
2362: Notes:
2363: At the end of a succesful request, the urlName string contains the
2364: name of the actually retrieved URL. As a URL can change over the time,
2365: (e.g., be redirected elsewhere), it is advised that the function
1.17 cvs 2366: caller verify the value of the urlName variable at the end of
1.4 cvs 2367: a request.
2368:
2369: Inputs:
2370: - docid Document identifier for the set of objects being
2371: retrieved.
2372: - urlName The URL to be retrieved (MAX_URL_LENGTH chars length)
2373: - outputfile A pointer to an empty string of MAX_URL_LENGTH.
2374: - mode The retrieval mode.
2375: - incremental_cbf
2376: - context_icbf
2377: Callback and context for the incremental modes
2378: - terminate_cbf
2379: - context_icbf
2380: Callback and context for a terminate handler
1.17 cvs 2381: -error_html if TRUE, then display any server error message as an
2382: HTML document.
1.88 cvs 2383: - content_type a string
2384:
1.4 cvs 2385: Outputs:
2386: - urlName The URL that was retrieved
2387: - outputfile The name of the temporary file which holds the
2388: retrieved data. (Only in case of success)
1.88 cvs 2389: - if content_type wasn't NULL, it will contain a copy of the parameter
2390: sent in the HTTP answer
1.4 cvs 2391: Returns:
2392: HT_ERROR
2393: HT_OK
1.5 cvs 2394:
2395: ----------------------------------------------------------------------*/
1.4 cvs 2396: #ifdef __STDC__
1.127 cvs 2397: int GetObjectWWW (int docid, char* urlName, char* formdata,
1.116 cvs 2398: char* outputfile, int mode, TIcbf* incremental_cbf,
2399: void* context_icbf, TTcbf* terminate_cbf,
1.88 cvs 2400: void* context_tcbf, boolean error_html, char *content_type)
1.4 cvs 2401: #else
1.127 cvs 2402: int GetObjectWWW (docid, urlName, formdata, outputfile, mode,
1.116 cvs 2403: incremental_cbf, context_icbf,
1.88 cvs 2404: terminate_cbf, context_tcbf, error_html, content_type)
1.73 cvs 2405: int docid;
2406: char *urlName;
1.127 cvs 2407: char *formdata;
1.73 cvs 2408: char *outputfile;
2409: int mode;
2410: TIcbf *incremental_cbf;
2411: void *context_icbf;
2412: TTcbf *terminate_cbf;
2413: void *context_tcbf;
2414: boolean error_html;
1.88 cvs 2415: char *content_type;
1.4 cvs 2416: #endif
2417: {
2418: AHTReqContext *me;
2419: char *ref;
1.107 cvs 2420: int status, l;
1.114 cvs 2421: int tempsubdir;
1.177 cvs 2422: boolean bool_tmp;
1.7 cvs 2423:
1.116 cvs 2424: if (urlName == NULL || docid == 0 || outputfile == NULL)
2425: {
2426: /* no file to be loaded */
2427: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);
1.69 cvs 2428:
1.116 cvs 2429: if (error_html)
1.69 cvs 2430: /* so we can show the error message */
2431: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1.116 cvs 2432: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
2433: context_tcbf, HT_ERROR);
2434: return HT_ERROR;
2435: }
1.7 cvs 2436:
1.159 cvs 2437: /* if it's a 'docImage', we have already downloaded it */
2438: if (!strncmp ("internal:", urlName, 9))
2439: {
2440: strcpy (outputfile, urlName);
2441: InvokeGetObjectWWW_callback (docid, urlName, outputfile,
2442: terminate_cbf, context_tcbf, HT_OK);
2443: return HT_OK;
2444: }
2445:
1.4 cvs 2446: /* do we support this protocol? */
1.116 cvs 2447: if (IsValidProtocol (urlName) == NO)
2448: {
2449: /* return error */
2450: outputfile[0] = EOS; /* file could not be opened */
2451: TtaSetStatus (docid, 1,
2452: TtaGetMessage (AMAYA, AM_GET_UNSUPPORTED_PROTOCOL),
2453: urlName);
2454:
2455: if (error_html)
1.69 cvs 2456: /* so we can show the error message */
2457: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1.116 cvs 2458: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
2459: context_tcbf, HT_ERROR);
2460: return HT_ERROR;
2461: }
1.4 cvs 2462:
1.114 cvs 2463: /* we store CSS in subdir named 0; all the other files go to a subidr
2464: named after their own docid */
2465:
2466: tempsubdir = (mode & AMAYA_LOAD_CSS) ? 0 : docid;
2467:
1.116 cvs 2468: /* create a tempfilename */
2469: sprintf (outputfile, "%s%c%d%c%04dAM",
2470: TempFileDirectory, DIR_SEP, tempsubdir, DIR_SEP, object_counter);
2471: /* update the object_counter (used for the tempfilename) */
1.4 cvs 2472: object_counter++;
1.116 cvs 2473:
1.4 cvs 2474: /* normalize the URL */
1.45 cvs 2475: ref = AmayaParseUrl (urlName, "", AMAYA_PARSE_ALL);
1.4 cvs 2476: /* should we abort the request if we could not normalize the url? */
1.69 cvs 2477: if (ref == (char*) NULL || ref[0] == EOS) {
2478: /*error */
2479: outputfile[0] = EOS;
2480: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);
2481:
2482: if (error_html)
1.116 cvs 2483: /* so we can show the error message */
2484: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1.99 cvs 2485: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
1.116 cvs 2486: context_tcbf, HT_ERROR);
1.69 cvs 2487: return HT_ERROR;
2488: }
1.116 cvs 2489:
1.4 cvs 2490: /* verify if that file name existed */
1.9 cvs 2491: if (TtaFileExist (outputfile))
1.77 cvs 2492: TtaFileUnlink (outputfile);
1.116 cvs 2493:
1.4 cvs 2494: /* Initialize the request structure */
2495: me = AHTReqContext_new (docid);
1.116 cvs 2496: if (me == NULL)
2497: {
2498: outputfile[0] = EOS;
2499: /* need an error message here */
2500: TtaFreeMemory (ref);
2501: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
2502: context_tcbf, HT_ERROR);
2503: return HT_ERROR;
2504: }
2505:
1.4 cvs 2506: /* Specific initializations for POST and GET */
1.116 cvs 2507: if (mode & AMAYA_FORM_POST)
2508: {
2509: me->method = METHOD_POST;
2510: HTRequest_setMethod (me->request, METHOD_POST);
1.183 cvs 2511: /* don't use the cache for post requests */
2512: HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);
1.116 cvs 2513: }
2514: else
2515: {
2516: me->method = METHOD_GET;
2517: if (!HasKnownFileSuffix (ref))
2518: HTRequest_setConversion(me->request, acceptTypes, TRUE);
2519: }
1.93 cvs 2520:
1.116 cvs 2521: /* Common initialization for all HTML methods */
1.4 cvs 2522: me->mode = mode;
2523: me->error_html = error_html;
2524: me->incremental_cbf = incremental_cbf;
2525: me->context_icbf = context_icbf;
2526: me->terminate_cbf = terminate_cbf;
2527: me->context_tcbf = context_tcbf;
1.64 cvs 2528:
1.69 cvs 2529: /* for the async. request modes, we need to have our
1.4 cvs 2530: own copy of outputfile and urlname
1.116 cvs 2531: */
1.4 cvs 2532:
1.116 cvs 2533: if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC))
2534: {
2535: l = strlen (outputfile);
2536: if (l > MAX_LENGTH)
2537: me->outputfile = TtaGetMemory (l + 2);
2538: else
2539: me->outputfile = TtaGetMemory (MAX_LENGTH + 2);
2540: strcpy (me->outputfile, outputfile);
2541: l = strlen (urlName);
2542: if (l > MAX_LENGTH)
2543: me->urlName = TtaGetMemory (l + 2);
2544: else
2545: me->urlName = TtaGetMemory (MAX_LENGTH + 2);
2546: strcpy (me->urlName, urlName);
2547: #ifdef _WINDOWS
2548: /* force windows ASYNC requests to always be non preemptive */
2549: HTRequest_setPreemptive (me->request, NO);
2550: #endif /*_WINDOWS */
2551: } /* AMAYA_ASYNC mode */
2552: else
2553: #ifdef _WINDOWS
2554: {
2555: me->outputfile = outputfile;
2556: me->urlName = urlName;
2557: /* force windows SYNC requests to always be non preemptive */
2558: HTRequest_setPreemptive (me->request, YES);
2559: }
2560: #else /* !_WINDOWS */
2561: {
2562: me->outputfile = outputfile;
2563: me->urlName = urlName;
2564: }
2565: /***
1.136 cvs 2566: In order to take into account the stop button,
2567: the requests will be always asynchronous, however, if mode=AMAYA_SYNC,
1.57 cvs 2568: we will loop until the document has been received or a stop signal
2569: generated
1.77 cvs 2570: ****/
1.116 cvs 2571: HTRequest_setPreemptive (me->request, NO);
2572: #endif /* _WINDOWS */
1.61 cvs 2573:
1.151 cvs 2574: /*
2575: ** Make sure that the first request is flushed immediately and not
2576: ** buffered in the output buffer
2577: */
2578: if (mode & AMAYA_FLUSH_REQUEST)
2579: HTRequest_setFlush(me->request, YES);
2580: HTRequest_setFlush(me->request, YES);
2581:
1.61 cvs 2582: /* prepare the URLname that will be displayed in teh status bar */
2583: ChopURL (me->status_urlName, me->urlName);
1.77 cvs 2584: TtaSetStatus (me->docid, 1,
2585: TtaGetMessage (AMAYA, AM_FETCHING),
2586: me->status_urlName);
1.4 cvs 2587:
2588: me->anchor = (HTParentAnchor *) HTAnchor_findAddress (ref);
1.45 cvs 2589: TtaFreeMemory (ref);
1.177 cvs 2590:
2591: TtaGetEnvBoolean ("CACHE_DISCONNECTED_MODE", &bool_tmp);
2592: if (!bool_tmp && (mode & AMAYA_NOCACHE))
1.116 cvs 2593: HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);
2594:
2595: /* prepare the query string and format for POST */
2596: if (mode & AMAYA_FORM_POST)
1.114 cvs 2597: {
1.116 cvs 2598: HTAnchor_setFormat ((HTParentAnchor *) me->anchor,
2599: HTAtom_for ("application/x-www-form-urlencoded"));
2600: HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size);
2601: HTRequest_setEntityAnchor (me->request, me->anchor);
2602: }
1.114 cvs 2603:
1.127 cvs 2604: /* create the formdata element for libwww */
2605: if (formdata)
2606: me->formdata = PrepareFormdata (formdata);
2607:
1.116 cvs 2608: /* do the request */
2609: if (mode & AMAYA_FORM_POST)
1.119 cvs 2610: {
2611: /* this call doesn't give back a boolean */
2612: HTParentAnchor * posted = NULL;
2613:
2614: posted = HTPostFormAnchor (me->formdata, (HTAnchor *) me->anchor,
2615: me->request);
2616: status = posted ? YES : NO;
2617: }
1.127 cvs 2618: else if (formdata)
2619: status = HTGetFormAnchor(me->formdata, (HTAnchor *) me->anchor,
2620: me->request);
1.116 cvs 2621: else
1.77 cvs 2622: status = HTLoadAnchor ((HTAnchor *) me->anchor, me->request);
1.69 cvs 2623:
1.123 cvs 2624: /* @@@ may need some special windows error msg here */
1.116 cvs 2625: /* control the errors */
1.4 cvs 2626:
1.130 cvs 2627: if (status == NO)
1.116 cvs 2628: /* the request invocation failed */
2629: {
2630: /* show an error message on the status bar */
2631: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
2632: TtaSetStatus (docid, 1,
2633: TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
2634: urlName);
2635: if (me->reqStatus == HT_NEW)
2636: /* manually invoke the last processing that usually gets done
2637: in a succesful request */
2638: InvokeGetObjectWWW_callback (docid, urlName, outputfile,
2639: terminate_cbf, context_tcbf, HT_ERROR);
2640: /* terminate_handler wasn't called */
1.136 cvs 2641: AHTReqContext_delete (me);
1.116 cvs 2642: }
2643: else
1.136 cvs 2644: /* end treatment for SYNC requests */
1.120 cvs 2645: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))
2646: {
1.136 cvs 2647: /* wait here untilt the asynchronous request finishes */
1.130 cvs 2648: status = LoopForStop (me);
1.136 cvs 2649: /* if status returns HT_ERROR, should we invoke the callback? */
1.120 cvs 2650: if (!HTRequest_kill (me->request))
2651: AHTReqContext_delete (me);
2652: }
1.130 cvs 2653:
1.136 cvs 2654: /* an interface problem!!! */
2655: return (status == YES ? 0 : -1);
1.4 cvs 2656: }
2657:
1.5 cvs 2658: /*----------------------------------------------------------------------
1.17 cvs 2659: PutObjectWWW
2660: frontend for uploading a resource to a URL. This function downloads
2661: a file to be uploaded into memory, it then calls UploadMemWWW to
2662: finish the job.
2663:
1.5 cvs 2664: 2 upload modes are proposed:
2665: AMAYA_SYNC : blocking mode
2666: AMAYA_ASYNC : non-blocking mode
2667:
1.4 cvs 2668: When the function is called with the SYNC mode, the function will
2669: return only when the file has been uploaded.
2670: The ASYNC mode will immediately return after setting up the
2671: call. Furthermore, at the end of an upload, the ASYNC mode will
2672: call back terminate_cbf, handling it the context defined in
2673: context_tcbf.
2674:
2675: Notes:
2676: At the end of a succesful request, the urlName string contains the
2677: name of the actually uploaded URL. As a URL can change over the time,
2678: (e.g., be redirected elsewhere), it is advised that the function
2679: caller verifies the value of the urlName variable at the end of
2680: a request.
2681:
2682: Inputs:
2683: - docid Document identifier for the set of objects being
2684: retrieved.
2685: - fileName A pointer to the local file to upload
2686: - urlName The URL to be uploaded (MAX_URL_LENGTH chars length)
2687: - mode The retrieval mode.
2688: - terminate_cbf
2689: - context_icbf
2690: Callback and context for a terminate handler
2691:
2692: Outputs:
2693: - urlName The URL that was uploaded
2694:
2695: Returns:
2696: HT_ERROR
2697: HT_OK
1.5 cvs 2698: ----------------------------------------------------------------------*/
1.4 cvs 2699: #ifdef __STDC__
1.27 cvs 2700: int PutObjectWWW (int docid, char *fileName, char *urlName, int mode, PicType contentType,
1.4 cvs 2701: TTcbf * terminate_cbf, void *context_tcbf)
2702: #else
1.26 cvs 2703: int PutObjectWWW (docid, urlName, fileName, mode, contentType,
1.4 cvs 2704: ,terminate_cbf, context_tcbf)
2705: int docid;
2706: char *urlName;
2707: char *fileName;
2708: int mode;
1.27 cvs 2709: PicType contentType;
1.4 cvs 2710: TTcbf *terminate_cbf;
2711: void *context_tcbf;
2712:
1.116 cvs 2713: #endif /* __STDC__ */
1.4 cvs 2714: {
1.116 cvs 2715: AHTReqContext *me;
1.4 cvs 2716: int status;
2717: int fd;
2718: struct stat file_stat;
1.116 cvs 2719: char *fileURL;
1.168 cvs 2720: char *etag = NULL;
1.169 cvs 2721: HTParentAnchor *dest_anc_parent;
2722: char *tmp;
1.168 cvs 2723: int UsePreconditions;
1.172 cvs 2724: boolean lost_update_check = TRUE;
2725:
2726: /* should we protect the PUT against lost updates? */
2727: tmp = (char *) TtaGetEnvString ("ENABLE_LOST_UPDATE_CHECK");
2728: if (tmp && *tmp && strcasecmp (tmp, "yes" ))
2729: lost_update_check = FALSE;
1.168 cvs 2730:
2731: UsePreconditions = mode & AMAYA_USE_PRECONDITIONS;
1.4 cvs 2732:
1.33 cvs 2733: AmayaLastHTTPErrorMsg [0] = EOS;
2734:
1.116 cvs 2735: if (urlName == NULL || docid == 0 || fileName == NULL
2736: || !TtaFileExist (fileName))
1.4 cvs 2737: /* no file to be uploaded */
2738: return HT_ERROR;
2739:
2740: /* do we support this protocol? */
1.7 cvs 2741: if (IsValidProtocol (urlName) == NO)
2742: {
2743: /* return error */
1.77 cvs 2744: TtaSetStatus (docid, 1,
2745: TtaGetMessage (AMAYA, AM_PUT_UNSUPPORTED_PROTOCOL),
1.7 cvs 2746: urlName);
2747: return HT_ERROR;
2748: }
1.116 cvs 2749:
2750: /* verify the file's size */
2751: #ifndef _WINDOWS
1.7 cvs 2752: if ((fd = open (fileName, O_RDONLY)) == -1)
1.116 cvs 2753: #else
1.137 cvs 2754: if ((fd = _open (fileName, _O_RDONLY | _O_BINARY)) == -1)
1.116 cvs 2755: #endif /* _WINDOWS */
1.7 cvs 2756: {
2757: /* if we could not open the file, exit */
2758: /*error msg here */
2759: return (HT_ERROR);
2760: }
1.4 cvs 2761:
2762: fstat (fd, &file_stat);
1.137 cvs 2763: # ifdef _WINDOWS
2764: _close (fd);
2765: # else /* _WINDOWS */
1.116 cvs 2766: close (fd);
1.137 cvs 2767: # endif /* _WINDOWS */
1.4 cvs 2768:
1.7 cvs 2769: if (file_stat.st_size == 0)
2770: {
2771: /* file was empty */
2772: /*errmsg here */
2773: return (HT_ERROR);
2774: }
1.116 cvs 2775:
2776: /* prepare the request context */
1.4 cvs 2777: if (THD_TRACE)
1.116 cvs 2778: fprintf (stderr, "file size == %u\n", (unsigned) file_stat.st_size);
1.4 cvs 2779:
2780: me = AHTReqContext_new (docid);
1.7 cvs 2781: if (me == NULL)
2782: {
1.168 cvs 2783: /* @@ need an error message here */
1.151 cvs 2784: TtaHandlePendingEvents ();
1.7 cvs 2785: return (HT_ERROR);
2786: }
1.116 cvs 2787:
1.4 cvs 2788: me->mode = mode;
2789: me->incremental_cbf = (TIcbf *) NULL;
2790: me->context_icbf = (void *) NULL;
2791: me->terminate_cbf = terminate_cbf;
2792: me->context_tcbf = context_tcbf;
2793: me->urlName = urlName;
1.116 cvs 2794: me->block_size = file_stat.st_size;
1.17 cvs 2795: /* select the parameters that distinguish a PUT from a GET/POST */
1.4 cvs 2796: me->method = METHOD_PUT;
2797: me->output = stdout;
1.17 cvs 2798: /* we are not expecting to receive any input from the server */
2799: me->outputfile = (char *) NULL;
1.4 cvs 2800:
1.134 cvs 2801: #ifdef _WINDOWS
2802: /* libwww's HTParse function doesn't take into account the drive name;
1.168 cvs 2803: so we sidestep it */
1.134 cvs 2804: fileURL = NULL;
2805: StrAllocCopy (fileURL, "file:");
2806: StrAllocCat (fileURL, fileName);
2807: #else
1.116 cvs 2808: fileURL = HTParse (fileName, "file:/", PARSE_ALL);
1.134 cvs 2809: #endif /* _WINDOWS */
1.168 cvs 2810: me->source = HTAnchor_findAddress (fileURL);
1.116 cvs 2811: HT_FREE (fileURL);
1.168 cvs 2812: me->dest = HTAnchor_findAddress (urlName);
1.169 cvs 2813: /* we memorize the anchor's parent @ as we use it a number of times
2814: in the following lines */
2815: dest_anc_parent = HTAnchor_parent (me->dest);
1.168 cvs 2816:
1.169 cvs 2817: /*
2818: ** Set the Content-Type of the file we are uploading
2819: */
2820: /* we try to use any content-type previosuly associated
2821: with the parent. If it doesn't exist, we try to guess it
2822: from the URL */
2823: tmp = HTAtom_name (HTAnchor_format (dest_anc_parent));
2824: if (!tmp || !strcmp (tmp, "www/unknown"))
2825: {
2826: HTAnchor_setFormat (dest_anc_parent,
2827: AHTGuessAtom_for (me->urlName, contentType));
2828: tmp = HTAtom_name (HTAnchor_format (dest_anc_parent));
2829: }
2830: /* .. and we give the same type to the source anchor */
2831: /* we go thru setOutputFormat, rather than change the parent's
2832: anchor, as that's the place that libwww expects it to be */
2833:
1.170 cvs 2834: HTAnchor_setFormat (HTAnchor_parent (me->source),
1.169 cvs 2835: HTAtom_for (tmp));
2836: HTRequest_setOutputFormat (me->request,
2837: HTAtom_for (tmp));
1.183 cvs 2838:
1.134 cvs 2839: /* define other request characteristics */
1.116 cvs 2840: #ifdef _WINDOWS
1.136 cvs 2841: HTRequest_setPreemptive (me->request, NO);
1.116 cvs 2842: #else
1.134 cvs 2843: HTRequest_setPreemptive (me->request, NO);
1.116 cvs 2844: #endif /* _WINDOWS */
2845:
1.151 cvs 2846: /*
2847: ** Make sure that the first request is flushed immediately and not
2848: ** buffered in the output buffer
2849: */
2850: if (mode & AMAYA_FLUSH_REQUEST)
2851: HTRequest_setFlush(me->request, YES);
1.168 cvs 2852:
2853: /* Should we use preconditions? */
1.172 cvs 2854: if (lost_update_check)
1.168 cvs 2855: {
1.172 cvs 2856: if (UsePreconditions)
2857: etag = HTAnchor_etag (HTAnchor_parent (me->dest));
2858:
2859: if (etag)
2860: {
2861: HTRequest_setPreconditions(me->request, HT_MATCH_THIS);
2862: }
2863: else
2864: {
2865: HTRequest_setPreconditions(me->request, HT_NO_MATCH);
2866: HTRequest_addAfter(me->request, check_handler, NULL, NULL, HT_ALL,
2867: HT_FILTER_MIDDLE, YES);
1.175 cvs 2868: HTRequest_addAfter (me->request, HTAuthFilter, "http://*", NULL,
2869: HT_NO_ACCESS, HT_FILTER_MIDDLE, YES);
2870: HTRequest_addAfter (me->request, HTAuthFilter, "http://*", NULL,
2871: HT_REAUTH, HT_FILTER_MIDDLE, YES);
2872: HTRequest_addAfter (me->request, HTAuthInfoFilter, "http://*", NULL,
2873: HT_ALL, HT_FILTER_MIDDLE, YES);
2874: HTRequest_addAfter (me->request, HTUseProxyFilter, "http://*", NULL,
2875: HT_USE_PROXY, HT_FILTER_MIDDLE, YES);
1.172 cvs 2876: }
1.168 cvs 2877: }
2878: else
2879: {
1.172 cvs 2880: /* don't use preconditions */
1.168 cvs 2881: HTRequest_setPreconditions(me->request, HT_NO_MATCH);
2882: }
1.151 cvs 2883:
1.136 cvs 2884: /* don't use the cache while saving a document */
2885: HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);
1.116 cvs 2886:
1.164 cvs 2887: /* Throw away any reponse body */
2888: /*
2889: HTRequest_setOutputStream (me->request, HTBlackHole());
2890: */
2891:
1.168 cvs 2892: /* prepare the URLname that will be displayed in the status bar */
1.74 cvs 2893: ChopURL (me->status_urlName, me->urlName);
2894: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REMOTE_SAVING),
1.168 cvs 2895: me->status_urlName);
1.114 cvs 2896:
1.164 cvs 2897: /* make the request */
1.172 cvs 2898: if (lost_update_check && (!UsePreconditions || !etag))
1.168 cvs 2899: status = HTHeadAnchor (me->dest, me->request);
2900: else
2901: status = HTPutDocumentAnchor (HTAnchor_parent (me->source), me->dest, me->request);
1.4 cvs 2902:
1.130 cvs 2903: if (status == YES && me->reqStatus != HT_ERR)
1.7 cvs 2904: {
1.168 cvs 2905: /* part of the stop button handler */
2906: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))
2907: status = LoopForStop (me);
1.15 cvs 2908: }
1.136 cvs 2909: if (!HTRequest_kill (me->request))
2910: AHTReqContext_delete (me);
1.168 cvs 2911:
1.116 cvs 2912: TtaHandlePendingEvents ();
1.90 cvs 2913:
1.130 cvs 2914: return (status == YES ? 0 : -1);
1.28 cvs 2915: }
1.4 cvs 2916:
1.5 cvs 2917: /*----------------------------------------------------------------------
1.138 cvs 2918: StopRequest
1.17 cvs 2919: stops (kills) all active requests associated with a docid
1.5 cvs 2920: ----------------------------------------------------------------------*/
1.4 cvs 2921: #ifdef __STDC__
2922: void StopRequest (int docid)
2923: #else
2924: void StopRequest (docid)
2925: int docid;
2926: #endif
2927: {
1.140 cvs 2928: if (Amaya && CanDoStop ())
1.138 cvs 2929: {
1.139 cvs 2930: #if 0 /* for later */
1.140 cvs 2931: AHTDocId_Status *docid_status;
2932: /* verify if there are any requests at all associated with docid */
1.138 cvs 2933: docid_status = (AHTDocId_Status *) GetDocIdStatus (docid,
2934: Amaya->docid_status);
2935: if (docid_status == (AHTDocId_Status *) NULL)
2936: return;
1.139 cvs 2937: #endif /* 0 */
1.138 cvs 2938: /* temporary call to stop all requests, as libwww changed its API */
2939: StopAllRequests (docid);
2940: }
2941: }
2942:
2943: /*----------------------------------------------------------------------
2944: StopAllRequests
2945: stops (kills) all active requests. We use the docid
2946: ----------------------------------------------------------------------*/
2947: #ifdef __STDC__
2948: void StopAllRequests (int docid)
2949: #else
1.140 cvs 2950: void StopAllRequests (docid)
1.138 cvs 2951: int docid;
2952: #endif
2953: {
1.4 cvs 2954: HTList *cur;
2955: AHTReqContext *me;
1.146 cvs 2956: static boolean lock_stop = 0;
1.161 cvs 2957: boolean async_flag;
1.116 cvs 2958:
1.138 cvs 2959: /* only do the stop if we're not being called while processing a
1.146 cvs 2960: request, and if we're not already dealing with a stop */
2961: if (Amaya && CanDoStop () && !lock_stop)
1.7 cvs 2962: {
1.100 cvs 2963: #ifdef DEBUG_LIBWWW
1.138 cvs 2964: fprintf (stderr, "StopRequest: number of Amaya requests "
2965: "before kill: %d\n", Amaya->open_requests);
1.100 cvs 2966: #endif /* DEBUG_LIBWWW */
1.150 cvs 2967: /* enter the critical section */
1.146 cvs 2968: lock_stop = TRUE;
1.164 cvs 2969: /* expire all outstanding timers */
2970: HTTimer_expireAll ();
1.160 cvs 2971: /* HTNet_killAll (); */
1.116 cvs 2972: cur = Amaya->reqlist;
2973: while ((me = (AHTReqContext *) HTList_nextObject (cur)))
2974: {
1.140 cvs 2975: if (AmayaIsAlive ())
1.160 cvs 2976: {
1.161 cvs 2977: #ifdef DEBUG_LIBWWW
1.163 cvs 2978: fprintf (stderr,"StopRequest: killing req %p, url %s, status %d\n", me, me->urlName, me->reqStatus);
1.161 cvs 2979: #endif /* DEBUG_LIBWWW */
2980:
1.165 cvs 2981: if (me->reqStatus != HT_END && me->reqStatus != HT_ABORT)
1.163 cvs 2982: {
2983: if ((me->mode & AMAYA_ASYNC)
2984: || (me->mode & AMAYA_IASYNC))
2985: async_flag = TRUE;
2986: else
2987: async_flag = FALSE;
2988:
1.165 cvs 2989: /* change the status to say that the request aborted */
2990: me->reqStatus = HT_ABORT;
2991:
1.163 cvs 2992: /* kill the request, using the appropriate function */
2993: if (me->request->net)
2994: HTNet_killPipe (me->request->net);
2995: else
2996: {
1.160 cvs 2997: if (me->terminate_cbf)
2998: (*me->terminate_cbf) (me->docid, -1, me->urlName,
2999: me->outputfile,
3000: me->content_type,
3001: me->context_tcbf);
1.164 cvs 3002:
3003: if (async_flag)
1.165 cvs 3004: /* explicitly free the request context for async
3005: requests. The sync requests context is freed by LoopForStop */
1.164 cvs 3006: AHTReqContext_delete (me);
1.160 cvs 3007: }
1.163 cvs 3008: cur = Amaya->reqlist;
3009: }
1.142 cvs 3010: #ifndef _WINDOWS
3011: #ifdef WWW_XWINDOWS
1.140 cvs 3012: /* to be on the safe side, remove all outstanding X events */
1.160 cvs 3013: else
3014: RequestKillAllXtevents (me);
1.142 cvs 3015: #endif /* WWW_XWINDOWS */
3016: #endif /* !_WINDOWS */
1.160 cvs 3017: }
1.116 cvs 3018: }
1.150 cvs 3019: /* Delete remaining channels */
3020: HTChannel_safeDeleteAll ();
3021: /* exit the critical section */
1.148 cvs 3022: lock_stop = FALSE;
1.100 cvs 3023: #ifdef DEBUG_LIBWWW
1.138 cvs 3024: fprintf (stderr, "StopRequest: number of Amaya requests "
3025: "after kill: %d\n", Amaya->open_requests);
1.100 cvs 3026: #endif /* DEBUG_LIBWWW */
1.138 cvs 3027: }
3028: } /* StopAllRequests */
1.17 cvs 3029:
3030:
1.105 cvs 3031: /*----------------------------------------------------------------------
3032: AmayaIsAlive
1.140 cvs 3033: returns the value of the AmayaAlive_flag
1.105 cvs 3034: ----------------------------------------------------------------------*/
3035: #ifdef __STDC__
3036: boolean AmayaIsAlive (void)
3037: #else
3038: boolean AmayaIsAlive ()
3039: #endif /* _STDC_ */
3040: {
1.140 cvs 3041: return AmayaAlive_flag;
3042: }
3043:
3044: /*----------------------------------------------------------------------
3045: CanDoStop
3046: returns the value of the CanDoStop flag
3047: ----------------------------------------------------------------------*/
3048: #ifdef __STDC__
3049: boolean CanDoStop (void)
3050: #else
3051: boolean CanDoStop ()
3052: #endif /* _STDC_ */
3053: {
3054: return CanDoStop_flag;
3055: }
3056:
3057: /*----------------------------------------------------------------------
3058: CanDoStop_set
3059: sets the value of the CanDoStop flag
3060: ----------------------------------------------------------------------*/
3061: #ifdef __STDC__
3062: void CanDoStop_set (boolean value)
3063: #else
3064: void CanDoStop (value)
3065: boolean value;
3066: #endif /* _STDC_ */
3067: {
3068: CanDoStop_flag = value;
1.176 cvs 3069: }
3070:
3071: #ifdef __STDC__
3072: void libwww_updateNetworkConf (int status)
3073: #else
3074: void libwww_updateNetworkConf (status)
3075: int status;
3076: #endif /*__STDC__*/
3077: {
3078: /* @@@ the docid parameter isn't used... clean it up */
3079: int docid = 1;
3080:
3081: /* first, stop all current requests, as the network
3082: may make some changes */
3083: StopAllRequests (docid);
3084:
3085: if (status & AMAYA_PROXY_RESTART)
3086: {
3087: HTProxy_deleteAll ();
3088: ProxyInit ();
3089: }
3090:
3091: if (status & AMAYA_CACHE_RESTART)
3092: {
3093: clear_cachelock ();
3094: HTCacheTerminate ();
3095: HTCacheMode_setEnabled (NO);
3096: CacheInit ();
3097: }
1.105 cvs 3098: }
1.116 cvs 3099:
1.69 cvs 3100: #endif /* AMAYA_JAVA */
1.77 cvs 3101:
1.116 cvs 3102: /*
3103: end of Module query.c
3104: */
1.140 cvs 3105:
3106:
3107:
3108:
3109:
3110:
1.17 cvs 3111:
3112:
Webmaster