Annotation of Amaya/amaya/query.c, revision 1.77
1.14 cvs 1: /*
2: *
3: * (c) COPYRIGHT MIT and INRIA, 1996.
4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
1.4 cvs 7:
1.19 cvs 8: /*
9: * query.c : contains all the functions for requesting iand publishing
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.75 cvs 14: * R. Guetari/J. Kahan Windows 95/NT routines
1.19 cvs 15: */
1.17 cvs 16:
1.44 cvs 17: #ifndef AMAYA_JAVA
18:
1.12 cvs 19: /* Amaya includes */
1.25 cvs 20: #define THOT_EXPORT extern
1.4 cvs 21: #include "amaya.h"
1.70 cvs 22: #ifdef _WINDOWS
23: #include <fcntl.h>
24: #endif /* _WINDOWS */
1.7 cvs 25:
1.4 cvs 26: #if defined(__svr4__)
27: #define CATCH_SIG
28: #endif
29:
30: /* local structures coming from libwww and which are
1.17 cvs 31: not found in any .h file
1.7 cvs 32: */
1.68 cvs 33:
1.7 cvs 34: struct _HTStream
35: {
1.15 cvs 36: const HTStreamClass *isa;
37: FILE *fp;
1.45 cvs 38: BOOL leave_open; /* Close file when TtaFreeMemory? */
1.15 cvs 39: char *end_command; /* Command to execute */
40: BOOL remove_on_close; /* Remove file? */
41: char *filename; /* Name of file */
42: HTRequest *request; /* saved for callback */
43: HTRequestCallback *callback;
1.7 cvs 44: };
45:
1.15 cvs 46:
1.7 cvs 47: struct _HTError
48: {
49: HTErrorElement element; /* Index number into HTError */
50: HTSeverity severity; /* A la VMS */
51: BOOL ignore; /* YES if msg should not go to user */
52: void *par; /* Explanation, e.g. filename */
53: int length; /* For copying by generic routine */
54: char *where; /* Which function */
55: };
56:
57:
58: struct _HTHost
59: {
60: char *hostname; /* name of host + optional port */
61: time_t ntime; /* Creation time */
62: char *type; /* Peer type */
63: int version; /* Peer version */
64: HTMethod methods; /* Public methods (bit-flag) */
65: char *server; /* Server name */
66: char *user_agent; /* User Agent */
67: char *range_units; /* Acceptable range units */
68: HTTransportMode mode; /* Supported mode */
69: HTChannel *channel; /* Persistent channel */
70: HTList *pipeline; /* Pipe line of net objects */
71: HTList *pending; /* List of pending Net objects */
72: time_t expires; /* Persistent channel expires time */
73: };
1.4 cvs 74:
75: /* Type definitions and global variables etc. local to this module */
76:
1.17 cvs 77: /*----------------------------------------------------------------------*/
78:
1.4 cvs 79: /*** private variables ***/
1.17 cvs 80:
1.4 cvs 81: static HTList *converters = NULL; /* List of global converters */
1.27 cvs 82: static HTList *acceptTypes = NULL; /* List of types for the Accept header */
1.4 cvs 83: static HTList *encodings = NULL;
1.16 cvs 84: static int object_counter = 0; /* loaded objects counter */
1.24 cvs 85: static boolean AmayaIsAlive;
1.4 cvs 86:
1.15 cvs 87: #include "answer_f.h"
88: #include "query_f.h"
89: #include "AHTURLTools_f.h"
90: #include "AHTBridge_f.h"
91: #include "AHTMemConv_f.h"
92: #include "AHTFWrite_f.h"
1.4 cvs 93:
1.70 cvs 94: #ifdef _WINDOWS
95: #ifdef __STDC__
96: int WIN_Activate_Request (HTRequest* , HTAlertOpcode, int, const char*, void*, HTAlertPar*);
97: #else
98: int WIN_Activate_Request ();
99: #endif /* __STDC__ */
100: #endif /* _WINDOWS */
1.15 cvs 101:
102: /*----------------------------------------------------------------------
1.17 cvs 103: GetDocIdStatus
104: gets the status associated to a docid
1.15 cvs 105: ----------------------------------------------------------------------*/
106: #ifdef __STDC__
107: AHTDocId_Status *GetDocIdStatus (int docid, HTList * documents)
108: #else
109: AHTDocID_Status *GetDocIdStatus (docid, documents)
110: int docid;
111: HTList *documents;
112:
113: #endif
114: {
115: AHTDocId_Status *me;
116: HTList *cur;
117:
118: if (documents)
119: {
120: cur = documents;
121:
122: while ((me = (AHTDocId_Status *) HTList_nextObject (cur)))
123: {
124: if (me->docid == docid)
125: return (me);
1.18 cvs 126: }
127: }
1.15 cvs 128: return (AHTDocId_Status *) NULL;
129:
130: }
131:
1.5 cvs 132: /*----------------------------------------------------------------------
1.27 cvs 133: AHTGuessAtom_for
134: Converts an Amaya type descriptor into the equivalent MIME type.
135: ----------------------------------------------------------------------*/
136: #ifdef __STDC__
137: static HTAtom *AHTGuessAtom_for (char *urlName, PicType contentType)
138: #else
139: static HTAtom *AHTGuessAtom_for (urlName, contentType)
140: char *urlName;
141: PicType contentType;
142: #endif
143: {
144: HTAtom *atom;
145: char *filename;
146: HTEncoding enc;
147: HTEncoding cte;
148: HTLanguage lang;
1.50 cvs 149: double quality = 1.0;
1.27 cvs 150:
151: switch (contentType)
152: {
153: case xbm_type:
154: atom = HTAtom_for("image/xbm");
155: break;
156: case eps_type:
1.35 cvs 157: atom = HTAtom_for("application/postscript");
1.27 cvs 158: break;
159: case xpm_type:
160: atom = HTAtom_for("image/xpm");
161: break;
162: case gif_type:
163: atom = HTAtom_for("image/gif");
164: break;
165: case jpeg_type:
166: atom = HTAtom_for("image/jpeg");
167: break;
168: case png_type:
169: atom = HTAtom_for("image/png");
170: break;
171: case unknown_type:
172: default:
173: /*
174: ** Amaya could not detect the type, so
175: ** we try to use the filename's suffix to do so.
176: */
1.45 cvs 177: filename = AmayaParseUrl (urlName, "", AMAYA_PARSE_PATH | AMAYA_PARSE_PUNCTUATION);
1.27 cvs 178: HTBind_getFormat (filename, &atom, &enc, &cte, &lang, &quality);
1.45 cvs 179: TtaFreeMemory (filename);
1.27 cvs 180: if (atom == WWW_UNKNOWN)
181: /*
182: ** we could not identify the suffix, so we assign it
183: ** a default type
184: */
185: atom = HTAtom_for ("text/html");
186: break;
187: }
188:
189: return atom;
190: }
191:
192: /*----------------------------------------------------------------------
1.17 cvs 193: AHTReqContext_new
194: create a new Amaya Context Object and update the global Amaya
195: request status.
1.5 cvs 196: ----------------------------------------------------------------------*/
1.4 cvs 197: #ifdef __STDC__
198: static AHTReqContext *AHTReqContext_new (int docid)
199: #else
200: static AHTReqContext *AHTReqContext_new (docid)
201: int docid;
202:
203: #endif
204: {
205: AHTReqContext *me;
206: AHTDocId_Status *docid_status;
207:
208: if ((me = (AHTReqContext *) TtaGetMemory (sizeof (AHTReqContext))) == NULL)
209: outofmem (__FILE__, "Context_new");
210:
211: /* Bind the Context object together with the Request Object */
212:
213: me->request = HTRequest_new ();
1.17 cvs 214:
1.4 cvs 215: /* Initialize the other members of the structure */
1.17 cvs 216: me->reqStatus = HT_NEW; /* initial status of a request */
1.4 cvs 217: me->output = NULL;
1.51 cvs 218: # ifndef _WINDOWS
1.4 cvs 219: me->read_xtinput_id = (XtInputId) NULL;
220: me->write_xtinput_id = (XtInputId) NULL;
221: me->except_xtinput_id = (XtInputId) NULL;
1.51 cvs 222: # endif
1.4 cvs 223: me->docid = docid;
224: HTRequest_setMethod (me->request, METHOD_GET);
225: HTRequest_setOutputFormat (me->request, WWW_SOURCE);
226: HTRequest_setContext (me->request, me);
227: me->read_ops = 0;
228: me->write_ops = 0;
229: me->except_ops = 0;
1.36 cvs 230: /* experimental */
231: me->read_sock = INVSOC;
232: me->write_sock = INVSOC;
233: me->except_sock = INVSOC;
1.4 cvs 234:
235: /* Update the global context */
236: HTList_appendObject (Amaya->reqlist, (void *) me);
237:
238: docid_status = GetDocIdStatus (docid, Amaya->docid_status);
239:
1.7 cvs 240: if (docid_status == NULL)
241: {
242: docid_status = (AHTDocId_Status *) TtaGetMemory (sizeof (AHTDocId_Status));
243: docid_status->docid = docid;
244: docid_status->counter = 1;
245: HTList_addObject (Amaya->docid_status, (void *) docid_status);
246: }
247: else
1.4 cvs 248: docid_status->counter++;
249:
250:
251: Amaya->open_requests++;
252:
253: /* error stream handling */
254: me->error_stream = (char *) NULL;
255: me->error_stream_size = 0;
1.74 cvs 256:
257: #ifdef DEBUG_LIBWWW
258: fprintf (stderr, "AHTReqContext_new: Created object %p\n", me);
259: #endif
1.4 cvs 260: return me;
1.74 cvs 261:
1.4 cvs 262: }
263:
1.5 cvs 264: /*----------------------------------------------------------------------
1.17 cvs 265: AHTReqContext_delete
266: Delete an Amaya Context Object and update the global Amaya request
267: status.
1.5 cvs 268: ----------------------------------------------------------------------*/
1.4 cvs 269:
270: #ifdef __STDC__
1.15 cvs 271: boolean AHTReqContext_delete (AHTReqContext * me)
1.4 cvs 272: #else
1.15 cvs 273: boolean AHTReqContext_delete (me)
1.4 cvs 274: AHTReqContext *me;
275:
276: #endif
277: {
278: AHTDocId_Status *docid_status;
279:
1.7 cvs 280: if (me)
281: {
1.4 cvs 282:
1.74 cvs 283: #ifdef DEBUG_LIBWWW
284: fprintf (stderr, "AHTReqContext_delete: Deleting object %p\n", me);
285: #endif
286:
1.7 cvs 287: if (Amaya->reqlist)
288: HTList_removeObject (Amaya->reqlist, (void *) me);
1.4 cvs 289:
1.7 cvs 290: docid_status = GetDocIdStatus (me->docid, Amaya->docid_status);
1.4 cvs 291:
1.7 cvs 292: if (docid_status)
293: {
294: docid_status->counter--;
295:
296: if (docid_status->counter == 0)
297: {
298: HTList_removeObject (Amaya->docid_status, (void *) docid_status);
299: TtaFreeMemory ((void *) docid_status);
300: }
301: }
302: HTRequest_delete (me->request);
1.4 cvs 303:
1.7 cvs 304: if (me->error_stream != (char *) NULL)
1.70 cvs 305: HT_FREE (me->error_stream);
306: # ifndef _WINDOWS
307: # ifdef WWW_XWINDOWS
1.21 cvs 308: if (me->read_xtinput_id || me->write_xtinput_id ||
309: me->except_xtinput_id)
310: RequestKillAllXtevents(me);
1.70 cvs 311: # endif /* WWW_XWINDOWS */
312: # endif /* !_WINDOWS */
1.74 cvs 313:
314: if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC))
315: /* for the ASYNC mode, free the memory we allocated in GetObjectWWW
316: or in PutObjectWWW */
317: {
318: TtaFreeMemory (me->urlName);
319: me->urlName = NULL;
320: TtaFreeMemory (me->outputfile);
321: me->outputfile = NULL;
322: }
323:
1.7 cvs 324: TtaFreeMemory ((void *) me);
1.4 cvs 325:
1.7 cvs 326: Amaya->open_requests--;
1.4 cvs 327:
1.15 cvs 328: return TRUE;
1.4 cvs 329:
1.7 cvs 330: }
1.15 cvs 331: return FALSE;
1.4 cvs 332: }
333:
334:
1.15 cvs 335: /*----------------------------------------------------------------------
336: AHTUpload_callback
1.17 cvs 337: callback handler for executing the PUT command
1.15 cvs 338: ----------------------------------------------------------------------*/
1.4 cvs 339: #ifdef __STDC__
340: static int AHTUpload_callback (HTRequest * request, HTStream * target)
341: #else
342: static int AHTUpload_callback (request, target)
343: HTRequest *request;
344: HTStream *target;
345:
346: #endif
347: {
348: AHTReqContext *me = HTRequest_context (request);
1.7 cvs 349: HTParentAnchor *entity = HTRequest_entityAnchor (request);
350: int len = HTAnchor_length (entity);
1.4 cvs 351: int status;
352:
353: /* Send the data down the pipe */
1.7 cvs 354:
1.4 cvs 355: status = (*target->isa->put_block) (target, me->mem_ptr, len);
356:
1.7 cvs 357: if (status == HT_LOADED || status == HT_OK)
358: {
1.13 cvs 359: if (PROT_TRACE)
360: HTTrace ("Posting Data Target is SAVED\n");
361: (*target->isa->flush) (target);
362: return (HT_LOADED);
1.7 cvs 363: }
364: if (status == HT_WOULD_BLOCK)
365: {
366: if (PROT_TRACE)
367: HTTrace ("Posting Data Target WOULD BLOCK\n");
1.74 cvs 368: #ifdef _WINDOWS
369: return HT_CONTINUE;
370: #else
371: return HT_WOULD_BLOCK;
372: #endif /* _WINDOWS */
373:
1.7 cvs 374: return HT_WOULD_BLOCK;
375: }
376: else if (status == HT_PAUSE)
377: {
378: if (PROT_TRACE)
379: HTTrace ("Posting Data Target PAUSED\n");
380: return HT_PAUSE;
381: }
382: else if (status > 0)
383: { /* Stream specific return code */
384: if (PROT_TRACE)
385: HTTrace ("Posting Data. Target returns %d\n", status);
386: return status;
387: }
388: else
389: { /* we have a real error */
390: if (PROT_TRACE)
391: HTTrace ("Posting Data Target ERROR %d\n", status);
392: return status;
393: }
1.4 cvs 394: }
395:
1.5 cvs 396: /*----------------------------------------------------------------------
1.17 cvs 397: Thread_deleteAll
398: this function deletes the whole list of active threads.
1.5 cvs 399: ----------------------------------------------------------------------*/
1.4 cvs 400: #ifdef __STDC__
401: static void Thread_deleteAll (void)
402: #else
403: static void Thread_deleteAll ()
404: #endif
405: {
1.21 cvs 406: HTList *cur;
407: AHTReqContext *me;
408: AHTDocId_Status *docid_status;
409:
1.74 cvs 410: if (Amaya && Amaya->reqlist)
411: {
412: if (Amaya->open_requests > 0)
413: #ifdef DEBUG_LIBWWW
414: fprintf (stderr, "Thread_deleteAll: Killing %d outstanding "
415: "requests\n", Amaya->open_requests);
416: #endif
417: {
418: cur = Amaya->reqlist;
419:
420: HTNet_killAll ();
421: /* erase the requests */
422: while ((me = (AHTReqContext *) HTList_removeLastObject (cur)))
423: {
424: if (me->request)
425: {
1.70 cvs 426: # ifndef _WINDOWS
1.74 cvs 427: RequestKillAllXtevents (me);
1.70 cvs 428: # endif /* !_WINDOWS */
1.74 cvs 429: AHTReqContext_delete (me);
430: }
431: } /* while */
432:
433: /* erase the docid_status entities */
434: while ((docid_status = (AHTDocId_Status *) HTList_removeLastObject ((void *) Amaya->docid_status)))
435: TtaFreeMemory ((void *) docid_status);
436:
437: } /* if */
438: }
1.4 cvs 439: }
440:
1.5 cvs 441: /*----------------------------------------------------------------------
1.17 cvs 442: redirection_handler
443: this function is registered to handle permanent and temporary
444: redirections.
445: ----------------------------------------------------------------------*/
1.4 cvs 446: #ifdef __STDC__
1.7 cvs 447: static int redirection_handler (HTRequest * request, HTResponse * response, void *param, int status)
1.4 cvs 448: #else
449: static int redirection_handler (request, context, status)
450: HTRequest *request;
451: HTResponse *response;
452: void *param;
453: int status;
454:
455: #endif
456: {
457:
458: char *ref;
459: HTAnchor *new_anchor = HTResponse_redirection (response);
1.7 cvs 460: AHTReqContext *me = HTRequest_context (request);
1.4 cvs 461: HTMethod method = HTRequest_method (request);
462:
463:
1.7 cvs 464: if (!new_anchor)
465: {
466: if (PROT_TRACE)
467: HTTrace ("Redirection. No destination\n");
468: return HT_OK;
469: }
1.4 cvs 470:
471: /*
472: ** Only do redirect on GET and HEAD
473: */
1.7 cvs 474: if (!HTMethod_isSafe (method))
475: {
476: HTAlertCallback *prompt = HTAlert_find (HT_A_CONFIRM);
477:
478: if (prompt)
479: {
480: if ((*prompt) (request, HT_A_CONFIRM, HT_MSG_REDIRECTION,
481: NULL, NULL, NULL) != YES)
482: return HT_ERROR;
483: }
484: }
1.4 cvs 485:
486: /*
487: ** Start new request with the redirect anchor found in the headers.
488: ** Note that we reuse the same request object which means that we must
489: ** keep this around until the redirected request has terminated. It also
490: ** allows us in an easy way to keep track of the number of redirections
491: ** so that we can detect endless loops.
492: */
1.17 cvs 493:
1.7 cvs 494: if (HTRequest_doRetry (request))
495: {
496: /* Verify if this is not redundant */
497:
498: /* do we need to normalize the URL? */
499: if (strncmp (new_anchor->parent->address, "http:", 5))
500: {
501: /* Yes, so we use the pre-redirection anchor as a base name */
1.74 cvs 502: ref = AmayaParseUrl (new_anchor->parent->address,
503: me->urlName, AMAYA_PARSE_ALL);
1.7 cvs 504: if (ref)
505: {
1.74 cvs 506: TtaFreeMemory (new_anchor->parent->address);
507: new_anchor->parent->address = ref;
1.7 cvs 508: }
509: }
510:
511: /* update the current file name */
1.21 cvs 512: if (strlen (new_anchor->parent->address) > (MAX_LENGTH - 2))
1.7 cvs 513: {
1.74 cvs 514: strncpy (me->urlName, new_anchor->parent->address,
515: MAX_LENGTH - 1);
1.21 cvs 516: me->urlName[MAX_LENGTH - 1] = EOS;
1.7 cvs 517: }
518: else
1.74 cvs 519: strcpy (me->urlName, new_anchor->parent->address);
1.7 cvs 520:
1.38 cvs 521: ChopURL (me->status_urlName, me->urlName);
522:
1.7 cvs 523: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_RED_FETCHING),
1.38 cvs 524: me->status_urlName);
1.7 cvs 525:
526: /* Start request with new credentials */
1.64 cvs 527:
1.69 cvs 528: if (me->output) {
1.74 cvs 529: #ifdef DEBUG_LIBWWW
530: fprintf (stderr, "redirection_handler: New URL is %s, closing "
531: "FILE %p\n", me->urlName, me->output);
532: #endif
1.69 cvs 533: AHTFWriter_FREE (request->output_stream);
1.74 cvs 534: if (me->output != stdout) { /* Are we writing to a file? */
535: fclose (me->output);
536: me->output = NULL;
537: }
1.64 cvs 538: }
1.68 cvs 539:
1.69 cvs 540: me->reqStatus = HT_NEW; /* reset the status */
1.7 cvs 541: if (me->method == METHOD_PUT || me->method == METHOD_POST) /* PUT, POST etc. */
1.74 cvs 542: status = HTLoadAbsolute (me->urlName, request);
1.7 cvs 543: else
1.74 cvs 544: HTLoadAnchor (new_anchor, request);
1.7 cvs 545: }
546: else
1.68 cvs 547: {
1.74 cvs 548: HTRequest_addError (request, ERR_FATAL, NO, HTERR_MAX_REDIRECT,
549: NULL, 0, "HTRedirectFilter");
550: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REDIRECTIONS_LIMIT),
551: NULL);
552: if (me->error_html)
553: DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR;
554: /* so that we can show the error message */
1.68 cvs 555: }
556:
1.4 cvs 557: /*
1.74 cvs 558: ** By returning HT_ERROR we make sure that this is the last handler to be
559: ** called. We do this as we don't want any other filter to delete the
560: ** request object now when we have just started a new one ourselves
561: */
1.4 cvs 562: return HT_ERROR;
563: }
564:
1.5 cvs 565: /*----------------------------------------------------------------------
1.17 cvs 566: terminate_handler
567: this function is registered to handle the result of the request
1.5 cvs 568: ----------------------------------------------------------------------*/
1.4 cvs 569: #if __STDC__
1.7 cvs 570: static int terminate_handler (HTRequest * request, HTResponse * response, void *context, int status)
1.4 cvs 571: #else
572: static int terminate_handler (request, response, context, status)
573: HTRequest *request;
574: HTResponse *response;
575: void *context;
576: int status;
577: #endif
578: {
579: AHTReqContext *me = (AHTReqContext *) HTRequest_context (request);
1.13 cvs 580: boolean error_flag;
1.28 cvs 581: char msg_status[10];
582: HTError *error;
1.30 cvs 583: HTErrorElement errorElement;
1.29 cvs 584: HTList *cur;
1.4 cvs 585:
586: if (!me)
1.74 cvs 587: return HT_OK; /* not an Amaya request */
588:
1.77 ! cvs 589: if (!AmayaIsAlive) /* if Amaya was killed, treat with this */
! 590: me->reqStatus = HT_ABORT; /* request as if it were issued by a Stop */
! 591: /* button event */
1.74 cvs 592:
1.77 ! cvs 593: if (status == HT_LOADED ||
! 594: status == HT_CREATED ||
! 595: status == HT_NO_DATA)
1.74 cvs 596: error_flag = FALSE;
1.13 cvs 597: else
1.74 cvs 598: error_flag = TRUE;
599:
1.4 cvs 600: /* output any errors from the server */
1.74 cvs 601:
1.77 ! cvs 602: /*
1.74 cvs 603: ** me->output = output file which will receive an html file
604: ** me->error_html = yes, output HTML errors in the screen
605: ** request->error_stack == if there are any errors, they will be here
606: ** me->error_stream_size If it's != 0 means an error message has already
607: ** been written to the stack
608: */
609:
1.4 cvs 610: /* First, we verify if there are any errors and if they are not
1.17 cvs 611: ** yet written to the error stack. If no, then let's try to write them
612: ** ourselves
613: */
1.74 cvs 614:
615: #ifdef DEBUG_LIBWWW
616: fprintf (stderr, "terminate_handler: URL is "
617: "%s, closing FILE %p status is %d\n", me->urlName, me->output,
618: status);
1.69 cvs 619: #endif
1.74 cvs 620:
1.69 cvs 621: if (me->output && me->output != stdout)
622: {
1.74 cvs 623: /* we are writing to a file */
624: if (me->reqStatus != HT_ABORT)
625: { /* if the request was not aborted and */
626: if (error_flag)
627: { /* there were some errors */
628: if (me->error_html == TRUE)
629: { /* and we want to print errors */
630: if (me->error_stream_size == 0)/* and the stream is empty */
631: AHTError_MemPrint (request); /* copy errors from
632: **the error stack
1.77 ! cvs 633: ** into the error stream */
1.74 cvs 634: if (me->error_stream)
635: { /* if the stream is non-empty */
636: fprintf (me->output, me->error_stream);/* output the errors */
637: error_flag = FALSE; /* show it in the HTML window */
638: }
639: else
640: me->reqStatus = HT_ERR; /* we did not get an error msg,
641: ** so just markerror */
642: }
643: else
644: me->reqStatus = HT_ERR; /* we don't want to print the error */
645: } /* if error_stack */
646: } /* if != HT_ABORT */
647: fclose (me->output);
648: me->output = NULL;
1.69 cvs 649: }
1.7 cvs 650: else
651: {
1.74 cvs 652: /* We must be doing a PUT. Verify if there was an error */
653: if (error_flag)
654: me->reqStatus = HT_ERR;
1.7 cvs 655: } /* if me-output */
1.74 cvs 656:
1.17 cvs 657: /* Second Step: choose a correct treatment in function of the request's
658: being associated with an error, with an interruption, or with a
659: succesful completion */
1.74 cvs 660:
1.13 cvs 661: if (!error_flag && me->reqStatus != HT_ERR
1.7 cvs 662: && me->reqStatus != HT_ABORT)
663: {
1.74 cvs 664: me->reqStatus = HT_END; /* no errors */
665: if (me->terminate_cbf)
666: (*me->terminate_cbf) ((AHTReqContext *) me,
667: HT_LOADED);
1.7 cvs 668: }
669: else if (me->reqStatus == HT_ABORT)
1.21 cvs 670: /* either the application ended or the user pressed the stop
671: button. We erase the incoming file, if it exists */
1.7 cvs 672: {
1.74 cvs 673: if (me->outputfile && me->outputfile[0] != EOS)
674: {
675: TtaFileUnlink (me->outputfile);
676: me->outputfile[0] = EOS;
677: }
1.7 cvs 678: }
679: else if (me->reqStatus == HT_ERR)
680: {
1.74 cvs 681: /* there was an error */
682: if (me->terminate_cbf)
683: (*me->terminate_cbf) ((AHTReqContext *) me,
684: HT_ERROR);
685:
686: if (me->outputfile && me->outputfile[0] != EOS)
687: {
688: TtaFileUnlink (me->outputfile);
689: me->outputfile[0] = EOS;
690: }
1.4 cvs 691: }
1.13 cvs 692: else if (error_flag &&
1.7 cvs 693: (me->reqStatus == HT_BUSY || me->reqStatus == HT_WAITING))
694: {
1.74 cvs 695: /* there was an error */
696: if (me->terminate_cbf)
697: (*me->terminate_cbf) ((AHTReqContext *) me,
698: HT_ERROR);
699:
700: if (me->outputfile && me->outputfile[0] != EOS)
701: {
702: TtaFileUnlink (me->outputfile);
703: me->outputfile[0] = EOS;
704: me->reqStatus = HT_ERR;
705: }
1.7 cvs 706: } /* if-else HT_END, HT_ABORT, HT_ERROR */
1.74 cvs 707:
1.34 cvs 708: /* don't remove or Xt will hang up during the PUT */
1.74 cvs 709:
1.28 cvs 710: if (AmayaIsAlive && ((me->method == METHOD_POST) ||
711: (me->method == METHOD_PUT)))
1.7 cvs 712: {
1.28 cvs 713: /* output the status of the request */
714: if (status == 200)
1.74 cvs 715: TtaSetStatus (me->docid, 1,
716: TtaGetMessage (AMAYA, AM_REQUEST_SUCCEEDED),
717: me->status_urlName);
1.28 cvs 718: else if (status == 201)
1.74 cvs 719: TtaSetStatus (me->docid, 1,
720: TtaGetMessage (AMAYA, AM_CREATED_NEW_REMOTE_RESSOURCE),
721: me->status_urlName);
1.28 cvs 722: else if (status == 204 && me->method == METHOD_PUT)
1.74 cvs 723: TtaSetStatus (me->docid, 1,
724: TtaGetMessage (AMAYA, AM_UPDATED_REMOTE_RESSOURCE),
725: me->status_urlName);
1.28 cvs 726: else if (status == 204 && me->method == METHOD_PUT)
1.74 cvs 727: TtaSetStatus (me->docid, 1,
728: TtaGetMessage (AMAYA, AM_NO_DATA),
729: (char *) NULL);
1.28 cvs 730: else if (status == -400 || status == 505)
1.34 cvs 731: {
1.74 cvs 732: TtaSetStatus (me->docid, 1,
733: TtaGetMessage (AMAYA,
734: AM_SERVER_DID_NOT_UNDERSTAND_REQ_SYNTAX),
735: (char *) NULL);
736: sprintf (AmayaLastHTTPErrorMsg,
737: TtaGetMessage (AMAYA,
738: AM_SERVER_DID_NOT_UNDERSTAND_REQ_SYNTAX));
1.34 cvs 739: }
740: else if (status == -401)
741: {
1.28 cvs 742: TtaSetStatus (me->docid, 1,
1.74 cvs 743: TtaGetMessage (AMAYA,
744: AM_AUTHENTICATION_FAILURE),
745: me->status_urlName);
746: sprintf (AmayaLastHTTPErrorMsg,
747: TtaGetMessage (AMAYA, AM_AUTHENTICATION_FAILURE),
748: me->status_urlName);
1.34 cvs 749: }
1.28 cvs 750: else if (status == -403)
1.34 cvs 751: {
752: TtaSetStatus (me->docid, 1,
1.74 cvs 753: TtaGetMessage (AMAYA, AM_FORBIDDEN_ACCESS),
754: me->status_urlName);
755: sprintf (AmayaLastHTTPErrorMsg,
756: TtaGetMessage (AMAYA, AM_FORBIDDEN_ACCESS),
757: me->urlName);
1.34 cvs 758: }
1.28 cvs 759: else if (status == -405)
1.34 cvs 760: {
1.74 cvs 761: TtaSetStatus (me->docid, 1,
762: TtaGetMessage (AMAYA, AM_METHOD_NOT_ALLOWED),
763: (char *) NULL);
764: sprintf(AmayaLastHTTPErrorMsg,
765: TtaGetMessage (AMAYA, AM_METHOD_NOT_ALLOWED));
1.34 cvs 766: }
1.28 cvs 767: else if (status == -1)
768: {
1.30 cvs 769: /*
770: ** Here we deal with errors for which libwww does not
771: ** return a correct status code
772: */
1.29 cvs 773: cur = HTRequest_error (request);
774: error = (HTError *) HTList_nextObject (cur);
1.33 cvs 775: if (error == (HTError *) NULL)
776: /* there's no error context */
777: {
778: sprintf (msg_status, "%d", status);
1.74 cvs 779: TtaSetStatus (me->docid, 1,
780: TtaGetMessage (AMAYA, AM_UNKNOWN_XXX_STATUS),
781: msg_status);
782: sprintf (AmayaLastHTTPErrorMsg,
783: TtaGetMessage (AMAYA, AM_UNKNOWN_XXX_STATUS),
784: msg_status);
1.69 cvs 785: return (HT_OK);
1.33 cvs 786: }
1.74 cvs 787:
788: /* there's an error context */
789: errorElement = error->element;
790:
1.30 cvs 791: if (errorElement == HTERR_NOT_IMPLEMENTED)
1.28 cvs 792: {
1.74 cvs 793: TtaSetStatus (me->docid, 1,
794: TtaGetMessage (AMAYA, AM_SERVER_NOT_IMPLEMENTED_501_ERROR),
795: (char *) NULL);
796: sprintf (AmayaLastHTTPErrorMsg,
797: TtaGetMessage (AMAYA, AM_SERVER_NOT_IMPLEMENTED_501_ERROR));
1.30 cvs 798: status = -501;
799: }
800: else if (errorElement == HTERR_INTERNAL)
801: {
1.31 cvs 802: if ((error->length > 0) && (error->length <= 25) &&
1.34 cvs 803: (error->par) && (((char *) error->par)[0] != EOS))
804: {
1.74 cvs 805: TtaSetStatus (me->docid, 1,
806: TtaGetMessage (AMAYA, AM_SERVER_INTERNAL_ERROR_500_CAUSE),
807: (char *) (error->par));
808: sprintf (AmayaLastHTTPErrorMsg,
809: TtaGetMessage (AMAYA, AM_SERVER_INTERNAL_ERROR_500_CAUSE),
810: (char *) (error->par));
1.34 cvs 811: }
1.30 cvs 812: else
1.34 cvs 813: {
1.74 cvs 814: TtaSetStatus (me->docid, 1,
815: TtaGetMessage (AMAYA, AM_SERVER_INTERNAL_ERROR_500_NO_CAUSE),
816: (char *) NULL);
817: sprintf (AmayaLastHTTPErrorMsg,
818: TtaGetMessage (AMAYA, AM_SERVER_INTERNAL_ERROR_500_NO_CAUSE));
1.34 cvs 819: }
1.28 cvs 820: status = -500;
821: }
1.30 cvs 822: else
823: {
824: sprintf (msg_status, "%d", status);
825: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_UNKNOWN_XXX_STATUS), msg_status);
1.74 cvs 826: sprintf (AmayaLastHTTPErrorMsg, TtaGetMessage (AMAYA, AM_UNKNOWN_XXX_STATUS), msg_status);
1.30 cvs 827: }
1.28 cvs 828: }
1.7 cvs 829: }
1.74 cvs 830:
1.72 cvs 831: #ifdef _WINDOWS
1.77 ! cvs 832: /* we erase the context if we're dealing with an asynchronous request */
1.74 cvs 833: if ((me->mode & AMAYA_ASYNC) ||
834: (me->mode & AMAYA_IASYNC)) {
1.71 cvs 835: me->reqStatus = HT_END;
836: /** AHTReqContext_delete (me); **/
837: }
1.72 cvs 838: #endif /* _WINDOWS */
1.71 cvs 839:
840: return HT_OK;
1.4 cvs 841: }
842:
1.5 cvs 843: /*----------------------------------------------------------------------
1.17 cvs 844: AHTLoadTerminate_handler
1.74 cvs 845: this is an application "AFTER" Callback. It's called by the library
846: when a request has ended, so that we can setup the correct status.
1.5 cvs 847: ----------------------------------------------------------------------*/
1.4 cvs 848:
849: #ifdef __STDC__
1.7 cvs 850: static int AHTLoadTerminate_handler (HTRequest * request, HTResponse * response, void *param, int status)
1.4 cvs 851: #else
852: static int AHTLoadTerminate_handler (request, response, param, status)
853: HTRequest *request;
854: HTResponse *response;
855: void *param;
856: int status;
1.69 cvs 857:
1.4 cvs 858: #endif
859: {
860: AHTReqContext *me = HTRequest_context (request);
861: HTAlertCallback *cbf;
862: AHTDocId_Status *docid_status;
863:
1.7 cvs 864: switch (status)
865: {
866: case HT_LOADED:
867: if (PROT_TRACE)
868: HTTrace ("Load End.... OK: `%s\' has been accessed\n",
1.38 cvs 869: me->status_urlName);
1.4 cvs 870:
1.7 cvs 871: docid_status = GetDocIdStatus (me->docid,
872: Amaya->docid_status);
873:
874: if (docid_status != NULL && docid_status->counter > 1)
1.74 cvs 875: TtaSetStatus (me->docid, 1,
876: TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),
877: me->status_urlName);
1.7 cvs 878: break;
879:
880: case HT_NO_DATA:
881: if (PROT_TRACE)
1.74 cvs 882: HTTrace ("Load End.... OK BUT NO DATA: `%s\'\n",
883: me->status_urlName);
884: TtaSetStatus (me->docid, 1,
885: TtaGetMessage (AMAYA, AM_LOADED_NO_DATA),
1.38 cvs 886: me->status_urlName);
1.7 cvs 887: break;
888:
889: case HT_INTERRUPTED:
890: if (PROT_TRACE)
1.74 cvs 891: HTTrace ("Load End.... INTERRUPTED: `%s\'\n",
892: me->status_urlName);
893: TtaSetStatus (me->docid, 1,
894: TtaGetMessage (AMAYA, AM_LOAD_ABORT),
895: NULL);
1.7 cvs 896: break;
897:
898: case HT_RETRY:
899: if (PROT_TRACE)
900: HTTrace ("Load End.... NOT AVAILABLE, RETRY AT %ld\n",
901: HTResponse_retryTime (response));
1.74 cvs 902: TtaSetStatus (me->docid, 1,
903: TtaGetMessage (AMAYA, AM_NOT_AVAILABLE_RETRY),
1.38 cvs 904: me->status_urlName);
1.7 cvs 905: break;
906:
907: case HT_ERROR:
908:
909: cbf = HTAlert_find (HT_A_MESSAGE);
910: if (cbf)
911: (*cbf) (request, HT_A_MESSAGE, HT_MSG_NULL, NULL,
912: HTRequest_error (request), NULL);
913: break;
914:
915: if (PROT_TRACE)
916: HTTrace ("Load End.... ERROR: Can't access `%s\'\n",
1.74 cvs 917: me->status_urlName ? me->status_urlName :"<UNKNOWN>");
918: TtaSetStatus (me->docid, 1,
919: TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
1.38 cvs 920: me->status_urlName ? me->status_urlName : "<UNKNOWN>");
1.7 cvs 921: break;
922: default:
923: if (PROT_TRACE)
924: HTTrace ("Load End.... UNKNOWN RETURN CODE %d\n", status);
925: break;
926: }
927:
1.4 cvs 928: return HT_OK;
929: }
930:
1.27 cvs 931: /*----------------------------------------------------------------------
932: AHTAcceptTypesInit
1.74 cvs 933: This function prepares the Accept header used by Amaya during
934: the HTTP content negotiation phase
1.27 cvs 935: ----------------------------------------------------------------------*/
936: #ifdef __STDC__
937: static void AHTAcceptTypesInit (HTList *c)
938: #else /* __STDC__ */
939: static void AHTAcceptTypesInit (c)
940: HTList *c;
941: #endif /* __STDC__ */
942: {
943: if (c == (HTList *) NULL)
944: return;
945:
946: /* define here all the mime types that Amaya can accept */
947:
1.74 cvs 948: HTConversion_add (c, "image/png", "www/present",
949: HTThroughLine, 1.0, 0.0, 0.0);
950: HTConversion_add (c, "image/jpeg", "www/present",
951: HTThroughLine, 1.0, 0.0, 0.0);
952: HTConversion_add (c, "image/gif", "www/present",
953: HTThroughLine, 1.0, 0.0, 0.0);
954: HTConversion_add (c, "image/xbm", "www/present",
955: HTThroughLine, 1.0, 0.0, 0.0);
956: HTConversion_add (c, "image/xpm", "www/present",
957: HTThroughLine, 1.0, 0.0, 0.0);
958: HTConversion_add (c, "application/postscript",
959: "www/present", HTThroughLine, 1.0, 0.0, 0.0);
1.4 cvs 960:
1.27 cvs 961: /* Define here the equivalences between MIME types and file extensions for
962: the types that Amaya can display */
963:
964: /* Register the default set of file suffix bindings */
965: HTFileInit ();
966:
967: /* Don't do any case distinction */
968: HTBind_caseSensitive (FALSE);
969: }
1.4 cvs 970:
1.5 cvs 971: /*----------------------------------------------------------------------
1.17 cvs 972: AHTConverterInit
973: Bindings between a source media type and a destination media type
974: (conversion).
1.5 cvs 975: ----------------------------------------------------------------------*/
1.15 cvs 976: #ifdef __STDC__
977: static void AHTConverterInit (HTList *c)
978: #else /* __STDC__ */
979: static void AHTConverterInit (c)
980: HTList *c;
981: #endif /* __STDC__ */
1.4 cvs 982: {
983:
984: /* Handler for custom http error messages */
1.7 cvs 985: HTConversion_add (c, "*/*", "www/debug", AHTMemConverter, 1.0, 0.0, 0.0);
1.4 cvs 986:
987: /*
988: ** These are converters that converts to something other than www/present,
989: ** that is not directly outputting someting to the user on the screen
990: */
991:
992: HTConversion_add (c, "message/rfc822", "*/*", HTMIMEConvert, 1.0, 0.0, 0.0);
993: HTConversion_add (c, "message/x-rfc822-foot", "*/*", HTMIMEFooter,
994: 1.0, 0.0, 0.0);
995: HTConversion_add (c, "message/x-rfc822-head", "*/*", HTMIMEHeader,
996: 1.0, 0.0, 0.0);
997: HTConversion_add (c, "multipart/*", "*/*", HTBoundary,
998: 1.0, 0.0, 0.0);
999: HTConversion_add (c, "text/plain", "text/html", HTPlainToHTML,
1000: 1.0, 0.0, 0.0);
1001:
1002:
1003: /*
1004: ** The following conversions are converting ASCII output from various
1005: ** protocols to HTML objects.
1006: */
1007: HTConversion_add (c, "text/x-http", "*/*", HTTPStatus_new,
1008: 1.0, 0.0, 0.0);
1009: HTConversion_add (c, "text/x-nntp-list", "*/*", HTNewsList,
1010: 1.0, 0.0, 0.0);
1011: HTConversion_add (c, "text/x-nntp-over", "*/*", HTNewsGroup,
1012: 1.0, 0.0, 0.0);
1013:
1014:
1015: /*
1016: ** We also register a special content type guess stream that can figure out
1017: ** the content type by reading the first bytes of the stream
1018: */
1019: HTConversion_add (c, "www/unknown", "*/*", HTGuess_new,
1020: 1.0, 0.0, 0.0);
1021:
1022: /*
1023: ** Register a persistent cache stream which can save an object to local
1024: ** file
1025: */
1026: HTConversion_add (c, "www/cache", "*/*", HTCacheWriter,
1027: 1.0, 0.0, 0.0);
1028:
1029: /*
1030: ** This dumps all other formats to local disk without any further
1031: ** action taken
1032: */
1033: HTConversion_add (c, "*/*", "www/present", HTSaveLocally,
1034: 0.3, 0.0, 0.0);
1035:
1036: }
1037:
1.27 cvs 1038:
1.15 cvs 1039: /*----------------------------------------------------------------------
1.17 cvs 1040: AHTProtocolInit
1041: Registers all amaya supported protocols.
1.15 cvs 1042: ----------------------------------------------------------------------*/
1.4 cvs 1043: static void AHTProtocolInit (void)
1044: {
1045:
1.17 cvs 1046: /*
1.74 cvs 1047: NB. Preemptive == YES means Blocking requests
1048: Non-preemptive == NO means Non-blocking requests
1.17 cvs 1049: */
1.4 cvs 1050:
1.63 cvs 1051: HTProtocol_add ("http", "buffered_tcp", NO, HTLoadHTTP, NULL);
1.4 cvs 1052: /* HTProtocol_add ("http", "tcp", NO, HTLoadHTTP, NULL); */
1053: HTProtocol_add ("file", "local", NO, HTLoadFile, NULL);
1054: HTProtocol_add ("cache", "local", NO, HTLoadCache, NULL);
1.36 cvs 1055: HTProtocol_add ("ftp", "tcp", NO, HTLoadFTP, NULL);
1.17 cvs 1056: #if 0 /* experimental code */
1.4 cvs 1057: HTProtocol_add ("telnet", "", YES, HTLoadTelnet, NULL);
1058: HTProtocol_add ("tn3270", "", YES, HTLoadTelnet, NULL);
1059: HTProtocol_add ("rlogin", "", YES, HTLoadTelnet, NULL);
1060: HTProtocol_add ("nntp", "tcp", NO, HTLoadNews, NULL);
1061: HTProtocol_add ("news", "tcp", NO, HTLoadNews, NULL);
1.17 cvs 1062: #endif
1.4 cvs 1063: }
1064:
1.15 cvs 1065: /*----------------------------------------------------------------------
1.17 cvs 1066: AHTNetInit
1067: Reegisters "before" and "after" request filters.
1.15 cvs 1068: ----------------------------------------------------------------------*/
1.4 cvs 1069: static void AHTNetInit (void)
1070: {
1071:
1072: /* Register BEFORE filters
1.74 cvs 1073: ** The BEFORE filters handle proxies, caches, rule files etc.
1074: ** The filters are called in the order by which the are registered
1075: ** Not done automaticly - may be done by application!
1076: */
1077:
1.4 cvs 1078:
1.74 cvs 1079: HTNet_addBefore (HTCredentialsFilter, "http://*", NULL, 6);
1080: HTNet_addBefore (HTProxyFilter, NULL, NULL, 10);
1.4 cvs 1081:
1082: /* register AFTER filters
1.74 cvs 1083: ** The AFTER filters handle error messages, logging, redirection,
1084: ** authentication etc.
1085: ** The filters are called in the order by which the are registered
1086: ** Not done automaticly - may be done by application!
1087: */
1.4 cvs 1088:
1.51 cvs 1089: HTNet_addAfter (HTAuthFilter, "http://*", NULL, HT_NO_ACCESS, 5);
1090: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_TEMP_REDIRECT, 5);
1091: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_PERM_REDIRECT, 5);
1092: HTNet_addAfter (HTUseProxyFilter, "http://*", NULL, HT_USE_PROXY, 5);
1093: HTNet_addAfter (AHTLoadTerminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST);
1094: /* handles all errors */
1.7 cvs 1095: HTNet_addAfter (terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST);
1.4 cvs 1096: }
1097:
1.15 cvs 1098: /*----------------------------------------------------------------------
1.17 cvs 1099: AHTAlertInit
1100: Register alert messages and their callbacks.
1.15 cvs 1101: ----------------------------------------------------------------------*/
1102: #ifdef __STDC__
1103: static void AHTAlertInit (void)
1104: #else
1105: static void AHTAlertInit ()
1106: #endif
1107: {
1108: HTAlert_add (AHTProgress, HT_A_PROGRESS);
1.70 cvs 1109: # ifndef _WINDOWS
1.15 cvs 1110: HTAlert_add ((HTAlertCallback *) Add_NewSocket_to_Loop, HT_PROG_CONNECT);
1.70 cvs 1111: # else /* _WINDOWS */
1112: HTAlert_add ((HTAlertCallback *) WIN_Activate_Request, HT_PROG_CONNECT);
1113: # endif /* _WINDOWS */
1.15 cvs 1114: HTAlert_add (AHTError_print, HT_A_MESSAGE);
1.48 cvs 1115: HTError_setShow (~((unsigned int) 0 ) & ~((unsigned int) HT_ERR_SHOW_DEBUG)); /* process all messages except debug ones*/
1.15 cvs 1116: HTAlert_add (AHTConfirm, HT_A_CONFIRM);
1117: HTAlert_add (AHTPrompt, HT_A_PROMPT);
1118: HTAlert_add (AHTPromptPassword, HT_A_SECRET);
1119: HTAlert_add (AHTPromptUsernameAndPassword, HT_A_USER_PW);
1120: }
1121:
1122: /*----------------------------------------------------------------------
1.17 cvs 1123: AHTProfile_newAmaya
1124: creates the Amaya client profile for libwww.
1.15 cvs 1125: ----------------------------------------------------------------------*/
1126: #ifdef __STDC__
1127: static void AHTProfile_newAmaya (char *AppName, char *AppVersion)
1128: #else /* __STDC__ */
1129: static void AHTProfile_newAmaya (AppName, AppVersion)
1130: char *AppName;
1131: char *AppVersion;
1132: #endif /* __STDC__ */
1.4 cvs 1133: {
1134: /* If the Library is not already initialized then do it */
1135: if (!HTLib_isInitialized ())
1136: HTLibInit (AppName, AppVersion);
1137:
1138: if (!converters)
1139: converters = HTList_new ();
1.27 cvs 1140: if (!acceptTypes)
1141: acceptTypes = HTList_new ();
1.4 cvs 1142: if (!encodings)
1143: encodings = HTList_new ();
1144:
1145: /* Register the default set of transport protocols */
1146: HTTransportInit ();
1147:
1148: /* Register the default set of application protocol modules */
1149: AHTProtocolInit ();
1150:
1151: /* Enable the persistent cache */
1152: /* HTCacheInit (NULL, 20); */
1153:
1154: /* Register the default set of BEFORE and AFTER filters */
1155: AHTNetInit ();
1156:
1157: /* Set up the default set of Authentication schemes */
1158: HTAAInit ();
1159:
1160: /* Get any proxy or gateway environment variables */
1161: HTProxy_getEnvVar ();
1162:
1163: /* Register the default set of converters */
1164: AHTConverterInit (converters);
1.27 cvs 1165: AHTAcceptTypesInit (acceptTypes);
1.4 cvs 1166: HTFormat_setConversion (converters);
1167:
1168: /* Register the default set of transfer encoders and decoders */
1169: HTEncoderInit (encodings); /* chunks ??? */
1170: HTFormat_setTransferCoding (encodings);
1171:
1172: /* Register the default set of MIME header parsers */
1.74 cvs 1173: HTMIMEInit (); /* must be called again for language selector */
1.4 cvs 1174:
1175: /* Register the default set of Icons for directory listings */
1.27 cvs 1176: /*HTIconInit(NULL); *//* experimental */
1.4 cvs 1177:
1178: /* Register the default set of messages and dialog functions */
1179: AHTAlertInit ();
1180: HTAlert_setInteractive (YES);
1181: }
1182:
1.5 cvs 1183: /*----------------------------------------------------------------------
1.17 cvs 1184: AHTProfile_delete
1185: deletes the Amaya client profile.
1.5 cvs 1186: ----------------------------------------------------------------------*/
1.4 cvs 1187: #ifdef __STDC__
1188: static void AHTProfile_delete (void)
1189: #else
1190: static void AHTProfile_delete ()
1.7 cvs 1191: #endif /* __STDC__ */
1.4 cvs 1192: {
1.22 cvs 1193:
1194: /* free the Amaya global context */
1.74 cvs 1195: if (!converters)
1196: HTConversion_deleteAll (converters);
1197: if (!acceptTypes)
1198: HTConversion_deleteAll (acceptTypes);
1199: if (!encodings)
1200: HTCoding_deleteAll (encodings);
1201:
1202: HTList_delete (Amaya->docid_status);
1203: HTList_delete (Amaya->reqlist);
1204: TtaFreeMemory (Amaya);
1205: {
1.61 cvs 1206:
1.74 cvs 1207: if (HTLib_isInitialized ())
1208:
1.61 cvs 1209: # ifdef _WINDOWS
1210: HTEventTerminate ();
1211: # endif _WINDOWS;
1.74 cvs 1212:
1213: /* Clean up the persistent cache (if any) */
1214: HTCacheTerminate ();
1215:
1216: /* Clean up all the global preferences */
1217: HTFormat_deleteAll ();
1218:
1219: /* Terminate libwww */
1220: HTLibTerminate ();
1221: }
1.4 cvs 1222: }
1223:
1.5 cvs 1224: /*----------------------------------------------------------------------
1.17 cvs 1225: QueryInit
1226: initializes the libwww interface
1.5 cvs 1227: ----------------------------------------------------------------------*/
1.4 cvs 1228: #ifdef __STDC__
1229: void QueryInit ()
1230: #else
1231: void QueryInit ()
1232: #endif
1233: {
1234:
1.24 cvs 1235: AmayaIsAlive = TRUE;
1.4 cvs 1236: AHTProfile_newAmaya (HTAppName, HTAppVersion);
1237:
1.69 cvs 1238: /* New AHTBridge stuff */
1.4 cvs 1239:
1.54 cvs 1240: # ifdef _WINDOWS
1.75 cvs 1241: AHTEventInit ();
1.54 cvs 1242: # endif _WINDOWS;
1.72 cvs 1243:
1.70 cvs 1244: HTEvent_setRegisterCallback (AHTEvent_register);
1.4 cvs 1245:
1.72 cvs 1246: # ifndef _WINDOWS
1247: HTEvent_setUnregisterCallback (AHTEvent_unregister);
1248: # endif /* _WINDOWS */
1249:
1.74 cvs 1250: #ifdef DEBUG_LIBWWW
1251: WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_THREAD_TRACE | PROT_TRACE;
1252: #endif
1.4 cvs 1253:
1254: /* Trace activation (for debugging) */
1.7 cvs 1255: /*
1.4 cvs 1256: WWW_TraceFlag = SHOW_APP_TRACE | SHOW_UTIL_TRACE |
1257: SHOW_BIND_TRACE | SHOW_THREAD_TRACE |
1258: SHOW_STREAM_TRACE | SHOW_PROTOCOL_TRACE |
1259: SHOW_URI_TRACE | SHOW_AUTH_TRACE | SHOW_ANCHOR_TRACE |
1260: SHOW_CORE_TRACE;
1261:
1.7 cvs 1262: */
1.4 cvs 1263:
1264: /***
1265: WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_AUTH_TRACE | SHOW_ANCHOR_TRACE |
1266: SHOW_PROTOCOL_TRACE| SHOW_APP_TRACE | SHOW_UTIL_TRACE;
1267: ***/
1268:
1269: /* Setting up other user interfaces */
1270:
1271: /* Setting up different network parameters */
1.17 cvs 1272: /* Maximum number of simultaneous open sockets */
1.4 cvs 1273: HTNet_setMaxSocket (8);
1.75 cvs 1274: /* different network services timeouts */
1.4 cvs 1275: HTDNS_setTimeout (3600);
1.75 cvs 1276: #ifdef _WINDOWS
1277: /* under windows, the libwww persistent socket handling has
1278: ** some bugs. The following line inhibits idle socket reusal.
1279: ** this is a bit slower, but avoids crashes and gives us time
1280: ** to distribute Amaya before having to patch up libwww.
1281: */
1.76 cvs 1282: HTHost_setPersistTimeout (-1L);
1.75 cvs 1283: #else
1.76 cvs 1284: HTHost_setPersistTimeout (60L);
1.75 cvs 1285: #endif /* _WINDOWS */
1286:
1.17 cvs 1287: /* Cache is disabled in this version */
1.4 cvs 1288: HTCacheMode_setEnabled (0);
1289:
1290: /* Initialization of the global context */
1291: Amaya = (AmayaContext *) TtaGetMemory (sizeof (AmayaContext));
1292: Amaya->reqlist = HTList_new ();
1293: Amaya->docid_status = HTList_new ();
1294: Amaya->open_requests = 0;
1.74 cvs 1295:
1.4 cvs 1296: #ifdef CATCH_SIG
1.18 cvs 1297: signal (SIGPIPE, SIG_IGN);
1.4 cvs 1298: #endif
1.15 cvs 1299: }
1300:
1.69 cvs 1301: #ifndef _WINDOWS
1.15 cvs 1302: /*----------------------------------------------------------------------
1.17 cvs 1303: LoopForStop
1304: a copy of the Thop event loop so we can handle the stop button.
1.69 cvs 1305: Not useful for windows code (Ramzi).
1.15 cvs 1306: ----------------------------------------------------------------------*/
1307: #ifdef __STDC__
1308: static int LoopForStop (AHTReqContext * me)
1309: #else
1310: static int LoopForStop (AHTReqContext * me)
1311: #endif
1312: {
1313:
1.25 cvs 1314: extern ThotAppContext app_cont;
1.51 cvs 1315: XEvent ev;
1316: XtInputMask status;
1.17 cvs 1317: int status_req = HT_OK;
1.15 cvs 1318:
1319: /* to test the async calls */
1.17 cvs 1320: /* Loop while waiting for new events, exists when the request is over */
1.15 cvs 1321: while (me->reqStatus != HT_ABORT &&
1322: me->reqStatus != HT_END &&
1.69 cvs 1323: me->reqStatus != HT_ERR) {
1324: if (!AmayaIsAlive)
1325: /* Amaya was killed by one of the callback handlers */
1326: exit (0);
1327:
1328: status = XtAppPending (app_cont);
1329: if (status & XtIMXEvent) {
1330: XtAppNextEvent (app_cont, &ev);
1331: TtaHandleOneEvent (&ev);
1332: } else if (status & (XtIMAll & (~XtIMXEvent))) {
1333: XtAppProcessEvent (app_cont, (XtIMAll & (~XtIMXEvent)));
1334: } else {
1335: XtAppNextEvent (app_cont, &ev);
1336: TtaHandleOneEvent (&ev);
1337: }
1338: }
1.4 cvs 1339:
1.69 cvs 1340: switch (me->reqStatus) {
1341: case HT_ERR:
1342: case HT_ABORT:
1.15 cvs 1343: status_req = HT_ERROR;
1344: break;
1345:
1.69 cvs 1346: case HT_END:
1.15 cvs 1347: status_req = HT_OK;
1348: break;
1349:
1.69 cvs 1350: default:
1.15 cvs 1351: break;
1.69 cvs 1352: }
1.15 cvs 1353: return (status_req);
1.4 cvs 1354: }
1.69 cvs 1355: #endif /* _WINDOWS */
1.4 cvs 1356:
1.5 cvs 1357: /*----------------------------------------------------------------------
1.15 cvs 1358: QueryClose
1.21 cvs 1359: closes all existing threads, frees all non-automatically deallocated
1360: memory and then ends libwww.
1.5 cvs 1361: ----------------------------------------------------------------------*/
1.4 cvs 1362: void QueryClose ()
1363: {
1.24 cvs 1364:
1365: AmayaIsAlive = FALSE;
1366:
1.21 cvs 1367: /* remove all the handlers and callbacks that may output a message to
1368: a non-existent Amaya window */
1369:
1370: HTNet_deleteAfter (AHTLoadTerminate_handler);
1371: HTNet_deleteAfter (redirection_handler);
1372: HTAlertCall_deleteAll (HTAlert_global () );
1.23 cvs 1373: HTAlert_setGlobal ((HTList *) NULL);
1.24 cvs 1374: HTEvent_setRegisterCallback ((HTEvent_registerCallback *) NULL);
1.27 cvs 1375: HTEvent_setUnregisterCallback ((HTEvent_unregisterCallback *) NULL);
1.69 cvs 1376:
1.4 cvs 1377: Thread_deleteAll ();
1.21 cvs 1378:
1.4 cvs 1379: HTProxy_deleteAll ();
1380: HTNoProxy_deleteAll ();
1381: HTGateway_deleteAll ();
1382: AHTProfile_delete ();
1383: }
1384:
1.5 cvs 1385: /*----------------------------------------------------------------------
1.15 cvs 1386: GetObjectWWW
1.17 cvs 1387: this function requests a resource designated by a URLname into a
1388: temporary filename. The download can come from a simple GET operation,
1389: or can come from POSTING/GETTING a form. In the latter
1390: case, the function receives a query string to send to the server.
1391:
1.5 cvs 1392: 4 file retrieval modes are proposed:
1393: AMAYA_SYNC : blocking mode
1394: AMAYA_ISYNC : incremental, blocking mode
1395: AMAYA_ASYNC : non-blocking mode
1396: AMAYA_IASYNC : incremental, non-blocking mode
1397:
1398: In the incremental mode, each time a package arrives, it will be
1399: stored in the temporary file. In addition, if an
1400: incremental_callback function is defined, this function will be
1401: called and handled a copy of the newly received data package.
1402: Finally, if a terminate_callback function is defined, it will be
1403: invoked when the request terminates. The caller of this function
1.4 cvs 1404: can define two different contexts to be passed to the callback
1405: functions.
1406:
1407: When the function is called with the SYNC mode, the function will
1408: return only when the requested file has been loaded.
1409: The ASYNC mode will immediately return after setting up the
1410: call.
1411:
1412: Notes:
1413: At the end of a succesful request, the urlName string contains the
1414: name of the actually retrieved URL. As a URL can change over the time,
1415: (e.g., be redirected elsewhere), it is advised that the function
1.17 cvs 1416: caller verify the value of the urlName variable at the end of
1.4 cvs 1417: a request.
1418:
1419: Inputs:
1420: - docid Document identifier for the set of objects being
1421: retrieved.
1422: - urlName The URL to be retrieved (MAX_URL_LENGTH chars length)
1423: - outputfile A pointer to an empty string of MAX_URL_LENGTH.
1424: - mode The retrieval mode.
1425: - incremental_cbf
1426: - context_icbf
1427: Callback and context for the incremental modes
1428: - terminate_cbf
1429: - context_icbf
1430: Callback and context for a terminate handler
1.17 cvs 1431: -error_html if TRUE, then display any server error message as an
1432: HTML document.
1.4 cvs 1433:
1434: Outputs:
1435: - urlName The URL that was retrieved
1436: - outputfile The name of the temporary file which holds the
1437: retrieved data. (Only in case of success)
1438: Returns:
1439: HT_ERROR
1440: HT_OK
1.5 cvs 1441:
1442: ----------------------------------------------------------------------*/
1.4 cvs 1443: #ifdef __STDC__
1.52 cvs 1444: int GetObjectWWW (int docid, char* urlName, char* postString, char* outputfile, int mode,
1445: TIcbf* incremental_cbf, void* context_icbf, TTcbf* terminate_cbf,
1446: void* context_tcbf, boolean error_html)
1.4 cvs 1447: #else
1.52 cvs 1448: int GetObjectWWW (docid, urlName, postString, outputfile, mode, incremental_cbf, context_icbf,
1449: terminate_cbf, context_tcbf, error_html)
1.73 cvs 1450: int docid;
1451: char *urlName;
1452: char *postString;
1453: char *outputfile;
1454: int mode;
1455: TIcbf *incremental_cbf;
1456: void *context_icbf;
1457: TTcbf *terminate_cbf;
1458: void *context_tcbf;
1459: boolean error_html;
1.4 cvs 1460: #endif
1461: {
1462: AHTReqContext *me;
1463: char *ref;
1464: int status;
1.7 cvs 1465:
1.69 cvs 1466: if (urlName == NULL || docid == 0 || outputfile == NULL) {
1467: /* no file to be loaded */
1468: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);
1469:
1470: if (error_html)
1471: /* so we can show the error message */
1472: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1473: return HT_ERROR;
1474:
1475: }
1.7 cvs 1476:
1.4 cvs 1477: /* do we support this protocol? */
1.69 cvs 1478: if (IsValidProtocol (urlName) == NO) {
1479: /* return error */
1480: outputfile[0] = EOS; /* file could not be opened */
1481: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_GET_UNSUPPORTED_PROTOCOL), urlName);
1482:
1483: if (error_html)
1484: /* so we can show the error message */
1485: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1486: return HT_ERROR;
1487: }
1.4 cvs 1488:
1.58 cvs 1489: /*create a tempfilename */
1.59 cvs 1490: sprintf (outputfile, "%s%c%d%c%04dAM", TempFileDirectory, DIR_SEP, docid, DIR_SEP, object_counter);
1.4 cvs 1491:
1492: /* update the object_counter */
1493: object_counter++;
1494: /* normalize the URL */
1.45 cvs 1495: ref = AmayaParseUrl (urlName, "", AMAYA_PARSE_ALL);
1.4 cvs 1496: /* should we abort the request if we could not normalize the url? */
1.69 cvs 1497: if (ref == (char*) NULL || ref[0] == EOS) {
1498: /*error */
1499: outputfile[0] = EOS;
1500: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);
1501:
1502: if (error_html)
1503: /* so we can show the error message */
1504: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1.4 cvs 1505:
1.69 cvs 1506: return HT_ERROR;
1507: }
1.4 cvs 1508: /* verify if that file name existed */
1.9 cvs 1509: if (TtaFileExist (outputfile))
1.77 ! cvs 1510: TtaFileUnlink (outputfile);
1.4 cvs 1511:
1512: /* Initialize the request structure */
1513: me = AHTReqContext_new (docid);
1.69 cvs 1514: if (me == NULL) {
1.77 ! cvs 1515: outputfile[0] = EOS;
! 1516: /* need an error message here */
! 1517: TtaFreeMemory (ref);
! 1518: return (HT_ERROR);
1.69 cvs 1519: }
1.77 ! cvs 1520:
1.4 cvs 1521: /* Specific initializations for POST and GET */
1.69 cvs 1522: if (mode & AMAYA_FORM_POST) {
1.77 ! cvs 1523: me->method = METHOD_POST;
! 1524: if (postString) {
! 1525: me->mem_ptr = postString;
! 1526: me->block_size = strlen (postString);
! 1527: } else {
! 1528: me->mem_ptr = "";
! 1529: me->block_size = 0;
! 1530: }
! 1531: HTRequest_setMethod (me->request, METHOD_POST);
1.69 cvs 1532: HTRequest_setPostCallback (me->request, AHTUpload_callback);
1533: } else {
1.77 ! cvs 1534: me->method = METHOD_GET;
! 1535: me->dest = (HTParentAnchor *) NULL; /*useful only for PUT and POST methods */
! 1536: if (!HasKnownFileSuffix (ref))
! 1537: HTRequest_setConversion(me->request, acceptTypes, TRUE);
1.69 cvs 1538: }
1.4 cvs 1539:
1540: /* Common initialization */
1541: me->mode = mode;
1542: me->error_html = error_html;
1543: me->incremental_cbf = incremental_cbf;
1544: me->context_icbf = context_icbf;
1545: me->terminate_cbf = terminate_cbf;
1546: me->context_tcbf = context_tcbf;
1.64 cvs 1547:
1.69 cvs 1548: /* for the async. request modes, we need to have our
1.4 cvs 1549: own copy of outputfile and urlname
1550: */
1551:
1.69 cvs 1552: if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC)) {
1.77 ! cvs 1553: char* tmp;
! 1554:
1.69 cvs 1555: tmp = TtaGetMemory (strlen (outputfile) + 1);
1556: strcpy (tmp, outputfile);
1557: me->outputfile = tmp;
1558:
1559: tmp = TtaGetMemory (MAX_LENGTH + 1);
1560: strncpy (tmp, urlName, MAX_LENGTH);
1561: tmp[MAX_LENGTH] = EOS;
1562: me->urlName = tmp;
1563: # ifdef _WINDOWS
1564: HTRequest_setPreemptive (me->request, NO);
1565: } else {
1.77 ! cvs 1566: me->outputfile = outputfile;
! 1567: me->urlName = urlName;
! 1568: HTRequest_setPreemptive (me->request, YES);
1.61 cvs 1569: }
1.69 cvs 1570: # else /* _WINDOWS */
1571: } else {
1.77 ! cvs 1572: me->outputfile = outputfile;
! 1573: me->urlName = urlName;
1.61 cvs 1574: }
1.77 ! cvs 1575: /***
1.57 cvs 1576: Change for taking into account the stop button:
1577: The requests will be always asynchronous, however, if mode=AMAYA_SYNC,
1578: we will loop until the document has been received or a stop signal
1579: generated
1.77 ! cvs 1580: ****/
! 1581: HTRequest_setPreemptive (me->request, NO);
1.69 cvs 1582: # endif /* _WINDOWS */
1.61 cvs 1583:
1584: /* prepare the URLname that will be displayed in teh status bar */
1585: ChopURL (me->status_urlName, me->urlName);
1586:
1.77 ! cvs 1587: TtaSetStatus (me->docid, 1,
! 1588: TtaGetMessage (AMAYA, AM_FETCHING),
! 1589: me->status_urlName);
1.4 cvs 1590:
1591: me->anchor = (HTParentAnchor *) HTAnchor_findAddress (ref);
1.45 cvs 1592: TtaFreeMemory (ref);
1.4 cvs 1593:
1.69 cvs 1594: if (mode & AMAYA_FORM_POST) {
1595: HTAnchor_setFormat ((HTParentAnchor *) me->anchor, HTAtom_for ("application/x-www-form-urlencoded"));
1596: HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size);
1597: HTRequest_setEntityAnchor (me->request, me->anchor);
1598:
1599: status = HTLoadAbsolute (urlName, me->request);
1600: } else
1.77 ! cvs 1601: status = HTLoadAnchor ((HTAnchor *) me->anchor, me->request);
1.69 cvs 1602:
1.72 cvs 1603: #ifndef _WINDOWS
1.77 ! cvs 1604: if (status == HT_ERROR ||
! 1605: me->reqStatus == HT_END ||
! 1606: me->reqStatus == HT_ERR)
! 1607: {
! 1608: /* in case of error, free all allocated memory and exit */
! 1609: if (me->output)
! 1610: fclose (me->output);
1.72 cvs 1611:
1.77 ! cvs 1612: if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC)) {
! 1613: if (me->outputfile)
! 1614: TtaFreeMemory (me->outputfile);
! 1615: if (me->urlName)
! 1616: TtaFreeMemory (me->urlName);
! 1617: }
! 1618:
1.72 cvs 1619: if (me->reqStatus == HT_ERR) {
1.77 ! cvs 1620: status = HT_ERROR;
! 1621: /* show an error message on the status bar */
! 1622: DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR;
! 1623: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_LOAD), me->
! 1624: status_urlName);
1.72 cvs 1625: } else
1.77 ! cvs 1626: status = HT_OK;
1.72 cvs 1627:
1628: AHTReqContext_delete (me);
1.77 ! cvs 1629: } else {
1.72 cvs 1630: /* part of the stop button handler */
1631: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC)) {
1632: status = LoopForStop (me);
1633: AHTReqContext_delete (me);
1634: }
1635: }
1636: TtaHandlePendingEvents ();
1637:
1638: #else /* !_WINDOWS */
1639:
1.71 cvs 1640: if (status == HT_ERROR) {
1641:
1.77 ! cvs 1642: /* in case of error, close any open files, free all allocated
! 1643: memory and exit */
! 1644: if (me->output && me->output != stdout)
1.69 cvs 1645: fclose (me->output);
1646:
1647: if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC)) {
1.77 ! cvs 1648: if (me->outputfile)
! 1649: TtaFreeMemory (me->outputfile);
! 1650: if (me->urlName)
! 1651: TtaFreeMemory (me->urlName);
1.69 cvs 1652: }
1653:
1654: if (me->reqStatus == HT_ERR) {
1.77 ! cvs 1655: status = HT_ERROR;
! 1656: /* show an error message on the status bar */
! 1657: DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR;
! 1658: TtaSetStatus (me->docid, 1,
! 1659: TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
! 1660: me->status_urlName);
1.69 cvs 1661: } else
1.77 ! cvs 1662: status = HT_OK;
1.69 cvs 1663:
1664: AHTReqContext_delete (me);
1665: } else {
1.77 ! cvs 1666: /* part of the stop button handler */
! 1667: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC)) {
! 1668: AHTReqContext_delete (me);
1.69 cvs 1669: }
1.64 cvs 1670: }
1.69 cvs 1671: TtaHandlePendingEvents ();
1.4 cvs 1672:
1.72 cvs 1673: #endif /* !_WINDOWS */
1674:
1.4 cvs 1675: return (status);
1676: }
1677:
1.5 cvs 1678: /*----------------------------------------------------------------------
1.17 cvs 1679: PutObjectWWW
1680: frontend for uploading a resource to a URL. This function downloads
1681: a file to be uploaded into memory, it then calls UploadMemWWW to
1682: finish the job.
1683:
1.5 cvs 1684: 2 upload modes are proposed:
1685: AMAYA_SYNC : blocking mode
1686: AMAYA_ASYNC : non-blocking mode
1687:
1.4 cvs 1688: When the function is called with the SYNC mode, the function will
1689: return only when the file has been uploaded.
1690: The ASYNC mode will immediately return after setting up the
1691: call. Furthermore, at the end of an upload, the ASYNC mode will
1692: call back terminate_cbf, handling it the context defined in
1693: context_tcbf.
1694:
1695: Notes:
1696: At the end of a succesful request, the urlName string contains the
1697: name of the actually uploaded URL. As a URL can change over the time,
1698: (e.g., be redirected elsewhere), it is advised that the function
1699: caller verifies the value of the urlName variable at the end of
1700: a request.
1701:
1702: Inputs:
1703: - docid Document identifier for the set of objects being
1704: retrieved.
1705: - fileName A pointer to the local file to upload
1706: - urlName The URL to be uploaded (MAX_URL_LENGTH chars length)
1707: - mode The retrieval mode.
1708: - terminate_cbf
1709: - context_icbf
1710: Callback and context for a terminate handler
1711:
1712: Outputs:
1713: - urlName The URL that was uploaded
1714:
1715: Returns:
1716: HT_ERROR
1717: HT_OK
1.5 cvs 1718: ----------------------------------------------------------------------*/
1.4 cvs 1719: #ifdef __STDC__
1.27 cvs 1720: int PutObjectWWW (int docid, char *fileName, char *urlName, int mode, PicType contentType,
1.4 cvs 1721: TTcbf * terminate_cbf, void *context_tcbf)
1722: #else
1.26 cvs 1723: int PutObjectWWW (docid, urlName, fileName, mode, contentType,
1.4 cvs 1724: ,terminate_cbf, context_tcbf)
1725: int docid;
1726: char *urlName;
1727: char *fileName;
1728: int mode;
1.27 cvs 1729: PicType contentType;
1.4 cvs 1730: TTcbf *terminate_cbf;
1731: void *context_tcbf;
1732:
1733: #endif
1734: {
1.7 cvs 1735: /*AHTReqContext *me; */
1.4 cvs 1736: int status;
1737:
1738: int fd;
1739: struct stat file_stat;
1740: char *mem_ptr;
1741: unsigned long block_size;
1742:
1.33 cvs 1743: AmayaLastHTTPErrorMsg [0] = EOS;
1744:
1.4 cvs 1745: if (urlName == NULL || docid == 0 || fileName == NULL ||
1.9 cvs 1746: !TtaFileExist (fileName))
1.4 cvs 1747: /* no file to be uploaded */
1748: return HT_ERROR;
1749:
1750: /* do we support this protocol? */
1.7 cvs 1751: if (IsValidProtocol (urlName) == NO)
1752: {
1753: /* return error */
1.77 ! cvs 1754: TtaSetStatus (docid, 1,
! 1755: TtaGetMessage (AMAYA, AM_PUT_UNSUPPORTED_PROTOCOL),
1.7 cvs 1756: urlName);
1757: return HT_ERROR;
1758: }
1.4 cvs 1759: /* read the file into memory */
1.70 cvs 1760: # ifndef _WINDOWS
1.7 cvs 1761: if ((fd = open (fileName, O_RDONLY)) == -1)
1.70 cvs 1762: # else /* _WINDOWS */
1.74 cvs 1763: if ((fd = open (fileName, _O_RDONLY | _O_BINARY)) == -1)
1.70 cvs 1764: # endif /* _WINDOWS */
1.7 cvs 1765: {
1766: /* if we could not open the file, exit */
1767: /*error msg here */
1768: return (HT_ERROR);
1769: }
1.4 cvs 1770:
1771: fstat (fd, &file_stat);
1772:
1.7 cvs 1773: if (file_stat.st_size == 0)
1774: {
1775: /* file was empty */
1776: /*errmsg here */
1777: close (fd);
1778: return (HT_ERROR);
1779: }
1.4 cvs 1780: block_size = file_stat.st_size;
1781:
1782: if (THD_TRACE)
1783: fprintf (stderr, "file size == %u\n", (unsigned) block_size);
1784:
1785: mem_ptr = (char *) TtaGetMemory (block_size);
1786:
1.7 cvs 1787: if (mem_ptr == (char *) NULL)
1788: {
1789: /* could not allocate enough memory */
1790: /*errmsg here */
1791: close (fd);
1792: return (HT_ERROR);
1793: }
1.4 cvs 1794: read (fd, mem_ptr, block_size);
1795:
1796: close (fd);
1797:
1.27 cvs 1798: status = UploadMemWWW (docid, METHOD_PUT, urlName, contentType, mem_ptr,
1.4 cvs 1799: block_size, mode, terminate_cbf,
1800: context_tcbf, (char *) NULL);
1801:
1802: TtaFreeMemory (mem_ptr);
1.28 cvs 1803: TtaHandlePendingEvents ();
1.4 cvs 1804: return (status);
1805: }
1806:
1.5 cvs 1807: /*----------------------------------------------------------------------
1.17 cvs 1808: UploadMemWWW
1809: low level interface function to libwww for uploading a block of
1810: memory to a URL.
1.5 cvs 1811: ----------------------------------------------------------------------*/
1.4 cvs 1812: #ifdef __STDC__
1813: int UploadMemWWW (int docid, HTMethod method,
1.27 cvs 1814: char *urlName, PicType contentType, char *mem_ptr, unsigned long block_size,
1.4 cvs 1815: int mode, TTcbf * terminate_cbf, void *context_tcbf,
1816: char *outputfile)
1817: #else
1.27 cvs 1818: int UploadMemWWW (docid, method, urlName, contentType, mem_ptr, block_size, mode,
1.4 cvs 1819: terminate_cbf, context_tcbf, outputfile)
1820: int docid;
1821: HTMethod method;
1822: char *urlName;
1.27 cvs 1823: PicType contentType;
1.4 cvs 1824: char *mem_ptr;
1825: usigned long block_size;
1826: int mode;
1827: TTcbf *terminate_cbf;
1828: void *context_tcbf;
1829: char *outputfile;
1.7 cvs 1830:
1.4 cvs 1831: #endif
1832: {
1833: AHTReqContext *me;
1834: int status;
1835:
1836: if (mem_ptr == (char *) NULL ||
1837: block_size == 0 ||
1838: docid == 0 ||
1.7 cvs 1839: urlName == (char *) NULL)
1840: {
1841: /* nothing to be uploaded */
1842: return HT_ERROR;
1843: }
1.4 cvs 1844:
1845: /* Initialize the request structure */
1846: me = AHTReqContext_new (docid);
1847:
1.7 cvs 1848: if (me == NULL)
1849: {
1850: /* need an error message here */
1851: TtaHandlePendingEvents ();
1852: return (HT_ERROR);
1853: }
1.4 cvs 1854: me->mode = mode;
1855:
1856: me->incremental_cbf = (TIcbf *) NULL;
1857: me->context_icbf = (void *) NULL;
1858: me->terminate_cbf = terminate_cbf;
1859: me->context_tcbf = context_tcbf;
1860:
1861: me->output = stdout;
1862: me->outputfile = (char *) NULL;
1863: me->urlName = urlName;
1864:
1.70 cvs 1865: #ifdef _WINDOWS
1866: HTRequest_setPreemptive (me->request, YES);
1867: #else
1.4 cvs 1868: HTRequest_setPreemptive (me->request, NO);
1.70 cvs 1869: #endif /* _WINDOWS */
1.74 cvs 1870:
1.17 cvs 1871: /* select the parameters that distinguish a PUT from a GET/POST */
1.4 cvs 1872: me->method = METHOD_PUT;
1873: HTRequest_setMethod (me->request, METHOD_PUT);
1874: me->output = stdout;
1.17 cvs 1875: /* we are not expecting to receive any input from the server */
1876: me->outputfile = (char *) NULL;
1.4 cvs 1877:
1878: me->mem_ptr = mem_ptr;
1879: me->block_size = block_size;
1.17 cvs 1880:
1881: /* set the callback which will actually copy data into the
1882: output stream */
1883:
1.4 cvs 1884: HTRequest_setPostCallback (me->request, AHTUpload_callback);
1.72 cvs 1885:
1.4 cvs 1886: me->anchor = (HTParentAnchor *) HTAnchor_findAddress (urlName);
1.7 cvs 1887:
1.28 cvs 1888: /* Set the Content-Type of the file we are uploading */
1.77 ! cvs 1889: HTAnchor_setFormat ((HTParentAnchor *) me->anchor,
! 1890: AHTGuessAtom_for (me->urlName, contentType));
1.17 cvs 1891:
1.7 cvs 1892: HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size);
1.4 cvs 1893: HTRequest_setEntityAnchor (me->request, me->anchor);
1.74 cvs 1894: /* prepare the URLname that will be displayed in teh status bar */
1895: ChopURL (me->status_urlName, me->urlName);
1896: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REMOTE_SAVING),
1897: me->status_urlName);
1.4 cvs 1898: status = HTLoadAbsolute (urlName, me->request);
1899:
1.74 cvs 1900: #ifndef _WINDOWS
1.77 ! cvs 1901: if (status == HT_ERROR ||
! 1902: me->reqStatus == HT_END ||
! 1903: me->reqStatus == HT_ERR ||
! 1904: HTError_hasSeverity (HTRequest_error (me->request), ERR_INFO))
1.74 cvs 1905: #else
1906: if (status == HT_ERROR)
1907: #endif /* !_WINDOWS */
1.7 cvs 1908: {
1.17 cvs 1909: status = HT_ERROR;
1.28 cvs 1910: }
1.7 cvs 1911: else
1912: {
1913: /* part of the stop button handler */
1.4 cvs 1914:
1.7 cvs 1915: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))
1916: {
1.70 cvs 1917: # ifndef _WINDOWS
1.7 cvs 1918: status = LoopForStop (me);
1.70 cvs 1919: # endif /* !_WINDOWS */
1.7 cvs 1920: }
1.15 cvs 1921: }
1.77 ! cvs 1922: AHTReqContext_delete (me);
1.4 cvs 1923: return (status);
1.28 cvs 1924: }
1.4 cvs 1925:
1926:
1927:
1.5 cvs 1928: /*----------------------------------------------------------------------
1.17 cvs 1929: Stop Request
1930: stops (kills) all active requests associated with a docid
1.5 cvs 1931: ----------------------------------------------------------------------*/
1.4 cvs 1932: #ifdef __STDC__
1933: void StopRequest (int docid)
1934: #else
1935: void StopRequest (docid)
1936: int docid;
1937: #endif
1938: {
1939: HTList *cur;
1940: AHTDocId_Status *docid_status;
1941: AHTReqContext *me;
1942: int open_requests;
1943:
1.7 cvs 1944: if (Amaya)
1945: {
1.4 cvs 1946:
1.7 cvs 1947: cur = Amaya->reqlist;
1948: docid_status = (AHTDocId_Status *) GetDocIdStatus (docid,
1.4 cvs 1949: Amaya->docid_status);
1950:
1.7 cvs 1951: /* verify if there are any requests at all associated with docid */
1.4 cvs 1952:
1.7 cvs 1953: if (docid_status == (AHTDocId_Status *) NULL)
1954: return;
1.4 cvs 1955:
1.7 cvs 1956: open_requests = docid_status->counter;
1.4 cvs 1957:
1.7 cvs 1958: while ((me = (AHTReqContext *) HTList_nextObject (cur)))
1959: {
1960: if (me->docid == docid)
1961: {
1962: /* kill this request */
1.4 cvs 1963:
1.7 cvs 1964: switch (me->reqStatus)
1965: {
1966: case HT_ABORT:
1967: break;
1.4 cvs 1968:
1.7 cvs 1969: case HT_BUSY:
1970: me->reqStatus = HT_ABORT;
1971: break;
1972: case HT_NEW_PENDING:
1973: case HT_WAITING:
1974: default:
1.74 cvs 1975: me->reqStatus = HT_ABORT;
1.70 cvs 1976: # ifndef _WINDOWS
1.7 cvs 1977: RequestKillAllXtevents (me);
1.74 cvs 1978: # endif _WINDOWS
1979: HTRequest_kill (me->request);
1980:
1.71 cvs 1981: if ((me->mode & AMAYA_ASYNC) ||
1982: (me->mode & AMAYA_IASYNC))
1.7 cvs 1983: {
1984: AHTReqContext_delete (me);
1985: }
1.75 cvs 1986:
1.74 cvs 1987: cur = Amaya->reqlist;
1988:
1.7 cvs 1989: open_requests--;
1.4 cvs 1990:
1.7 cvs 1991: break;
1.4 cvs 1992:
1.7 cvs 1993: } /* switch */
1994: } /* if me docid */
1995: } /* while */
1996: } /* if amaya open requests */
1.4 cvs 1997: } /* StopRequest */
1.17 cvs 1998:
1999: /*
2000: end of Module query.c
2001: */
2002:
1.69 cvs 2003: #endif /* AMAYA_JAVA */
1.77 ! cvs 2004:
! 2005:
1.17 cvs 2006:
2007:
Webmaster