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