Annotation of libwww/Library/src/HTResponse.c, revision 2.1
2.1 ! frystyk 1: /*
! 2: ** RESPONSE MANAGER
! 3: **
! 4: ** (c) COPYRIGHT MIT 1995.
! 5: ** Please first read the full copyright statement in the file COPYRIGH.
! 6: ** @(#) $Id: HTReqMan.c,v 2.58 1996/09/13 02:05:29 frystyk Exp $
! 7: **
! 8: ** Authors
! 9: ** HFN Henrik Frystyk, frystyk@w3.org
! 10: */
! 11:
! 12: /* Library include files */
! 13: #include "sysdep.h"
! 14: #include "WWWUtil.h"
! 15: #include "HTHeader.h"
! 16: #include "HTLib.h"
! 17: #include "HTResMan.h" /* Implemented here */
! 18:
! 19: /* --------------------------------------------------------------------------*/
! 20: /* Create and delete the HTResponse Object */
! 21: /* --------------------------------------------------------------------------*/
! 22:
! 23: PUBLIC HTResponse * HTResponse_new (void)
! 24: {
! 25: HTResponse * me;
! 26: if ((me = (HTResponse *) HT_CALLOC(1, sizeof(HTResponse))) == NULL)
! 27: HT_OUTOFMEM("HTResponse_new()");
! 28:
! 29: /* Default content-* values */
! 30: me->content_type = WWW_UNKNOWN;
! 31: me->content_length = -1;
! 32:
! 33: /* Default retry after value */
! 34: me->retry_after = -1;
! 35:
! 36: /* By default a response is not cachable */
! 37: me->cachable = NO;
! 38:
! 39: if (CORE_TRACE) HTTrace("Response.... Created %p\n", me);
! 40: return me;
! 41: }
! 42:
! 43: PUBLIC BOOL HTResponse_delete (HTResponse * me)
! 44: {
! 45: if (me) {
! 46: if (CORE_TRACE) HTTrace("Response.... Delete %p\n", me);
! 47:
! 48: /* Access Authentication */
! 49: HT_FREE(me->realm);
! 50: HT_FREE(me->scheme);
! 51: if (me->challenge) HTAssocList_delete(me->challenge);
! 52:
! 53: /* Connection headers */
! 54: if (me->connection) HTAssocList_delete(me->connection);
! 55:
! 56: /* PEP Information */
! 57: if (me->protocol) HTAssocList_delete(me->protocol);
! 58: if (me->protocol_request) HTAssocList_delete(me->protocol_request);
! 59: if (me->protocol_info) HTAssocList_delete(me->protocol_info);
! 60:
! 61: /* Cache control headers */
! 62: if (me->cache_control) HTAssocList_delete(me->cache_control);
! 63:
! 64: /* Byte ranges */
! 65: if (me->byte_ranges) HTAssocList_delete(me->byte_ranges);
! 66:
! 67: /* Content Encoding */
! 68: if (me->content_encoding) HTList_delete(me->content_encoding);
! 69:
! 70: /*
! 71: ** Only delete Content Type parameters and original headers if the
! 72: ** information is not used elsewhere, for example by the anchor
! 73: ** object.
! 74: */
! 75: if (!me->cached) {
! 76: if (me->type_parameters) HTAssocList_delete(me->type_parameters);
! 77: if (me->headers) HTAssocList_delete(me->headers);
! 78: }
! 79:
! 80: HT_FREE(me);
! 81: return YES;
! 82: }
! 83: return NO;
! 84: }
! 85:
! 86: /* --------------------------------------------------------------------------*/
! 87: /* Methods on the HTResponse Object */
! 88: /* --------------------------------------------------------------------------*/
! 89:
! 90: /*
! 91: ** Redirection information
! 92: */
! 93: PUBLIC HTAnchor * HTResponse_redirection (HTResponse * me)
! 94: {
! 95: return (me ? me->redirectionAnchor : NULL);
! 96: }
! 97:
! 98: PUBLIC BOOL HTResponse_setRedirection (HTResponse * me, HTAnchor * anchor)
! 99: {
! 100: if (me && anchor) {
! 101: me->redirectionAnchor = (HTAnchor *) HTAnchor_parent(anchor);
! 102: return YES;
! 103: }
! 104: return NO;
! 105: }
! 106:
! 107: /*
! 108: ** When to retry a response if HT_RETRY
! 109: ** Returns -1 if not available
! 110: */
! 111: PUBLIC time_t HTResponse_retryTime (HTResponse * me)
! 112: {
! 113: return me ? me->retry_after : -1;
! 114: }
! 115:
! 116: PUBLIC BOOL HTResponse_setRetryTime (HTResponse * me, time_t retry)
! 117: {
! 118: if (me) {
! 119: me->retry_after = retry;
! 120: return YES;
! 121: }
! 122: return NO;
! 123: }
! 124:
! 125: /*
! 126: ** Access Authentication Challenges
! 127: */
! 128: PUBLIC BOOL HTResponse_addChallenge (HTResponse * me,
! 129: char * token, char * value)
! 130: {
! 131: if (me) {
! 132: if (!me->challenge) me->challenge = HTAssocList_new();
! 133: return HTAssocList_addObject(me->challenge, token, value);
! 134: }
! 135: return NO;
! 136: }
! 137:
! 138: PUBLIC BOOL HTResponse_deleteChallengeAll (HTResponse * me)
! 139: {
! 140: if (me && me->challenge) {
! 141: HTAssocList_delete(me->challenge);
! 142: me->challenge = NULL;
! 143: return YES;
! 144: }
! 145: return NO;
! 146: }
! 147:
! 148: PUBLIC HTAssocList * HTResponse_challenge (HTResponse * me)
! 149: {
! 150: return (me ? me->challenge : NULL);
! 151: }
! 152:
! 153: /*
! 154: ** Access Authentication Realms
! 155: */
! 156: PUBLIC BOOL HTResponse_setRealm (HTResponse * me, char * realm)
! 157: {
! 158: if (me && realm) {
! 159: StrAllocCopy(me->realm, realm);
! 160: return YES;
! 161: }
! 162: return NO;
! 163: }
! 164:
! 165: PUBLIC const char * HTResponse_realm (HTResponse * me)
! 166: {
! 167: return (me ? me->realm : NULL);
! 168: }
! 169:
! 170: /*
! 171: ** Access Authentication Schemes
! 172: */
! 173: PUBLIC BOOL HTResponse_setScheme (HTResponse * me, char * scheme)
! 174: {
! 175: if (me && scheme) {
! 176: StrAllocCopy(me->scheme, scheme);
! 177: return YES;
! 178: }
! 179: return NO;
! 180: }
! 181:
! 182: PUBLIC const char * HTResponse_scheme (HTResponse * me)
! 183: {
! 184: return (me ? me->scheme : NULL);
! 185: }
! 186:
! 187: /*
! 188: ** Connection Directives
! 189: */
! 190: PUBLIC BOOL HTResponse_addConnection (HTResponse * me,
! 191: char * token, char * value)
! 192: {
! 193: if (me) {
! 194: if (!me->connection) me->connection = HTAssocList_new();
! 195: return HTAssocList_replaceObject(me->connection, token, value);
! 196: }
! 197: return NO;
! 198: }
! 199:
! 200: PUBLIC BOOL HTResponse_deleteConnectionAll (HTResponse * me)
! 201: {
! 202: if (me && me->connection) {
! 203: HTAssocList_delete(me->connection);
! 204: me->connection = NULL;
! 205: return YES;
! 206: }
! 207: return NO;
! 208: }
! 209:
! 210: PUBLIC HTAssocList * HTResponse_connection (HTResponse * me)
! 211: {
! 212: return (me ? me->connection : NULL);
! 213: }
! 214:
! 215: /*
! 216: ** PEP Protocol header
! 217: */
! 218: PUBLIC BOOL HTResponse_addProtocol (HTResponse * me,
! 219: char * token, char * value)
! 220: {
! 221: if (me) {
! 222: if (!me->protocol) me->protocol = HTAssocList_new();
! 223: return HTAssocList_addObject(me->protocol, token,value);
! 224: }
! 225: return NO;
! 226: }
! 227:
! 228: PUBLIC BOOL HTResponse_deleteProtocolAll (HTResponse * me)
! 229: {
! 230: if (me && me->protocol) {
! 231: HTAssocList_delete(me->protocol);
! 232: me->protocol = NULL;
! 233: return YES;
! 234: }
! 235: return NO;
! 236: }
! 237:
! 238: PUBLIC HTAssocList * HTResponse_protocol (HTResponse * me)
! 239: {
! 240: return (me ? me->protocol : NULL);
! 241: }
! 242:
! 243: /*
! 244: ** PEP Protocol Info header
! 245: */
! 246: PUBLIC BOOL HTResponse_addProtocolInfo (HTResponse * me,
! 247: char * token, char * value)
! 248: {
! 249: if (me) {
! 250: if (!me->protocol_info) me->protocol_info = HTAssocList_new();
! 251: return HTAssocList_addObject(me->protocol_info, token,value);
! 252: }
! 253: return NO;
! 254: }
! 255:
! 256: PUBLIC BOOL HTResponse_deleteProtocolInfoAll (HTResponse * me)
! 257: {
! 258: if (me && me->protocol_info) {
! 259: HTAssocList_delete(me->protocol_info);
! 260: me->protocol_info = NULL;
! 261: return YES;
! 262: }
! 263: return NO;
! 264: }
! 265:
! 266: PUBLIC HTAssocList * HTResponse_protocolInfo (HTResponse * me)
! 267: {
! 268: return (me ? me->protocol_info : NULL);
! 269: }
! 270:
! 271: /*
! 272: ** PEP Protocol request header
! 273: */
! 274: PUBLIC BOOL HTResponse_addProtocolRequest (HTResponse * me,
! 275: char * token, char * value)
! 276: {
! 277: if (me) {
! 278: if (!me->protocol_request) me->protocol_request = HTAssocList_new();
! 279: return HTAssocList_addObject(me->protocol_request, token,value);
! 280: }
! 281: return NO;
! 282: }
! 283:
! 284: PUBLIC BOOL HTResponse_deleteProtocolRequestAll (HTResponse * me)
! 285: {
! 286: if (me && me->protocol_request) {
! 287: HTAssocList_delete(me->protocol_request);
! 288: me->protocol_request = NULL;
! 289: return YES;
! 290: }
! 291: return NO;
! 292: }
! 293:
! 294: PUBLIC HTAssocList * HTResponse_protocolRequest (HTResponse * me)
! 295: {
! 296: return (me ? me->protocol_request : NULL);
! 297: }
! 298:
! 299: /*
! 300: ** Cache control directives received in the response
! 301: */
! 302: PUBLIC BOOL HTResponse_deleteCacheControlAll (HTResponse * me)
! 303: {
! 304: if (me && me->cache_control) {
! 305: HTAssocList_delete(me->cache_control);
! 306: me->cache_control = NULL;
! 307: return YES;
! 308: }
! 309: return NO;
! 310: }
! 311:
! 312: PUBLIC HTAssocList * HTResponse_cacheControl (HTResponse * me)
! 313: {
! 314: return (me ? me->cache_control : NULL);
! 315: }
! 316:
! 317: PUBLIC BOOL HTResponse_addCacheControl (HTResponse * me,
! 318: char * token, char * value)
! 319: {
! 320: if (me) {
! 321: if (!me->cache_control)
! 322: me->cache_control=HTAssocList_new();
! 323: return HTAssocList_replaceObject(me->cache_control,
! 324: token, value);
! 325: }
! 326: return NO;
! 327: }
! 328:
! 329: /*
! 330: ** Check whether we can cache this object or not.
! 331: */
! 332: PUBLIC BOOL HTResponse_isCachable (HTResponse * me)
! 333: {
! 334: if (me) {
! 335:
! 336: /* We may already have decided that this object is not cachable */
! 337: if (me->cachable == NO) return NO;
! 338:
! 339: /* We don't cache negotiated resources for the moment */
! 340: if (me->variants) return NO;
! 341:
! 342: /*
! 343: ** Check if we should cache this object or not. We are very liberale
! 344: ** in that we cache everything except if we explicit are told not to
! 345: ** cache (no-store, no-cache). In all other cases we can get around
! 346: ** it by forcing revalidation
! 347: */
! 348: if (me->cache_control) {
! 349: char * token;
! 350: if ((token=HTAssocList_findObject(me->cache_control, "no-store")))
! 351: return NO;
! 352: if ((token=HTAssocList_findObject(me->cache_control, "no-cache")))
! 353: if (!*token) return NO;
! 354: }
! 355:
! 356: /* Cache everything else */
! 357: return YES;
! 358: }
! 359: return NO;
! 360: }
! 361:
! 362: PUBLIC BOOL HTResponse_setCachable (HTResponse * me, BOOL mode)
! 363: {
! 364: if (me) {
! 365: me->cachable = mode;
! 366: return YES;
! 367: }
! 368: return NO;
! 369: }
! 370:
! 371: PUBLIC BOOL HTResponse_isCached (HTResponse * me, BOOL mode)
! 372: {
! 373: if (me) {
! 374: me->cached = mode;
! 375: return YES;
! 376: }
! 377: return NO;
! 378: }
! 379:
! 380: PUBLIC time_t HTResponse_maxAge (HTResponse * me)
! 381: {
! 382: if (me && me->cache_control) {
! 383: char * token = HTAssocList_findObject(me->cache_control, "max-age");
! 384: if (token) return atol(token);
! 385: }
! 386: return (time_t) -1;
! 387: }
! 388:
! 389: PUBLIC BOOL HTResponse_mustRevalidate (HTResponse * me)
! 390: {
! 391: return me && me->cache_control &&
! 392: (HTAssocList_findObject(me->cache_control,
! 393: "must-revalidate") != NULL);
! 394: }
! 395:
! 396: PUBLIC char * HTResponse_noCache (HTResponse * me)
! 397: {
! 398: return (me && me->cache_control) ?
! 399: HTAssocList_findObject(me->cache_control,
! 400: "no-cache") : NULL;
! 401: }
! 402:
! 403: /*
! 404: ** Byte ranges
! 405: */
! 406: PUBLIC BOOL HTResponse_deleteRangeAll (HTResponse * me)
! 407: {
! 408: if (me && me->byte_ranges) {
! 409: HTAssocList_delete(me->byte_ranges);
! 410: me->byte_ranges = NULL;
! 411: return YES;
! 412: }
! 413: return NO;
! 414: }
! 415:
! 416: PUBLIC BOOL HTResponse_addRange (HTResponse * me, char * unit, char * range)
! 417: {
! 418: if (me) {
! 419: if (!me->byte_ranges) me->byte_ranges = HTAssocList_new();
! 420: return HTAssocList_replaceObject(me->byte_ranges, unit, range);
! 421: }
! 422: return NO;
! 423: }
! 424:
! 425: PUBLIC HTAssocList * HTResponse_range (HTResponse * me)
! 426: {
! 427: return (me ? me->byte_ranges : NULL);
! 428: }
! 429:
! 430: /*
! 431: ** Content Length
! 432: */
! 433: PUBLIC long int HTResponse_length (HTResponse * me)
! 434: {
! 435: return me ? me->content_length : -1;
! 436: }
! 437:
! 438: PUBLIC void HTResponse_setLength (HTResponse * me, long int length)
! 439: {
! 440: if (me) me->content_length = length;
! 441: }
! 442:
! 443: PUBLIC void HTResponse_addLength (HTResponse * me, long int delta_length)
! 444: {
! 445: if (me) {
! 446: if (me->content_length < 0)
! 447: me->content_length = delta_length;
! 448: else
! 449: me->content_length += delta_length;
! 450: }
! 451: }
! 452:
! 453: /*
! 454: ** Content-Type
! 455: */
! 456: PUBLIC HTFormat HTResponse_format (HTResponse * me)
! 457: {
! 458: return me ? me->content_type : NULL;
! 459: }
! 460:
! 461: PUBLIC void HTResponse_setFormat (HTResponse * me, HTFormat form)
! 462: {
! 463: if (me) me->content_type = form;
! 464: }
! 465:
! 466: PUBLIC HTAssocList * HTResponse_formatParam (HTResponse * me)
! 467: {
! 468: return me ? me->type_parameters : NULL;
! 469: }
! 470:
! 471: PUBLIC BOOL HTResponse_addFormatParam (HTResponse * me,
! 472: const char * name, const char * value)
! 473: {
! 474: if (me) {
! 475: if (!me->type_parameters) me->type_parameters = HTAssocList_new();
! 476: return HTAssocList_replaceObject(me->type_parameters, name, value);
! 477: }
! 478: return NO;
! 479: }
! 480:
! 481: /*
! 482: ** Charset parameter to Content-Type
! 483: */
! 484: PUBLIC HTCharset HTResponse_charset (HTResponse * me)
! 485: {
! 486: if (me && me->type_parameters) {
! 487: char * charset = HTAssocList_findObject(me->type_parameters,"charset");
! 488: return HTAtom_for(charset);
! 489: }
! 490: return NULL;
! 491: }
! 492:
! 493: PUBLIC BOOL HTResponse_setCharset (HTResponse * me, HTCharset charset)
! 494: {
! 495: return HTResponse_addFormatParam(me, "charset", HTAtom_name(charset));
! 496: }
! 497:
! 498: /*
! 499: ** Content Encoding
! 500: */
! 501: PUBLIC BOOL HTResponse_addEncoding (HTResponse * me, HTEncoding encoding)
! 502: {
! 503: if (me && encoding) {
! 504: if (!me->content_encoding) me->content_encoding = HTList_new();
! 505: return HTList_addObject(me->content_encoding, encoding);
! 506: }
! 507: return NO;
! 508: }
! 509:
! 510: PUBLIC HTList * HTResponse_encoding (HTResponse * me)
! 511: {
! 512: return me ? me->content_encoding : NULL;
! 513: }
! 514:
! 515: /*
! 516: ** Content Transfer Encoding
! 517: */
! 518: PUBLIC HTEncoding HTResponse_transfer (HTResponse * me)
! 519: {
! 520: return me ? me->transfer_encoding : NULL;
! 521: }
! 522:
! 523: PUBLIC BOOL HTResponse_setTransfer (HTResponse * me, HTEncoding transfer)
! 524: {
! 525: if (me) {
! 526: me->transfer_encoding = transfer;
! 527: return YES;
! 528: }
! 529: return NO;
! 530: }
! 531:
! 532: PUBLIC BOOL HTResponse_addVariant (HTResponse * me, char * token, char * value)
! 533: {
! 534: if (me) {
! 535: if (!me->variants) me->variants =HTAssocList_new();
! 536: return HTAssocList_replaceObject (me->variants, token, value);
! 537: }
! 538: return NO;
! 539: }
! 540:
! 541: PUBLIC BOOL HTResponse_deleteVariantAll (HTResponse * me)
! 542: {
! 543: if (me && me->variants) {
! 544: HTAssocList_delete(me->variants);
! 545: me->variants = NULL;
! 546: return YES;
! 547: }
! 548: return NO;
! 549: }
! 550:
! 551: PUBLIC HTAssocList * HTResponse_variant (HTResponse * me)
! 552: {
! 553: return (me ? me->variants : NULL);
! 554: }
! 555:
! 556: /*
! 557: ** Original header information
! 558: */
! 559: PUBLIC BOOL HTResponse_addHeader (HTResponse * me,
! 560: char * token, char * value)
! 561: {
! 562: if (me) {
! 563: if (!me->headers) me->headers = HTAssocList_new();
! 564: return HTAssocList_addObject(me->headers, token, value);
! 565: }
! 566: return NO;
! 567: }
! 568:
! 569: PUBLIC BOOL HTResponse_deleteHeaderAll (HTResponse * me)
! 570: {
! 571: if (me && me->headers) {
! 572: HTAssocList_delete(me->headers);
! 573: me->headers = NULL;
! 574: return YES;
! 575: }
! 576: return NO;
! 577: }
! 578:
! 579: PUBLIC HTAssocList * HTResponse_header (HTResponse * me)
! 580: {
! 581: return (me ? me->headers : NULL);
! 582: }
! 583:
! 584:
! 585:
Webmaster