Annotation of libwww/Library/src/HTMIMERq.c, revision 2.11
2.1 frystyk 1: /* HTMIMERq.c
2.10 frystyk 2: ** MIME ENTITY HEADERS GENERATION
2.1 frystyk 3: **
4: ** This module implements the output stream for MIME used for sending
2.10 frystyk 5: ** requests with a entity body to HTTP, NEWS, etc. or for generating
6: ** responses
2.1 frystyk 7: **
8: ** History:
9: ** Jan 95 HFN Written
10: */
11:
12: /* Library Includes */
13: #include "tcp.h"
14: #include "HTUtils.h"
15: #include "HTString.h"
2.5 frystyk 16: #include "HTWWWStr.h"
2.1 frystyk 17: #include "HTParse.h"
18: #include "HTFormat.h"
2.7 frystyk 19: #include "HTAncMan.h"
2.1 frystyk 20: #include "HTNetMan.h"
21: #include "HTDNS.h"
22: #include "HTTCP.h"
23: #include "HTWriter.h"
2.2 frystyk 24: #include "HTHeader.h"
2.1 frystyk 25: #include "HTReqMan.h"
26: #include "HTTPReq.h" /* Implements */
27:
28: #define PUTBLOCK(b, l) (*me->target->isa->put_block)(me->target, b, l)
29:
30: struct _HTStream {
31: CONST HTStreamClass * isa;
32: HTStream * target;
33: HTRequest * request;
2.10 frystyk 34: BOOL endHeader;
2.1 frystyk 35: BOOL transparent;
36: };
37:
38: /* ------------------------------------------------------------------------- */
39: /* MIME Output Request Stream */
40: /* ------------------------------------------------------------------------- */
41:
42: /* MIMEMakeRequest
43: ** ---------------
2.10 frystyk 44: ** Generates the BODY parts of a MIME message.
2.1 frystyk 45: */
2.2 frystyk 46: PRIVATE int MIMEMakeRequest (HTStream * me, HTRequest * request)
2.1 frystyk 47: {
2.10 frystyk 48: char linebuf[256]; /* @@@ */
2.11 ! frystyk 49: HTParentAnchor *entity = request->source_anchor ?
! 50: request->source_anchor : request->anchor;
2.1 frystyk 51:
2.10 frystyk 52: if (request->EntityMask & HT_E_ALLOW) {
53: /* @@@@@@@@@@ */
54: }
55: if (request->EntityMask & HT_E_CONTENT_ENCODING &&
56: entity->content_encoding) {
57: sprintf(linebuf, "Content-Encoding: %s%c%c",
58: HTAtom_name(entity->content_encoding), CR, LF);
2.2 frystyk 59: PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1 frystyk 60: }
2.10 frystyk 61:
62: /* @@@ SHOULD BE A LIST @@@ */
63: if (request->EntityMask & HT_E_CONTENT_LANGUAGE &&
64: entity->content_language) {
65: sprintf(linebuf, "Content-Language: %s%c%c",
66: HTAtom_name(entity->content_language), CR, LF);
2.2 frystyk 67: PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1 frystyk 68: }
2.10 frystyk 69: if (request->EntityMask & HT_E_CONTENT_LENGTH) { /* Must be there!!! */
70: sprintf(linebuf, "Content-Length: %ld%c%c",
71: entity->content_length, CR, LF);
72: PUTBLOCK(linebuf, (int) strlen(linebuf));
73: }
74: if (request->EntityMask & HT_E_CTE && entity->cte) {
75: sprintf(linebuf, "Content-Transfer-Encoding: %s%c%c",
76: HTAtom_name(entity->cte), CR, LF);
2.2 frystyk 77: PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1 frystyk 78: }
2.10 frystyk 79: if (request->EntityMask & HT_E_CONTENT_TYPE && entity->content_type) {
80: int len;
81: sprintf(linebuf, "Content-Type: %s",
82: HTAtom_name(entity->content_type));
83: if (entity->charset) {
84: strcat(linebuf, "; charset=");
85: strcat(linebuf, HTAtom_name(entity->charset));
86: }
87: if (entity->level) {
88: strcat(linebuf, "; level=");
89: strcat(linebuf, HTAtom_name(entity->level));
90: }
91: len = strlen(linebuf);
92: *(linebuf+len) = CR;
93: *(linebuf+len+1) = LF;
94: *(linebuf+len+2) = '\0';
95: PUTBLOCK(linebuf, (int) len+2);
96: }
97: if (request->EntityMask & HT_E_DERIVED_FROM && entity->derived_from) {
98: sprintf(linebuf, "Derived-From: %s%c%c", entity->derived_from,
99: CR, LF);
2.2 frystyk 100: PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1 frystyk 101: }
2.10 frystyk 102: if (request->EntityMask & HT_E_EXPIRES) {
103: if (entity->expires != -1) {
104: sprintf(linebuf, "Expires: %s%c%c",
105: HTDateTimeStr(&entity->expires, NO), CR,LF);
2.2 frystyk 106: PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1 frystyk 107: }
2.10 frystyk 108: }
109: if (request->EntityMask & HT_E_LAST_MODIFIED) {
110: if (entity->last_modified != -1) {
111: sprintf(linebuf, "Last-Modified: %s%c%c",
112: HTDateTimeStr(&entity->last_modified, NO), CR,LF);
2.2 frystyk 113: PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1 frystyk 114: }
2.10 frystyk 115: }
116: if (request->EntityMask & HT_E_LINK) { /* @@@@@@@@@@ */
2.1 frystyk 117:
2.10 frystyk 118: }
119: if (request->EntityMask & HT_E_TITLE) { /* @@@@@@@@@@ */
2.1 frystyk 120:
2.10 frystyk 121: }
122: if (request->EntityMask & HT_E_URI) { /* @@@@@@@@@@ */
2.1 frystyk 123:
124: }
2.10 frystyk 125: if (request->EntityMask & HT_E_VERSION && entity->version) {
126: sprintf(linebuf, "Version: %s%c%c", entity->version, CR, LF);
127: PUTBLOCK(linebuf, (int) strlen(linebuf));
128: }
129: if (me->endHeader) {
130: sprintf(linebuf, "%c%c", CR, LF); /* Blank line means "end" */
131: PUTBLOCK(linebuf, (int) strlen(linebuf));
2.2 frystyk 132: }
2.10 frystyk 133: if (PROT_TRACE) TTYPrint(TDEST,"MIME........ Generating Entity Headers\n");
2.2 frystyk 134: return HT_OK;
2.1 frystyk 135: }
136:
137: PRIVATE int MIMERequest_put_block (HTStream * me, CONST char * b, int l)
138: {
139: if (me->transparent)
140: return b ? PUTBLOCK(b, l) : HT_OK;
141: else {
142: MIMEMakeRequest(me, me->request);
2.9 frystyk 143: if (HTRequest_isDestination(me->request)) {
144: (*me->target->isa->flush)(me->target);
145: HTNet_setBytesWritten(me->request->net, 0);
2.1 frystyk 146: }
2.9 frystyk 147: me->transparent = YES;
2.2 frystyk 148: return b ? PUTBLOCK(b, l) : HT_OK;
2.1 frystyk 149: }
150: }
151:
152: PRIVATE int MIMERequest_put_character (HTStream * me, char c)
153: {
154: return MIMERequest_put_block(me, &c, 1);
155: }
156:
157: PRIVATE int MIMERequest_put_string (HTStream * me, CONST char * s)
158: {
159: return MIMERequest_put_block(me, s, strlen(s));
160: }
161:
162: /*
163: ** Flushes header but doesn't free stream object
164: */
165: PRIVATE int MIMERequest_flush (HTStream * me)
166: {
167: int status = MIMERequest_put_block(me, NULL, 0);
168: return status==HT_OK ? (*me->target->isa->flush)(me->target) : status;
169: }
170:
171: /*
172: ** Flushes data and frees stream object
173: */
174: PRIVATE int MIMERequest_free (HTStream * me)
175: {
176: int status = MIMERequest_flush(me);
177: if (status != HT_WOULD_BLOCK) {
178: if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)
179: return HT_WOULD_BLOCK;
180: free(me);
181: }
182: return status;
183: }
184:
2.4 frystyk 185: PRIVATE int MIMERequest_abort (HTStream * me, HTList * e)
2.1 frystyk 186: {
187: if (me->target) (*me->target->isa->abort)(me->target, e);
188: free(me);
2.3 frystyk 189: if (PROT_TRACE) TTYPrint(TDEST, "MIMERequest. ABORTING...\n");
2.1 frystyk 190: return HT_ERROR;
191: }
192:
193: /* MIMERequest Stream
194: ** -----------------
195: */
196: PRIVATE CONST HTStreamClass MIMERequestClass =
197: {
198: "MIMERequest",
199: MIMERequest_flush,
200: MIMERequest_free,
201: MIMERequest_abort,
202: MIMERequest_put_character,
203: MIMERequest_put_string,
204: MIMERequest_put_block
205: };
206:
2.10 frystyk 207: PUBLIC HTStream * HTMIMERequest_new (HTRequest * request, HTStream * target,
208: BOOL endHeader)
2.1 frystyk 209: {
210: HTStream * me = (HTStream *) calloc(1, sizeof(HTStream));
211: if (!me) outofmem(__FILE__, "HTMIMERequest_new");
212: me->isa = &MIMERequestClass;
213: me->target = target;
214: me->request = request;
2.10 frystyk 215: me->endHeader = endHeader;
2.1 frystyk 216: me->transparent = NO;
217: return me;
218: }
Webmaster