Annotation of libwww/Library/src/HTMIMImp.c, revision 2.23
2.1 frystyk 1: /*
2.8 frystyk 2: ** DEFAULT MIME HEADER PARSERS
2.1 frystyk 3: **
4: ** (c) COPYRIGHT MIT 1995.
5: ** Please first read the full copyright statement in the file COPYRIGH.
2.23 ! kahan 6: ** @(#) $Id: HTMIMImp.c,v 1.3 1998/12/15 12:50:21 cvs Exp $
2.1 frystyk 7: **
8: ** This module contains the default MIME header parsers for the MIME
9: ** parser in HTMIME.c. They are all initialized at run time and can hence
10: ** be replaced or extended with your own set.
11: **
12: ** History:
13: ** Jun 96 HFN Written
2.23 ! kahan 14: ** Dec 98 JKO Added support for message-digest authentication
2.1 frystyk 15: */
16:
17: /* Library include files */
2.21 frystyk 18: #include "wwwsys.h"
2.1 frystyk 19: #include "WWWUtil.h"
20: #include "WWWCore.h"
21: #include "HTHeader.h"
2.10 frystyk 22: #include "HTTPUtil.h"
2.1 frystyk 23: #include "HTMIMImp.h" /* Implemented here */
24:
25: /* ------------------------------------------------------------------------- */
26:
2.8 frystyk 27: PUBLIC int HTMIME_accept (HTRequest * request, HTResponse * response,
28: char * token, char * value)
2.1 frystyk 29: {
30:
31: return HT_OK;
32: }
33:
2.8 frystyk 34: PUBLIC int HTMIME_acceptCharset (HTRequest * request, HTResponse * response,
35: char * token, char * value)
2.1 frystyk 36: {
37:
38: return HT_OK;
39: }
40:
2.8 frystyk 41: PUBLIC int HTMIME_acceptEncoding (HTRequest * request, HTResponse * response,
42: char * token, char * value)
2.1 frystyk 43: {
44:
45: return HT_OK;
46: }
47:
2.8 frystyk 48: PUBLIC int HTMIME_acceptLanguage (HTRequest * request, HTResponse * response,
49: char * token, char * value)
2.1 frystyk 50: {
51:
52: return HT_OK;
53: }
54:
2.8 frystyk 55: PUBLIC int HTMIME_acceptRanges (HTRequest * request, HTResponse * response,
56: char * token, char * value)
2.1 frystyk 57: {
2.8 frystyk 58: if (value) {
59: HTNet * net = HTRequest_net(request);
60: HTHost * host = HTNet_host(net);
61: HTHost_setRangeUnits(host, value);
2.1 frystyk 62: }
63: return HT_OK;
64: }
65:
2.8 frystyk 66: PUBLIC int HTMIME_authenticate (HTRequest * request, HTResponse * response,
67: char * token, char * value)
2.3 frystyk 68: {
69: char * scheme = HTNextField(&value);
2.4 frystyk 70: if (scheme) {
2.8 frystyk 71: HTResponse_addChallenge(response, scheme, value);
72: HTResponse_setScheme(response, scheme);
2.4 frystyk 73: }
2.3 frystyk 74: return HT_OK;
75: }
76:
2.23 ! kahan 77: /* @@@ WARNING: The following function hasn't been thoroughly tested yet */
! 78: PUBLIC int HTMIME_authenticationInfo (HTRequest * request,
! 79: HTResponse * response,
! 80: char * token, char * value)
! 81: {
! 82: /* deal here with the next nonce, the qop, and the digest response (mutual
! 83: authentication */
! 84: if (value) {
! 85: if (PROT_TRACE)
! 86: HTTrace("Protocol.... Authentication-Info: `%s\', value: `%s\'\n",
! 87: value);
! 88: HTDigest_refresh (request, response, FALSE, value);
! 89: }
! 90: return HT_OK;
! 91: }
! 92:
2.8 frystyk 93: PUBLIC int HTMIME_authorization (HTRequest * request, HTResponse * response,
94: char * token, char * value)
2.1 frystyk 95: {
96:
97: return HT_OK;
98: }
99:
2.8 frystyk 100: PUBLIC int HTMIME_cacheControl (HTRequest * request, HTResponse * response,
101: char * token, char * value)
2.1 frystyk 102: {
2.7 frystyk 103: /*
104: ** Walk through the set of cache-control directives and add them to the
105: ** response association list for cache control directives
106: */
107: char * name_val;
108: while ((name_val = HTNextPair(&value)) != NULL) {
109: char * name = HTNextField(&name_val);
110: char * val = HTNextField(&name_val);
2.8 frystyk 111: if (name) HTResponse_addCacheControl(response, name, val ? val : "");
2.7 frystyk 112: }
2.1 frystyk 113: return HT_OK;
114: }
115:
2.8 frystyk 116: PUBLIC int HTMIME_connection (HTRequest * request, HTResponse * response,
117: char * token, char * value)
2.1 frystyk 118: {
2.7 frystyk 119: /*
120: ** Walk through the set of connection directives and add them to the
121: ** response association list for connection directives
122: */
123: char * name_val;
124: while ((name_val = HTNextPair(&value)) != NULL) {
125: char * name = HTNextField(&name_val);
126: char * val = HTNextField(&name_val);
127:
128: /*
129: ** If we have a name then look if it is concerning persistent
130: ** connections. If so, then we handle it here, otherwise we leave it
131: ** to somebody else by simply adding it to the list of connection
132: ** tokens.
133: */
134: if (name) {
2.15 frystyk 135: HTNet * net = HTRequest_net(request);
136: HTHost * host = HTNet_host(net);
2.7 frystyk 137: if (!strcasecomp(name, "close")) { /* HTTP/1.1 */
2.11 frystyk 138: if (STREAM_TRACE) HTTrace("MIMEParser.. Close received...\n");
2.15 frystyk 139: HTHost_setCloseNotification(host, YES);
2.7 frystyk 140: } else if (!strcasecomp(name, "keep-alive")) { /* HTTP/1.0 */
2.10 frystyk 141:
142: /*
143: ** In case this is an HTTP/1.1 server sending keep-alive then
144: ** ignore it.
145: */
146: if (HTHost_version(host) < HTTP_11) {
147: HTNet_setPersistent(net, YES, HT_TP_SINGLE);
148: if (STREAM_TRACE) HTTrace("MIMEParser.. HTTP/1.0 Keep Alive\n");
149: } else
150: if (STREAM_TRACE) HTTrace("MIMEParser.. HTTP/1.0 Keep Alive ignored\n");
2.7 frystyk 151: } else
2.8 frystyk 152: HTResponse_addConnection(response, name, val ? val : "");
2.1 frystyk 153: }
154: }
155: return HT_OK;
156: }
157:
2.8 frystyk 158: PUBLIC int HTMIME_contentEncoding (HTRequest * request, HTResponse * response,
159: char * token, char * value)
2.1 frystyk 160: {
161: char * field;
162: while ((field = HTNextField(&value)) != NULL) {
163: char * lc = field;
164: while ((*lc = TOLOWER(*lc))) lc++;
2.8 frystyk 165: HTResponse_addEncoding(response, HTAtom_for(field));
2.1 frystyk 166: }
167: return HT_OK;
168: }
169:
2.8 frystyk 170: PUBLIC int HTMIME_contentLength (HTRequest * request, HTResponse * response,
171: char * token, char * value)
2.1 frystyk 172: {
173: char * field;
174: if ((field = HTNextField(&value)) != NULL)
2.8 frystyk 175: HTResponse_setLength(response, atol(field));
2.1 frystyk 176: return HT_OK;
177: }
178:
2.8 frystyk 179: PUBLIC int HTMIME_contentRange (HTRequest * request, HTResponse * response,
180: char * token, char * value)
2.1 frystyk 181: {
2.2 frystyk 182: char * field;
2.8 frystyk 183: if ((field = HTNextField(&value)))
184: HTResponse_addRange(response, field, value);
2.1 frystyk 185: return HT_OK;
186: }
187:
2.8 frystyk 188: PUBLIC int HTMIME_contentTransferEncoding (HTRequest * request, HTResponse * response,
189: char * token, char * value)
2.1 frystyk 190: {
191: char * field;
192: if ((field = HTNextField(&value)) != NULL) {
193: char *lc = field;
194: while ((*lc = TOLOWER(*lc))) lc++;
2.20 frystyk 195: HTResponse_setContentTransferEncoding(response, HTAtom_for(field));
2.1 frystyk 196: }
197: return HT_OK;
198: }
199:
2.8 frystyk 200: PUBLIC int HTMIME_contentType (HTRequest * request, HTResponse * response,
201: char * token, char * value)
2.1 frystyk 202: {
203: char * field;
204: if ((field = HTNextField(&value)) != NULL) {
2.2 frystyk 205:
206: /* Get the Content-Type */
2.1 frystyk 207: char *lc = field;
208: while ((*lc = TOLOWER(*lc))) lc++;
2.8 frystyk 209: HTResponse_setFormat(response, HTAtom_for(field));
2.2 frystyk 210:
211: /* Get all the parameters to the Content-Type */
212: {
213: char * param;
214: while ((field = HTNextField(&value)) != NULL &&
215: (param = HTNextField(&value)) != NULL) {
216: lc = field;
217: while ((*lc = TOLOWER(*lc))) lc++;
218: lc = param;
219: while ((*lc = TOLOWER(*lc))) lc++;
2.8 frystyk 220: HTResponse_addFormatParam(response, field, param);
2.1 frystyk 221: }
222: }
2.12 eric 223: }
224: return HT_OK;
225: }
226:
2.19 frystyk 227: #if 0
2.17 frystyk 228: PRIVATE int HTFindInt(char * haystack, char * needle, int deflt)
2.12 eric 229: {
230: char * start = strstr(haystack, needle);
231: int value = deflt;
232: if (start != NULL) {
233: start += strlen(needle);
234: while isspace(*start) start++;
235: if (isdigit(*start)) {
236: char * end = start + 1;
237: char save;
238: while (isdigit(*end)) end++;
239: save = *end;
240: *end = 0;
241: value = atoi(start);
242: *end = save;
243: }
244: }
245: return value;
246: }
2.19 frystyk 247: #endif
2.12 eric 248:
249: PUBLIC int HTMIME_keepAlive (HTRequest * request, HTResponse * response,
250: char * token, char * value)
251: {
2.17 frystyk 252: char * name_val;
253: HTNet * net = HTRequest_net(request);
254: HTHost * host = HTNet_host(net);
255: while ((name_val = HTNextPair(&value)) != NULL) {
256: char * name = HTNextField(&name_val);
257: char * val = HTNextField(&name_val);
258: if (!strcasecomp(name, "max") && val) {
259: int max = atoi(val);
260: if (STREAM_TRACE) HTTrace("MIMEParser.. Max %d requests pr connection\n", max);
261: HTHost_setReqsPerConnection(host, max);
262: } else if (!strcasecomp(name, "timeout") && val) {
263: int timeout = atoi(val);
264: if (STREAM_TRACE) HTTrace("MIMEParser.. Timeout after %d secs\n", timeout);
265: }
2.1 frystyk 266: }
267: return HT_OK;
268: }
269:
2.8 frystyk 270: PUBLIC int HTMIME_link (HTRequest * request, HTResponse * response,
271: char * token, char * value)
2.1 frystyk 272: {
273:
274: return HT_OK;
275: }
276:
2.8 frystyk 277: PUBLIC int HTMIME_location (HTRequest * request, HTResponse * response,
278: char * token, char * value)
2.1 frystyk 279: {
2.18 frystyk 280: HTAnchor * redirection = NULL;
281: char * location = HTStrip(value);
282:
283: /*
284: ** If not absolute URI (Error) then find the base
285: */
286: if (!HTURL_isAbsolute(location)) {
287: char * base = HTAnchor_address((HTAnchor *) HTRequest_anchor(request));
288: location = HTParse(location, base, PARSE_ALL);
289: redirection = HTAnchor_findAddress(location);
290: HT_FREE(base);
291: HT_FREE(location);
292: } else {
293: redirection = HTAnchor_findAddress(location);
294: }
2.8 frystyk 295: HTResponse_setRedirection(response, redirection);
2.1 frystyk 296: return HT_OK;
297: }
298:
2.8 frystyk 299: PUBLIC int HTMIME_maxForwards (HTRequest * request, HTResponse * response,
300: char * token, char * value)
2.1 frystyk 301: {
302:
2.6 frystyk 303: return HT_OK;
304: }
305:
2.8 frystyk 306: PUBLIC int HTMIME_messageDigest (HTRequest * request, HTResponse * response,
307: char * token, char * value)
2.1 frystyk 308: {
2.8 frystyk 309: HTResponse_addChallenge(response, "Digest-MessageDigest", value);
2.1 frystyk 310: return HT_OK;
311: }
312:
2.8 frystyk 313: PUBLIC int HTMIME_pragma (HTRequest * request, HTResponse * response,
314: char * token, char * value)
2.1 frystyk 315: {
2.8 frystyk 316: /*
317: ** Walk through the set of pragma directives and search for one that may
318: ** affect the cachability of this object
2.2 frystyk 319: */
2.8 frystyk 320: char * name_val;
321: while ((name_val = HTNextPair(&value)) != NULL) {
322: char * name = HTNextField(&name_val);
323: if (name) {
324: if (!strcasecomp(name, "no-cache")) {
2.22 frystyk 325: HTResponse_setCachable(response, HT_NO_CACHE);
2.8 frystyk 326: if (STREAM_TRACE) HTTrace("MIMEParser.. No-Cache Pragma\n");
327: }
328: }
329: }
2.1 frystyk 330: return HT_OK;
331: }
332:
2.8 frystyk 333: PUBLIC int HTMIME_protocol (HTRequest * request, HTResponse * response,
334: char * token, char * value)
2.1 frystyk 335: {
2.8 frystyk 336: char * param = NULL;
337: char * protocol = HTNextSExp(&value, ¶m);
338: if (protocol) {
339: if (PROT_TRACE)
340: HTTrace("Protocol.... Name: `%s\', value: `%s\'\n",
341: protocol, param);
342: HTResponse_addProtocol(response, protocol, param);
343: }
2.6 frystyk 344: return HT_OK;
345: }
346:
2.8 frystyk 347: PUBLIC int HTMIME_protocolInfo (HTRequest * request, HTResponse * response,
348: char * token, char * value)
2.6 frystyk 349: {
2.8 frystyk 350: char * param = NULL;
351: char * info = HTNextSExp(&value, ¶m);
352: if (info) {
353: if (PROT_TRACE)
354: HTTrace("Protocol.... Info: `%s\', value: `%s\'\n",
355: info, param);
356: HTResponse_addProtocolInfo(response, info, param);
357: }
2.1 frystyk 358: return HT_OK;
359: }
360:
2.8 frystyk 361: PUBLIC int HTMIME_protocolRequest (HTRequest * request, HTResponse * response,
362: char * token, char * value)
2.1 frystyk 363: {
2.8 frystyk 364: char * param = NULL;
365: char * preq = HTNextSExp(&value, ¶m);
366: if (preq) {
367: if (PROT_TRACE)
368: HTTrace("Protocol.... Request: `%s\', value: `%s\'\n",
369: preq, param);
370: HTResponse_addProtocolRequest(response, preq, param);
2.7 frystyk 371: }
2.1 frystyk 372: return HT_OK;
373: }
374:
2.8 frystyk 375: PUBLIC int HTMIME_proxyAuthorization (HTRequest * request, HTResponse * response,
376: char * token, char * value)
2.1 frystyk 377: {
378:
379: return HT_OK;
2.23 ! kahan 380: }
! 381:
! 382:
! 383: /* @@@ WARNING: The following function hasn't been thoroughly tested yet */
! 384: PUBLIC int HTMIME_proxyAuthenticationInfo (HTRequest * request,
! 385: HTResponse * response,
! 386: char * token, char * value)
! 387: {
! 388: /* deal here with the next nonce, the qop, and the digest response (mutual
! 389: authentication */
! 390: if (value) {
! 391: if (PROT_TRACE)
! 392: HTTrace("Protocol.... Proxy-Authentication-Info: `%s\', value: `%s\'\n",
! 393: value);
! 394: HTDigest_refresh (request, response, TRUE, value);
! 395: }
! 396: return HT_OK;
2.1 frystyk 397: }
398:
2.8 frystyk 399: PUBLIC int HTMIME_public (HTRequest * request, HTResponse * response,
400: char * token, char * value)
2.1 frystyk 401: {
2.2 frystyk 402: char * field;
403: HTNet * net = HTRequest_net(request);
404: HTHost * host = HTNet_host(net);
405: while ((field = HTNextField(&value)) != NULL) {
406: HTMethod new_method;
407: /* We treat them as case-insensitive! */
408: if ((new_method = HTMethod_enum(field)) != METHOD_INVALID)
409: HTHost_appendPublicMethods(host, new_method);
410: }
411: if (STREAM_TRACE)
412: HTTrace("MIMEParser.. Public methods: %d\n",
413: HTHost_publicMethods(host));
2.1 frystyk 414: return HT_OK;
415: }
416:
2.8 frystyk 417: PUBLIC int HTMIME_range (HTRequest * request, HTResponse * response,
418: char * token, char * value)
2.1 frystyk 419: {
420:
421: return HT_OK;
422: }
423:
2.8 frystyk 424: PUBLIC int HTMIME_referer (HTRequest * request, HTResponse * response,
425: char * token, char * value)
2.1 frystyk 426: {
427:
428: return HT_OK;
429: }
430:
2.8 frystyk 431: PUBLIC int HTMIME_retryAfter (HTRequest * request, HTResponse * response,
432: char * token, char * value)
2.1 frystyk 433: {
2.8 frystyk 434: HTUserProfile * up = HTRequest_userProfile(request);
435: HTResponse_setRetryTime(response, HTParseTime(value, up, YES));
2.1 frystyk 436: return HT_OK;
437: }
438:
2.8 frystyk 439: PUBLIC int HTMIME_server (HTRequest * request, HTResponse * response,
440: char * token, char * value)
2.2 frystyk 441: {
442: char * field;
443: HTNet * net = HTRequest_net(request);
444: HTHost * host = HTNet_host(net);
445: if ((field = HTNextField(&value)) != NULL)
446: HTHost_setServer(host, field);
2.16 frystyk 447: return HT_OK;
448: }
2.20 frystyk 449:
450: PUBLIC int HTMIME_transferEncoding (HTRequest * request, HTResponse * response,
451: char * token, char * value)
452: {
453: char * field;
454: while ((field = HTNextField(&value)) != NULL) {
455: char * lc = field;
456: while ((*lc = TOLOWER(*lc))) lc++;
457: HTResponse_addTransfer(response, HTAtom_for(field));
458: }
459: return HT_OK;
460: }
461:
2.16 frystyk 462:
463: PUBLIC int HTMIME_trailer (HTRequest * request, HTResponse * response,
464: char * token, char * value)
465: {
466: /*
467: ** Walk through the set of trailer directives and add them to the
468: ** response association list for trailer directives
469: */
470: char * name_val;
471: while ((name_val = HTNextPair(&value)) != NULL) {
472: char * name = HTNextField(&name_val);
473: char * val = HTNextField(&name_val);
474: if (name) HTResponse_addTrailer(response, name, val ? val : "");
475: }
2.2 frystyk 476: return HT_OK;
477: }
478:
2.8 frystyk 479: PUBLIC int HTMIME_upgrade (HTRequest * request, HTResponse * response,
480: char * token, char * value)
2.1 frystyk 481: {
482:
483: return HT_OK;
484: }
485:
2.8 frystyk 486: PUBLIC int HTMIME_userAgent (HTRequest * request, HTResponse * response,
487: char * token, char * value)
2.1 frystyk 488: {
2.2 frystyk 489: char * field;
490: HTNet * net = HTRequest_net(request);
491: HTHost * host = HTNet_host(net);
492: if ((field = HTNextField(&value)) != NULL)
493: HTHost_setUserAgent(host, field);
2.1 frystyk 494: return HT_OK;
495: }
496:
2.8 frystyk 497: PUBLIC int HTMIME_vary (HTRequest * request, HTResponse * response,
498: char * token, char * value)
2.1 frystyk 499: {
2.19 frystyk 500: /*
501: ** Walk through the set of vary directives and add them to the
502: ** response association list for vary directives
503: */
504: char * name_val;
505: while ((name_val = HTNextPair(&value)) != NULL) {
506: char * name = HTNextField(&name_val);
507: char * val = HTNextField(&name_val);
508: if (name) HTResponse_addVariant(response, name, val ? val : "");
509: }
2.1 frystyk 510: return HT_OK;
511: }
512:
2.8 frystyk 513: PUBLIC int HTMIME_via (HTRequest * request, HTResponse * response,
514: char * token, char * value)
2.1 frystyk 515: {
516:
517: return HT_OK;
518: }
519:
2.8 frystyk 520: PUBLIC int HTMIME_warning (HTRequest * request, HTResponse * response,
521: char * token, char * value)
2.1 frystyk 522: {
2.2 frystyk 523: char * codestr = HTNextField(&value);
524: char * agent = HTNextField(&value);
525: if (codestr && agent) {
526: int code = atoi(codestr);
527: int idx;
528: char * ptr;
529: if (code==10) idx=HTERR_STALE; else
530: if (code==11) idx=HTERR_REVALIDATION_FAILED; else
531: if (code==12) idx=HTERR_DISCONNECTED_CACHE; else
532: if (code==13) idx=HTERR_HEURISTIC_EXPIRATION; else
533: if (code==14) idx=HTERR_TRANSFORMED; else
534: idx=HTERR_CACHE;
535: if ((ptr = strchr(agent, '\r')) != NULL) /* Strip \r and \n */
536: *ptr = '\0';
537: else if ((ptr = strchr(agent, '\n')) != NULL)
538: *ptr = '\0';
539: HTRequest_addError(request, ERR_WARN, NO, idx, agent,
540: (int) strlen(agent), "HTMIME_warning");
541: } else {
542: if (STREAM_TRACE) HTTrace("MIMEParser.. Invalid warning\n");
543: }
2.1 frystyk 544: return HT_OK;
545: }
Webmaster