Return to query.c CVS log | Up to [Public] / Amaya / amaya |
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; 214: #ifdef WWW_XWINDOWS 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.4 cvs 391: #ifdef WWW_XWINDOWS 1.7 cvs 392: RequestKillAllXtevents (me); 1.4 cvs 393: #endif /* WWW_XWINDOWS */ 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 1134: JavaSetSelectCallback(W3ContinueRequest); 1135: #endif 1136: 1.24 cvs 1137: AmayaIsAlive = TRUE; 1.4 cvs 1138: AHTProfile_newAmaya (HTAppName, HTAppVersion); 1139: 1140: /* New AHTBridge stuff */ 1141: 1142: HTEvent_setRegisterCallback (AHTEvent_register); 1143: HTEvent_setUnregisterCallback (AHTEvent_unregister); 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: 1203: #ifdef WWW_XWINDOWS 1.25 cvs 1204: extern ThotAppContext app_cont; 1.15 cvs 1205: XEvent ev; 1206: XtInputMask status; 1207: 1208: #endif /* WWW_XWINDOWS */ 1.17 cvs 1209: int status_req = HT_OK; 1.15 cvs 1210: 1211: /* to test the async calls */ 1.17 cvs 1212: /* Loop while waiting for new events, exists when the request is over */ 1.15 cvs 1213: while (me->reqStatus != HT_ABORT && 1214: me->reqStatus != HT_END && 1215: me->reqStatus != HT_ERR) 1216: { 1217: 1218: #ifdef WWW_XWINDOWS 1.27 cvs 1219: if (!AmayaIsAlive) 1220: /* Amaya was killed by one of the callback handlers */ 1221: exit (0); 1222: 1.37 cvs 1223: #ifdef AMAYA_JAVA 1224: JavaPollLoop(app_cont); 1225: #else /* ! AMAYA_JAVA */ 1226: status = XtAppPending (app_cont); 1227: if (status & XtIMXEvent) 1228: { 1229: XtAppNextEvent (app_cont, &ev); 1230: TtaHandleOneEvent (&ev); 1231: } 1232: else if (status & (XtIMAll & (~XtIMXEvent))) 1233: { 1234: XtAppProcessEvent (app_cont, 1235: (XtIMAll & (~XtIMXEvent))); 1236: } 1237: else 1238: { 1239: XtAppNextEvent (app_cont, &ev); 1240: TtaHandleOneEvent (&ev); 1241: } 1242: #endif /* AMAYA_JAVA */ 1.15 cvs 1243: #endif /* WWW_XWINDOWS */ 1244: } 1245: 1246: switch (me->reqStatus) 1247: { 1.4 cvs 1248: 1.15 cvs 1249: case HT_ERR: 1250: case HT_ABORT: 1251: status_req = HT_ERROR; 1252: break; 1253: 1254: case HT_END: 1255: status_req = HT_OK; 1256: break; 1257: 1258: default: 1259: break; 1260: } 1.12 cvs 1261: 1.15 cvs 1262: return (status_req); 1.4 cvs 1263: } 1264: 1265: 1.5 cvs 1266: /*---------------------------------------------------------------------- 1.15 cvs 1267: QueryClose 1.21 cvs 1268: closes all existing threads, frees all non-automatically deallocated 1269: memory and then ends libwww. 1.5 cvs 1270: ----------------------------------------------------------------------*/ 1.4 cvs 1271: void QueryClose () 1272: { 1.24 cvs 1273: 1274: AmayaIsAlive = FALSE; 1275: 1.21 cvs 1276: /* remove all the handlers and callbacks that may output a message to 1277: a non-existent Amaya window */ 1278: 1279: HTNet_deleteAfter (AHTLoadTerminate_handler); 1280: HTNet_deleteAfter (redirection_handler); 1281: HTAlertCall_deleteAll (HTAlert_global () ); 1.23 cvs 1282: HTAlert_setGlobal ((HTList *) NULL); 1.24 cvs 1283: HTEvent_setRegisterCallback ((HTEvent_registerCallback *) NULL); 1.27 cvs 1284: HTEvent_setUnregisterCallback ((HTEvent_unregisterCallback *) NULL); 1.21 cvs 1285: 1.4 cvs 1286: Thread_deleteAll (); 1.21 cvs 1287: 1.4 cvs 1288: #ifndef HACK_WWW 1289: /** HTAuthInfo_deleteAll (); **/ 1290: #endif 1291: HTProxy_deleteAll (); 1292: HTNoProxy_deleteAll (); 1293: HTGateway_deleteAll (); 1294: AHTProfile_delete (); 1295: } 1296: 1297: 1.5 cvs 1298: /*---------------------------------------------------------------------- 1.15 cvs 1299: GetObjectWWW 1.17 cvs 1300: this function requests a resource designated by a URLname into a 1301: temporary filename. The download can come from a simple GET operation, 1302: or can come from POSTING/GETTING a form. In the latter 1303: case, the function receives a query string to send to the server. 1304: 1.5 cvs 1305: 4 file retrieval modes are proposed: 1306: AMAYA_SYNC : blocking mode 1307: AMAYA_ISYNC : incremental, blocking mode 1308: AMAYA_ASYNC : non-blocking mode 1309: AMAYA_IASYNC : incremental, non-blocking mode 1310: 1311: In the incremental mode, each time a package arrives, it will be 1312: stored in the temporary file. In addition, if an 1313: incremental_callback function is defined, this function will be 1314: called and handled a copy of the newly received data package. 1315: Finally, if a terminate_callback function is defined, it will be 1316: invoked when the request terminates. The caller of this function 1.4 cvs 1317: can define two different contexts to be passed to the callback 1318: functions. 1319: 1320: When the function is called with the SYNC mode, the function will 1321: return only when the requested file has been loaded. 1322: The ASYNC mode will immediately return after setting up the 1323: call. 1324: 1325: Notes: 1326: At the end of a succesful request, the urlName string contains the 1327: name of the actually retrieved URL. As a URL can change over the time, 1328: (e.g., be redirected elsewhere), it is advised that the function 1.17 cvs 1329: caller verify the value of the urlName variable at the end of 1.4 cvs 1330: a request. 1331: 1332: Inputs: 1333: - docid Document identifier for the set of objects being 1334: retrieved. 1335: - urlName The URL to be retrieved (MAX_URL_LENGTH chars length) 1336: - outputfile A pointer to an empty string of MAX_URL_LENGTH. 1337: - mode The retrieval mode. 1338: - incremental_cbf 1339: - context_icbf 1340: Callback and context for the incremental modes 1341: - terminate_cbf 1342: - context_icbf 1343: Callback and context for a terminate handler 1.17 cvs 1344: -error_html if TRUE, then display any server error message as an 1345: HTML document. 1.4 cvs 1346: 1347: Outputs: 1348: - urlName The URL that was retrieved 1349: - outputfile The name of the temporary file which holds the 1350: retrieved data. (Only in case of success) 1351: Returns: 1352: HT_ERROR 1353: HT_OK 1.5 cvs 1354: 1355: ----------------------------------------------------------------------*/ 1.4 cvs 1356: #ifdef __STDC__ 1357: int GetObjectWWW (int docid, char *urlName, char *postString, 1358: char *outputfile, int mode, 1359: TIcbf * incremental_cbf, void *context_icbf, 1.15 cvs 1360: TTcbf * terminate_cbf, void *context_tcbf, boolean error_html) 1.4 cvs 1361: #else 1362: int GetObjectWWW (docid, urlName, postString, outputfile, mode, 1363: incremental_cbf, context_icbf, terminate_cbf, context_tcbf, 1364: error_html) 1365: int docid; 1366: char *urlName; 1367: char *postString; 1368: char *outputfile; 1369: int mode; 1370: TIcbf *incremental_cbf; 1371: void *context_icbf; 1372: TTcbf *terminate_cbf; 1373: void *context_tcbf; 1.15 cvs 1374: boolean error_html; 1.4 cvs 1375: #endif 1376: { 1377: AHTReqContext *me; 1378: 1379: FILE *tmp_fp; 1380: char *tmp_dir; 1381: char *ref; 1382: int status; 1383: HTList *cur, *pending; 1.7 cvs 1384: 1385: if (urlName == NULL || docid == 0 || outputfile == NULL) 1386: { 1387: /* no file to be loaded */ 1388: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), 1389: urlName); 1390: 1391: if (error_html) 1392: FilesLoading[docid] = 2; /* so we can show the error message */ 1393: return HT_ERROR; 1.4 cvs 1394: 1.7 cvs 1395: } 1.4 cvs 1396: /* do we support this protocol? */ 1.7 cvs 1397: if (IsValidProtocol (urlName) == NO) 1398: { 1399: /* return error */ 1400: outputfile[0] = EOS; /* file could not be opened */ 1401: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_GET_UNSUPPORTED_PROTOCOL), 1402: urlName); 1403: 1404: if (error_html) 1405: FilesLoading[docid] = 2; /* so we can show the error message */ 1406: return HT_ERROR; 1407: } 1.4 cvs 1408: 1409: /* verify if a docid directory exists */ 1410: 1411: tmp_dir = TtaGetMemory (strlen (TempFileDirectory) + 5 + 1); 1412: sprintf (tmp_dir, "%s/%d", TempFileDirectory, docid); 1413: 1414: tmp_fp = fopen (tmp_dir, "r"); 1.7 cvs 1415: if (tmp_fp == 0) 1416: { 1417: /*directory did not exist */ 1418: if (mkdir (tmp_dir, S_IRWXU) == -1) 1419: { 1420: /*error */ 1421: outputfile[0] = EOS; 1422: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_CACHE_ERROR), 1423: urlName); 1424: 1425: if (error_html) 1426: FilesLoading[docid] = 2; /* so we can show the error message */ 1427: 1428: return HT_ERROR; 1429: } 1430: } 1431: else 1.4 cvs 1432: fclose (tmp_fp); 1433: 1434: /*create a tempfilename */ 1435: 1436: sprintf (outputfile, "%s/%04dAM", tmp_dir, object_counter); 1437: 1438: TtaFreeMemory (tmp_dir); 1439: 1440: /* update the object_counter */ 1441: object_counter++; 1442: 1443: /* normalize the URL */ 1444: ref = HTParse (urlName, "", PARSE_ALL); 1445: 1446: /* should we abort the request if we could not normalize the url? */ 1447: 1.7 cvs 1448: if (ref == (char *) NULL || ref[0] == EOS) 1449: { 1450: /*error */ 1451: outputfile[0] = EOS; 1452: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), 1453: urlName); 1.4 cvs 1454: 1.7 cvs 1455: if (error_html) 1456: FilesLoading[docid] = 2; /* so we can show the error message */ 1.4 cvs 1457: 1.7 cvs 1458: return HT_ERROR; 1459: } 1.4 cvs 1460: /* verify if that file name existed */ 1.9 cvs 1461: if (TtaFileExist (outputfile)) 1.7 cvs 1462: { 1.9 cvs 1463: TtaFileUnlink (outputfile); 1.7 cvs 1464: } 1.4 cvs 1465: 1466: /* try to open the outputfile */ 1467: 1.7 cvs 1468: if ((tmp_fp = fopen (outputfile, "w")) == NULL) 1469: { 1470: outputfile[0] = EOS; /* file could not be opened */ 1471: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE), 1472: outputfile); 1473: HT_FREE (ref); 1474: 1475: if (error_html) 1476: FilesLoading[docid] = 2; /* so we can show the error message */ 1477: return (HT_ERROR); 1478: } 1.4 cvs 1479: 1480: /* the terminate_handler closes the above open fp */ 1481: /* Not anymore, we do that in the AHTCallback_bridge, as all 1482: requests are now asynchronous */ 1483: 1484: /* Initialize the request structure */ 1485: 1486: me = AHTReqContext_new (docid); 1487: 1.7 cvs 1488: if (me == NULL) 1489: { 1490: fclose (tmp_fp); 1491: outputfile[0] = EOS; 1492: /* need an error message here */ 1493: HT_FREE (ref); 1494: return (HT_ERROR); 1495: } 1.4 cvs 1496: 1497: 1498: /* Specific initializations for POST and GET */ 1.7 cvs 1499: if (mode & AMAYA_FORM_POST) 1500: { 1501: me->method = METHOD_POST; 1.20 cvs 1502: if (postString) 1503: { 1504: me->mem_ptr = postString; 1505: me->block_size = strlen (postString); 1506: } 1507: else 1508: { 1509: me->mem_ptr = ""; 1510: me->block_size = 0; 1511: } 1.7 cvs 1512: HTRequest_setMethod (me->request, METHOD_POST); 1513: HTRequest_setPostCallback (me->request, AHTUpload_callback); 1514: } 1515: else 1516: { 1517: me->method = METHOD_GET; 1518: me->dest = (HTParentAnchor *) NULL; /*useful only for PUT and POST methods */ 1.27 cvs 1519: if (!HasKnownFileSuffix (ref)) 1520: HTRequest_setConversion(me->request, acceptTypes, TRUE); 1.7 cvs 1521: } 1.4 cvs 1522: 1523: /* Common initialization */ 1524: 1525: me->mode = mode; 1526: me->error_html = error_html; 1527: me->incremental_cbf = incremental_cbf; 1528: me->context_icbf = context_icbf; 1529: me->terminate_cbf = terminate_cbf; 1530: me->context_tcbf = context_tcbf; 1531: me->output = tmp_fp; 1532: 1533: HTRequest_setOutputStream (me->request, 1534: AHTFWriter_new (me->request, me->output, YES)); 1.7 cvs 1535: 1.4 cvs 1536: 1537: /*for the async. request modes, we need to have our 1538: own copy of outputfile and urlname 1539: */ 1540: 1.7 cvs 1541: if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC)) 1542: { 1543: char *tmp; 1544: 1545: tmp = TtaGetMemory (strlen (outputfile) + 1); 1546: strcpy (tmp, outputfile); 1547: me->outputfile = tmp; 1548: 1.21 cvs 1549: tmp = TtaGetMemory (MAX_LENGTH + 1); 1550: strncpy (tmp, urlName, MAX_LENGTH); 1551: tmp[MAX_LENGTH] = EOS; 1.7 cvs 1552: me->urlName = tmp; 1553: } 1554: else 1555: { 1556: me->outputfile = outputfile; 1557: me->urlName = urlName; 1558: } 1.38 cvs 1559: 1560: /* prepare the URLname that will be displayed in teh status bar */ 1561: ChopURL (me->status_urlName, me->urlName); 1.4 cvs 1562: 1563: /*** 1564: Change for taking into account the stop button: 1565: The requests will be always asynchronous, however, if mode=AMAYA_SYNC, 1566: we will loop until the document has been received or a stop signal 1567: generated 1568: ****/ 1569: 1570: HTRequest_setPreemptive (me->request, NO); 1571: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_FETCHING), 1.38 cvs 1572: me->status_urlName); 1.4 cvs 1573: 1574: me->anchor = (HTParentAnchor *) HTAnchor_findAddress (ref); 1575: 1576: HT_FREE (ref); 1577: 1.7 cvs 1578: if (mode & AMAYA_FORM_POST) 1579: { 1580: HTAnchor_setFormat ((HTParentAnchor *) me->anchor, HTAtom_for ("application/x-www-form-urlencoded")); 1581: HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size); 1582: HTRequest_setEntityAnchor (me->request, me->anchor); 1.4 cvs 1583: 1.7 cvs 1584: status = HTLoadAbsolute (urlName, me->request); 1585: } 1586: else 1.4 cvs 1587: status = HTLoadAnchor ((HTAnchor *) me->anchor, 1588: me->request); 1589: 1590: if (status == HT_ERROR || me->reqStatus == HT_END 1.7 cvs 1591: || me->reqStatus == HT_ERR) 1592: { 1593: /* in case of error, free all allocated memory and exit */ 1594: 1.21 cvs 1595: if (me->output) 1596: fclose (me->output); 1597: 1.7 cvs 1598: if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC)) 1599: { 1.21 cvs 1600: if(me->outputfile) 1601: TtaFreeMemory (me->outputfile); 1602: if(me->urlName) 1603: TtaFreeMemory (me->urlName); 1.7 cvs 1604: } 1.4 cvs 1605: 1.27 cvs 1606: if (me->reqStatus == HT_ERR) 1607: { 1608: status = HT_ERROR; 1609: /* show an error message on the status bar */ 1610: FilesLoading[me->docid] = 2; 1611: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_LOAD), 1.38 cvs 1612: me->status_urlName); 1.27 cvs 1613: } 1614: else 1615: status = HT_OK; 1.7 cvs 1616: 1617: AHTReqContext_delete (me); 1.27 cvs 1618: } 1.7 cvs 1619: 1620: else 1621: { 1622: /* part of the stop button handler */ 1623: 1624: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC)) 1625: { 1626: status = LoopForStop (me); 1627: AHTReqContext_delete (me); 1628: } 1629: else 1630: { 1631: 1632: /* ASYNC MODE */ 1633: /* if the request went to the pending events queue, then we close 1634: ** the file. It'll be open by AddEventLoop upon liberation of the 1635: ** queue 1.4 cvs 1636: */ 1.7 cvs 1637: 1638: /* verify if this request went to the pending request queue */ 1639: 1640: if ((cur = (HTList *) me->request->net->host->pending)) 1641: while ((pending = HTList_nextObject (cur))) 1642: { 1643: if (me->request->net == (HTNet *) pending) 1644: { 1645: /* To correct: see if we can fine tune this request */ 1646: if (me->reqStatus == HT_WAITING) 1647: break; 1648: me->reqStatus = HT_NEW_PENDING; 1649: /* the request went to the pending queue, so we close the fd to 1650: **avoid having many of them open without being used 1651: */ 1652: if (THD_TRACE) 1653: fprintf (stderr, "GetObjectWWW: %s is pending. Closing fd %d\n", me->urlName, (int) me->output); 1.21 cvs 1654: /* free the allocated stream object */ 1655: AHTFWriter_FREE (HTRequest_outputStream(me->request)); 1656: HTRequest_setOutputStream (me->request, (HTStream *) NULL); 1.7 cvs 1657: fclose (me->output); 1658: me->output = NULL; 1659: break; 1660: } 1661: } 1662: 1.4 cvs 1663: } 1.7 cvs 1664: } 1.4 cvs 1665: TtaHandlePendingEvents (); 1666: 1667: return (status); 1668: } 1669: 1.5 cvs 1670: /*---------------------------------------------------------------------- 1.17 cvs 1671: PutObjectWWW 1672: frontend for uploading a resource to a URL. This function downloads 1673: a file to be uploaded into memory, it then calls UploadMemWWW to 1674: finish the job. 1675: 1.5 cvs 1676: 2 upload modes are proposed: 1677: AMAYA_SYNC : blocking mode 1678: AMAYA_ASYNC : non-blocking mode 1679: 1.4 cvs 1680: When the function is called with the SYNC mode, the function will 1681: return only when the file has been uploaded. 1682: The ASYNC mode will immediately return after setting up the 1683: call. Furthermore, at the end of an upload, the ASYNC mode will 1684: call back terminate_cbf, handling it the context defined in 1685: context_tcbf. 1686: 1687: Notes: 1688: At the end of a succesful request, the urlName string contains the 1689: name of the actually uploaded URL. As a URL can change over the time, 1690: (e.g., be redirected elsewhere), it is advised that the function 1691: caller verifies the value of the urlName variable at the end of 1692: a request. 1693: 1694: Inputs: 1695: - docid Document identifier for the set of objects being 1696: retrieved. 1697: - fileName A pointer to the local file to upload 1698: - urlName The URL to be uploaded (MAX_URL_LENGTH chars length) 1699: - mode The retrieval mode. 1700: - terminate_cbf 1701: - context_icbf 1702: Callback and context for a terminate handler 1703: 1704: Outputs: 1705: - urlName The URL that was uploaded 1706: 1707: Returns: 1708: HT_ERROR 1709: HT_OK 1.5 cvs 1710: ----------------------------------------------------------------------*/ 1.4 cvs 1711: #ifdef __STDC__ 1.27 cvs 1712: int PutObjectWWW (int docid, char *fileName, char *urlName, int mode, PicType contentType, 1.4 cvs 1713: TTcbf * terminate_cbf, void *context_tcbf) 1714: #else 1.26 cvs 1715: int PutObjectWWW (docid, urlName, fileName, mode, contentType, 1.4 cvs 1716: ,terminate_cbf, context_tcbf) 1717: int docid; 1718: char *urlName; 1719: char *fileName; 1720: int mode; 1.27 cvs 1721: PicType contentType; 1.4 cvs 1722: TTcbf *terminate_cbf; 1723: void *context_tcbf; 1724: 1725: #endif 1726: { 1.7 cvs 1727: /*AHTReqContext *me; */ 1.4 cvs 1728: int status; 1729: 1730: #ifdef WWW_XWINDOWS 1731: int fd; 1732: struct stat file_stat; 1733: char *mem_ptr; 1734: unsigned long block_size; 1735: 1.33 cvs 1736: AmayaLastHTTPErrorMsg [0] = EOS; 1737: 1.4 cvs 1738: if (urlName == NULL || docid == 0 || fileName == NULL || 1.9 cvs 1739: !TtaFileExist (fileName)) 1.4 cvs 1740: /* no file to be uploaded */ 1741: return HT_ERROR; 1742: 1743: /* do we support this protocol? */ 1.7 cvs 1744: if (IsValidProtocol (urlName) == NO) 1745: { 1746: /* return error */ 1747: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_PUT_UNSUPPORTED_PROTOCOL), 1748: urlName); 1749: return HT_ERROR; 1750: } 1.4 cvs 1751: /* read the file into memory */ 1752: 1.7 cvs 1753: if ((fd = open (fileName, O_RDONLY)) == -1) 1754: { 1755: /* if we could not open the file, exit */ 1756: /*error msg here */ 1757: return (HT_ERROR); 1758: } 1.4 cvs 1759: 1760: fstat (fd, &file_stat); 1761: 1.7 cvs 1762: if (file_stat.st_size == 0) 1763: { 1764: /* file was empty */ 1765: /*errmsg here */ 1766: close (fd); 1767: return (HT_ERROR); 1768: } 1.4 cvs 1769: block_size = file_stat.st_size; 1770: 1771: if (THD_TRACE) 1772: fprintf (stderr, "file size == %u\n", (unsigned) block_size); 1773: 1774: mem_ptr = (char *) TtaGetMemory (block_size); 1775: 1.7 cvs 1776: if (mem_ptr == (char *) NULL) 1777: { 1778: /* could not allocate enough memory */ 1779: /*errmsg here */ 1.4 cvs 1780: 1.7 cvs 1781: close (fd); 1782: return (HT_ERROR); 1783: } 1.4 cvs 1784: read (fd, mem_ptr, block_size); 1785: 1786: close (fd); 1787: 1.27 cvs 1788: status = UploadMemWWW (docid, METHOD_PUT, urlName, contentType, mem_ptr, 1.4 cvs 1789: block_size, mode, terminate_cbf, 1790: context_tcbf, (char *) NULL); 1791: 1792: TtaFreeMemory (mem_ptr); 1.28 cvs 1793: TtaHandlePendingEvents (); 1.4 cvs 1794: 1795: #endif /*WWW_XWINDOWS */ 1796: 1797: return (status); 1798: } 1799: 1800: 1.5 cvs 1801: /*---------------------------------------------------------------------- 1.17 cvs 1802: UploadMemWWW 1803: low level interface function to libwww for uploading a block of 1804: memory to a URL. 1.5 cvs 1805: ----------------------------------------------------------------------*/ 1.4 cvs 1806: #ifdef __STDC__ 1807: int UploadMemWWW (int docid, HTMethod method, 1.27 cvs 1808: char *urlName, PicType contentType, char *mem_ptr, unsigned long block_size, 1.4 cvs 1809: int mode, TTcbf * terminate_cbf, void *context_tcbf, 1810: char *outputfile) 1811: #else 1.27 cvs 1812: int UploadMemWWW (docid, method, urlName, contentType, mem_ptr, block_size, mode, 1.4 cvs 1813: terminate_cbf, context_tcbf, outputfile) 1814: int docid; 1815: HTMethod method; 1816: char *urlName; 1.27 cvs 1817: PicType contentType; 1.4 cvs 1818: char *mem_ptr; 1819: usigned long block_size; 1820: int mode; 1821: TTcbf *terminate_cbf; 1822: void *context_tcbf; 1823: char *outputfile; 1.7 cvs 1824: 1.4 cvs 1825: #endif 1826: { 1827: AHTReqContext *me; 1828: int status; 1829: 1830: if (mem_ptr == (char *) NULL || 1831: block_size == 0 || 1832: docid == 0 || 1.7 cvs 1833: urlName == (char *) NULL) 1834: { 1835: /* nothing to be uploaded */ 1836: return HT_ERROR; 1837: } 1.4 cvs 1838: 1839: /* Initialize the request structure */ 1840: me = AHTReqContext_new (docid); 1841: 1.7 cvs 1842: if (me == NULL) 1843: { 1844: /* need an error message here */ 1845: TtaHandlePendingEvents (); 1846: return (HT_ERROR); 1847: } 1.4 cvs 1848: me->mode = mode; 1849: 1850: me->incremental_cbf = (TIcbf *) NULL; 1851: me->context_icbf = (void *) NULL; 1852: me->terminate_cbf = terminate_cbf; 1853: me->context_tcbf = context_tcbf; 1854: 1855: me->output = stdout; 1856: me->outputfile = (char *) NULL; 1857: me->urlName = urlName; 1858: 1859: HTRequest_setPreemptive (me->request, NO); 1860: 1.17 cvs 1861: /* select the parameters that distinguish a PUT from a GET/POST */ 1.4 cvs 1862: me->method = METHOD_PUT; 1863: HTRequest_setMethod (me->request, METHOD_PUT); 1864: me->output = stdout; 1.17 cvs 1865: /* we are not expecting to receive any input from the server */ 1866: me->outputfile = (char *) NULL; 1.4 cvs 1867: 1868: me->mem_ptr = mem_ptr; 1869: me->block_size = block_size; 1.17 cvs 1870: 1871: /* set the callback which will actually copy data into the 1872: output stream */ 1873: 1.4 cvs 1874: HTRequest_setPostCallback (me->request, AHTUpload_callback); 1875: 1876: HTRequest_setOutputStream (me->request, 1877: HTFWriter_new (me->request, me->output, YES)); 1878: 1879: me->anchor = (HTParentAnchor *) HTAnchor_findAddress (urlName); 1.7 cvs 1880: 1.28 cvs 1881: /* Set the Content-Type of the file we are uploading */ 1.27 cvs 1882: HTAnchor_setFormat ((HTParentAnchor *) me->anchor, AHTGuessAtom_for (me->urlName, contentType)); 1.17 cvs 1883: 1.7 cvs 1884: HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size); 1.4 cvs 1885: HTRequest_setEntityAnchor (me->request, me->anchor); 1886: status = HTLoadAbsolute (urlName, me->request); 1887: 1.28 cvs 1888: if (status == HT_ERROR || me->reqStatus == HT_END || me->reqStatus == HT_ERR || HTError_hasSeverity (HTRequest_error (me->request), ERR_INFO)) 1.7 cvs 1889: { 1.17 cvs 1890: status = HT_ERROR; 1891: AHTReqContext_delete (me); 1.28 cvs 1892: } 1.7 cvs 1893: else 1894: { 1.38 cvs 1895: /* prepare the URLname that will be displayed in teh status bar */ 1896: ChopURL (me->status_urlName, me->urlName); 1897: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REMOTE_SAVING), 1898: me->status_urlName); 1.4 cvs 1899: 1.7 cvs 1900: /* part of the stop button handler */ 1.4 cvs 1901: 1.7 cvs 1902: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC)) 1903: { 1904: status = LoopForStop (me); 1905: AHTReqContext_delete (me); 1906: } 1.15 cvs 1907: } 1.4 cvs 1908: return (status); 1.28 cvs 1909: } 1.4 cvs 1910: 1911: 1912: 1.5 cvs 1913: /*---------------------------------------------------------------------- 1.17 cvs 1914: Stop Request 1915: stops (kills) all active requests associated with a docid 1.5 cvs 1916: ----------------------------------------------------------------------*/ 1.4 cvs 1917: #ifdef __STDC__ 1918: void StopRequest (int docid) 1919: #else 1920: void StopRequest (docid) 1921: int docid; 1922: #endif 1923: { 1924: HTList *cur; 1925: AHTDocId_Status *docid_status; 1926: AHTReqContext *me; 1927: int open_requests; 1928: 1.7 cvs 1929: if (Amaya) 1930: { 1.4 cvs 1931: 1.7 cvs 1932: cur = Amaya->reqlist; 1933: docid_status = (AHTDocId_Status *) GetDocIdStatus (docid, 1.4 cvs 1934: Amaya->docid_status); 1935: 1.7 cvs 1936: /* verify if there are any requests at all associated with docid */ 1.4 cvs 1937: 1.7 cvs 1938: if (docid_status == (AHTDocId_Status *) NULL) 1939: return; 1.4 cvs 1940: 1.7 cvs 1941: open_requests = docid_status->counter; 1.4 cvs 1942: 1.7 cvs 1943: while ((me = (AHTReqContext *) HTList_nextObject (cur))) 1944: { 1.4 cvs 1945: 1.7 cvs 1946: if (me->docid == docid) 1947: { 1948: /* kill this request */ 1.4 cvs 1949: 1.7 cvs 1950: switch (me->reqStatus) 1951: { 1952: case HT_ABORT: 1953: break; 1.4 cvs 1954: 1.7 cvs 1955: case HT_BUSY: 1956: me->reqStatus = HT_ABORT; 1957: break; 1958: case HT_NEW_PENDING: 1959: case HT_WAITING: 1960: default: 1.4 cvs 1961: #ifdef WWW_XWINDOWS 1.7 cvs 1962: RequestKillAllXtevents (me); 1.4 cvs 1963: #endif 1.7 cvs 1964: me->reqStatus = HT_ABORT; 1965: HTRequest_kill (me->request); 1.4 cvs 1966: 1.7 cvs 1967: if (me->mode == AMAYA_ASYNC || 1968: me->mode == AMAYA_IASYNC) 1969: { 1.4 cvs 1970: 1.7 cvs 1971: AHTReqContext_delete (me); 1972: } 1973: cur = Amaya->reqlist; 1.4 cvs 1974: 1.7 cvs 1975: open_requests--; 1.4 cvs 1976: 1.7 cvs 1977: break; 1.4 cvs 1978: 1.7 cvs 1979: } /* switch */ 1980: } /* if me docid */ 1981: } /* while */ 1982: } /* if amaya open requests */ 1.4 cvs 1983: } /* StopRequest */ 1.17 cvs 1984: 1985: 1986: /* 1987: end of Module query.c 1988: */ 1989: 1990: 1991: