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