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