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