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