Annotation of libwww/Library/src/HTTPGen.c, revision 2.8
2.1 frystyk 1: /* HTTPGen.c
2: ** HTTP GENERAL HEADER GENERATION
3: **
2.5 frystyk 4: ** (c) COPYRIGHT MIT 1995.
5: ** Please first read the full copyright statement in the file COPYRIGH.
2.8 ! frystyk 6: ** @(#) $Id: HTTPGen.c,v 2.7 1996/07/08 19:11:06 frystyk Exp $
2.5 frystyk 7: **
2.1 frystyk 8: ** This module implements the output stream for General HTTP headers
9: **
10: ** History:
11: ** Jan 96 HFN Written
12: */
13:
14: /* Library Includes */
2.4 frystyk 15: #include "sysdep.h"
2.8 ! frystyk 16: #include "WWWUtil.h"
! 17: #include "WWWCore.h"
! 18: #include "WWWMIME.h"
! 19: #include "WWWTrans.h"
2.1 frystyk 20: #include "HTTPReq.h" /* Implements */
21:
22: #define MIME_VERSION "MIME/1.0"
2.8 ! frystyk 23:
! 24: #define PUTC(c) (*me->target->isa->put_character)(me->target, c)
! 25: #define PUTS(s) (*me->target->isa->put_string)(me->target, s)
2.1 frystyk 26: #define PUTBLOCK(b, l) (*me->target->isa->put_block)(me->target, b, l)
27:
28: struct _HTStream {
2.4 frystyk 29: const HTStreamClass * isa;
2.1 frystyk 30: HTStream * target;
31: HTRequest * request;
32: BOOL endHeader;
33: BOOL transparent;
34: };
35:
36: /* ------------------------------------------------------------------------- */
37: /* HTTP General Header Stream */
38: /* ------------------------------------------------------------------------- */
39:
40: /* HTTPGenMake
41: ** ------------
42: ** Makes a MIME/1.0 request header.
43: */
44: PRIVATE int HTTPGenMake (HTStream * me, HTRequest * request)
45: {
2.8 ! frystyk 46: char linebuf[256]; /* @@@ */
! 47: char crlf[3];
! 48: HTGnHd gen_mask = HTRequest_gnHd(request);
! 49: *crlf = CR; *(crlf+1) = LF; *(crlf+2) = '\0';
! 50: if (gen_mask & HT_G_CC) { /* Cache control */
! 51: HTAssocList * cur = HTRequest_cacheControl(request);
! 52: if (cur) {
! 53: BOOL first=YES;
! 54: HTAssoc * pres;
! 55: while ((pres = (HTAssoc *) HTAssocList_nextObject(cur))) {
! 56: char * value = HTAssoc_value(pres);
! 57: if (first) {
! 58: PUTS("Cache-Control: ");
! 59: first = NO;
! 60: } else
! 61: PUTC(',');
! 62:
! 63: /* Output the name */
! 64: PUTS(HTAssoc_name(pres));
! 65:
! 66: /* Only output the value if not empty string */
! 67: if (*value) {
! 68: PUTS("=");
! 69: PUTS(value);
! 70: }
! 71: }
! 72: PUTBLOCK(crlf, 2);
! 73: }
! 74: }
! 75: if (gen_mask & HT_G_CONNECTION) {
! 76: HTAssocList * cur = HTRequest_cacheControl(request);
! 77: if (cur) {
! 78: BOOL first=YES;
! 79: HTAssoc * pres;
! 80: while ((pres = (HTAssoc *) HTAssocList_nextObject(cur))) {
! 81: char * value = HTAssoc_value(pres);
! 82: if (first) {
! 83: PUTS("Connection: ");
! 84: first = NO;
! 85: } else
! 86: PUTC(',');
! 87:
! 88: /* Output the name */
! 89: PUTS(HTAssoc_name(pres));
! 90:
! 91: /* Only output the value if not empty string */
! 92: if (*value) {
! 93: PUTS("=");
! 94: PUTS(value);
! 95: }
! 96: }
! 97: PUTBLOCK(crlf, 2);
! 98: }
! 99: }
! 100: if (gen_mask & HT_G_DATE) {
2.1 frystyk 101: time_t local = time(NULL);
102: sprintf(linebuf, "Date: %s%c%c", HTDateTimeStr(&local, NO), CR,LF);
103: PUTBLOCK(linebuf, (int) strlen(linebuf));
104: }
2.8 ! frystyk 105: if (gen_mask & HT_G_FORWARDED) {
2.1 frystyk 106: /* @@@@@@ */
107: }
2.8 ! frystyk 108: if (gen_mask & HT_G_PRAGMA_NO_CACHE) {
! 109: sprintf(linebuf, "Pragma: %s%c%c", "no-cache", CR, LF);
! 110: PUTBLOCK(linebuf, (int) strlen(linebuf));
! 111: }
! 112: if (gen_mask & HT_G_MESSAGE_ID) {
2.6 frystyk 113: const char *msgid = HTMessageIdStr(HTRequest_userProfile(request));
2.1 frystyk 114: if (msgid) {
115: sprintf(linebuf, "Message-ID: %s%c%c", msgid, CR, LF);
116: PUTBLOCK(linebuf, (int) strlen(linebuf));
117: }
118: }
2.8 ! frystyk 119: if (gen_mask & HT_G_MIME) {
2.1 frystyk 120: sprintf(linebuf, "MIME-Version: %s%c%c", MIME_VERSION, CR, LF);
121: PUTBLOCK(linebuf, (int) strlen(linebuf));
122: }
123:
124: /* Put out extra information if any */
125: {
126: HTList * list;
127: BOOL override;
128: if ((list = HTRequest_generator(request, &override))) {
129: HTList *local = list;
130: HTPostCallback *pres;
2.3 eric 131: if (STREAM_TRACE) HTTrace("HTTPGen..... Extra local\n");
2.1 frystyk 132: while ((pres = (HTPostCallback *) HTList_nextObject(local)))
133: (*pres)(request, me->target);
134: } else if (!override && (list = HTHeader_generator())) {
135: HTList *global = list;
136: HTPostCallback *pres;
2.3 eric 137: if (STREAM_TRACE) HTTrace("HTTPGen..... Extra global\n");
2.1 frystyk 138: while ((pres = (HTPostCallback *) HTList_nextObject(global)))
139: (*pres)(request, me->target);
140: }
141: }
142: if (me->endHeader) {
143: sprintf(linebuf, "%c%c", CR, LF); /* Blank line means "end" */
144: PUTBLOCK(linebuf, (int) strlen(linebuf));
145: }
2.3 eric 146: if (PROT_TRACE)HTTrace("HTTP........ Generating General Headers\n");
2.1 frystyk 147: return HT_OK;
148: }
149:
2.4 frystyk 150: PRIVATE int HTTPGen_put_block (HTStream * me, const char * b, int l)
2.1 frystyk 151: {
152: if (me->transparent)
153: return b ? PUTBLOCK(b, l) : HT_OK;
154: else {
155: HTTPGenMake(me, me->request);
156: me->transparent = YES;
157: return b ? PUTBLOCK(b, l) : HT_OK;
158: }
159: }
160:
161: PRIVATE int HTTPGen_put_character (HTStream * me, char c)
162: {
163: return HTTPGen_put_block(me, &c, 1);
164: }
165:
2.4 frystyk 166: PRIVATE int HTTPGen_put_string (HTStream * me, const char * s)
2.1 frystyk 167: {
168: return HTTPGen_put_block(me, s, strlen(s));
169: }
170:
171: /*
172: ** Flushes header but doesn't free stream object
173: */
174: PRIVATE int HTTPGen_flush (HTStream * me)
175: {
176: int status = HTTPGen_put_block(me, NULL, 0);
177: return status==HT_OK ? (*me->target->isa->flush)(me->target) : status;
178: }
179:
180: /*
181: ** Flushes data and frees stream object
182: */
183: PRIVATE int HTTPGen_free (HTStream * me)
184: {
185: int status = HTTPGen_flush(me);
186: if (status != HT_WOULD_BLOCK) {
187: if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)
188: return HT_WOULD_BLOCK;
2.2 frystyk 189: HT_FREE(me);
2.1 frystyk 190: }
191: return status;
192: }
193:
194: PRIVATE int HTTPGen_abort (HTStream * me, HTList * e)
195: {
196: if (me->target) (*me->target->isa->abort)(me->target, e);
2.2 frystyk 197: HT_FREE(me);
2.3 eric 198: if (PROT_TRACE) HTTrace("HTTPGen..... ABORTING...\n");
2.1 frystyk 199: return HT_ERROR;
200: }
201:
202: /* HTTPGen Stream
203: ** -----------------
204: */
2.4 frystyk 205: PRIVATE const HTStreamClass HTTPGenClass =
2.1 frystyk 206: {
207: "HTTPGen",
208: HTTPGen_flush,
209: HTTPGen_free,
210: HTTPGen_abort,
211: HTTPGen_put_character,
212: HTTPGen_put_string,
213: HTTPGen_put_block
214: };
215:
216: PUBLIC HTStream * HTTPGen_new (HTRequest * request, HTStream * target,
217: BOOL endHeader)
218: {
2.2 frystyk 219: HTStream * me;
220: if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
221: HT_OUTOFMEM("HTTPGen_new");
2.1 frystyk 222: me->isa = &HTTPGenClass;
223: me->target = target;
224: me->request = request;
225: me->endHeader = endHeader;
226: me->transparent = NO;
227: return me;
228: }
Webmaster