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