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