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