Annotation of libwww/Library/src/HTTPGen.c, revision 2.6
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.6 ! frystyk 6: ** @(#) $Id: HTTPGen.c,v 2.5 1996/04/12 17:49:10 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.1 frystyk 16: #include "HTUtils.h"
17: #include "HTString.h"
18: #include "HTWWWStr.h"
19: #include "HTParse.h"
20: #include "HTFormat.h"
21: #include "HTAncMan.h"
22: #include "HTNetMan.h"
23: #include "HTTCP.h"
24: #include "HTHeader.h"
25: #include "HTReqMan.h"
26: #include "HTTPReq.h" /* Implements */
27:
28: #define MIME_VERSION "MIME/1.0"
29: #define PUTBLOCK(b, l) (*me->target->isa->put_block)(me->target, b, l)
30:
31: struct _HTStream {
2.4 frystyk 32: const HTStreamClass * isa;
2.1 frystyk 33: HTStream * target;
34: HTRequest * request;
35: BOOL endHeader;
36: BOOL transparent;
37: };
38:
39: /* ------------------------------------------------------------------------- */
40: /* HTTP General Header Stream */
41: /* ------------------------------------------------------------------------- */
42:
43: /* HTTPGenMake
44: ** ------------
45: ** Makes a MIME/1.0 request header.
46: */
47: PRIVATE int HTTPGenMake (HTStream * me, HTRequest * request)
48: {
49: char linebuf[256];
50: if (request->GenMask & HT_G_DATE) {
51: time_t local = time(NULL);
52: sprintf(linebuf, "Date: %s%c%c", HTDateTimeStr(&local, NO), CR,LF);
53: PUTBLOCK(linebuf, (int) strlen(linebuf));
54: }
55: if (request->GenMask & HT_G_FORWARDED) {
56: /* @@@@@@ */
57: }
58: if (request->GenMask & HT_G_MESSAGE_ID) {
2.6 ! frystyk 59: const char *msgid = HTMessageIdStr(HTRequest_userProfile(request));
2.1 frystyk 60: if (msgid) {
61: sprintf(linebuf, "Message-ID: %s%c%c", msgid, CR, LF);
62: PUTBLOCK(linebuf, (int) strlen(linebuf));
63: }
64: }
65: if (request->GenMask & HT_G_MIME) {
66: sprintf(linebuf, "MIME-Version: %s%c%c", MIME_VERSION, CR, LF);
67: PUTBLOCK(linebuf, (int) strlen(linebuf));
68: }
69: if (request->GenMask & HT_G_CONNECTION) {
70: sprintf(linebuf, "Connection: Keep-Alive%c%c", CR, LF);
71: PUTBLOCK(linebuf, (int) strlen(linebuf));
72: }
73: if (request->RequestMask & HT_G_NO_CACHE) {
74: sprintf(linebuf, "Pragma: %s%c%c", "no-cache", CR, LF);
75: PUTBLOCK(linebuf, (int) strlen(linebuf));
76: }
77:
78: /* Put out extra information if any */
79: {
80: HTList * list;
81: BOOL override;
82: if ((list = HTRequest_generator(request, &override))) {
83: HTList *local = list;
84: HTPostCallback *pres;
2.3 eric 85: if (STREAM_TRACE) HTTrace("HTTPGen..... Extra local\n");
2.1 frystyk 86: while ((pres = (HTPostCallback *) HTList_nextObject(local)))
87: (*pres)(request, me->target);
88: } else if (!override && (list = HTHeader_generator())) {
89: HTList *global = list;
90: HTPostCallback *pres;
2.3 eric 91: if (STREAM_TRACE) HTTrace("HTTPGen..... Extra global\n");
2.1 frystyk 92: while ((pres = (HTPostCallback *) HTList_nextObject(global)))
93: (*pres)(request, me->target);
94: }
95: }
96: if (me->endHeader) {
97: sprintf(linebuf, "%c%c", CR, LF); /* Blank line means "end" */
98: PUTBLOCK(linebuf, (int) strlen(linebuf));
99: }
2.3 eric 100: if (PROT_TRACE)HTTrace("HTTP........ Generating General Headers\n");
2.1 frystyk 101: return HT_OK;
102: }
103:
2.4 frystyk 104: PRIVATE int HTTPGen_put_block (HTStream * me, const char * b, int l)
2.1 frystyk 105: {
106: if (me->transparent)
107: return b ? PUTBLOCK(b, l) : HT_OK;
108: else {
109: HTTPGenMake(me, me->request);
110: me->transparent = YES;
111: return b ? PUTBLOCK(b, l) : HT_OK;
112: }
113: }
114:
115: PRIVATE int HTTPGen_put_character (HTStream * me, char c)
116: {
117: return HTTPGen_put_block(me, &c, 1);
118: }
119:
2.4 frystyk 120: PRIVATE int HTTPGen_put_string (HTStream * me, const char * s)
2.1 frystyk 121: {
122: return HTTPGen_put_block(me, s, strlen(s));
123: }
124:
125: /*
126: ** Flushes header but doesn't free stream object
127: */
128: PRIVATE int HTTPGen_flush (HTStream * me)
129: {
130: int status = HTTPGen_put_block(me, NULL, 0);
131: return status==HT_OK ? (*me->target->isa->flush)(me->target) : status;
132: }
133:
134: /*
135: ** Flushes data and frees stream object
136: */
137: PRIVATE int HTTPGen_free (HTStream * me)
138: {
139: int status = HTTPGen_flush(me);
140: if (status != HT_WOULD_BLOCK) {
141: if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)
142: return HT_WOULD_BLOCK;
2.2 frystyk 143: HT_FREE(me);
2.1 frystyk 144: }
145: return status;
146: }
147:
148: PRIVATE int HTTPGen_abort (HTStream * me, HTList * e)
149: {
150: if (me->target) (*me->target->isa->abort)(me->target, e);
2.2 frystyk 151: HT_FREE(me);
2.3 eric 152: if (PROT_TRACE) HTTrace("HTTPGen..... ABORTING...\n");
2.1 frystyk 153: return HT_ERROR;
154: }
155:
156: /* HTTPGen Stream
157: ** -----------------
158: */
2.4 frystyk 159: PRIVATE const HTStreamClass HTTPGenClass =
2.1 frystyk 160: {
161: "HTTPGen",
162: HTTPGen_flush,
163: HTTPGen_free,
164: HTTPGen_abort,
165: HTTPGen_put_character,
166: HTTPGen_put_string,
167: HTTPGen_put_block
168: };
169:
170: PUBLIC HTStream * HTTPGen_new (HTRequest * request, HTStream * target,
171: BOOL endHeader)
172: {
2.2 frystyk 173: HTStream * me;
174: if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
175: HT_OUTOFMEM("HTTPGen_new");
2.1 frystyk 176: me->isa = &HTTPGenClass;
177: me->target = target;
178: me->request = request;
179: me->endHeader = endHeader;
180: me->transparent = NO;
181: return me;
182: }
Webmaster