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