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