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