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