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