Annotation of libwww/Library/src/HTTPRes.c, revision 2.8
2.1 frystyk 1: /* HTTPRes.c
2.4 frystyk 2: ** HTTP RESPONSE GENERATION
2.1 frystyk 3: **
4: ** This module implements the output stream for HTTP used for sending
5: ** responces with or without a entity body. It is the server equivalent
6: ** to the HTTPReq module
7: **
8: ** History:
9: ** Dec 95 HFN Written from scratch
10: */
11:
12: /* Library Includes */
2.8 ! frystyk 13: #include "sysdep.h"
2.1 frystyk 14: #include "HTUtils.h"
15: #include "HTString.h"
16: #include "HTWWWStr.h"
17: #include "HTAccess.h"
18: #include "HTWriter.h"
2.5 frystyk 19: #include "HTError.h"
2.4 frystyk 20: #include "HTFWrite.h"
2.1 frystyk 21: #include "HTEvntrg.h"
22: #include "HTNetMan.h"
23: #include "HTReqMan.h"
2.4 frystyk 24: #include "HTTPGen.h"
2.1 frystyk 25: #include "HTTPUtil.h"
26: #include "HTTPRes.h" /* Implements */
27:
2.5 frystyk 28: #define PUTC(c) (*me->target->isa->put_character)(me->target, c)
29: #define PUTS(s) (*me->target->isa->put_string)(me->target, s)
2.1 frystyk 30: #define PUTBLOCK(b, l) (*me->target->isa->put_block)(me->target, b, l)
31:
32: struct _HTStream {
2.8 ! frystyk 33: const HTStreamClass * isa;
2.1 frystyk 34: HTStream * target;
35: HTRequest * request;
36: BOOL transparent;
37: };
38:
39: /* ------------------------------------------------------------------------- */
40: /* HTTP Output Request Stream */
41: /* ------------------------------------------------------------------------- */
42:
43: /* HTTPMakeResponse
44: ** ----------------
45: ** Makes a HTTP/1.0-1.1 response header.
46: */
2.4 frystyk 47: PRIVATE int HTTPMakeResponse (HTStream * me, HTRequest * request)
2.1 frystyk 48: {
2.5 frystyk 49: char crlf[3];
50: *crlf = CR; *(crlf+1) = LF; *(crlf+2) = '\0';
51:
52: if (request->ResponseMask & HT_S_LOCATION) { /* @@@ */
53:
54: }
55: if (request->ResponseMask & HT_S_PROXY_AUTH) { /* @@@ */
56:
57: }
58: if (request->ResponseMask & HT_S_PUBLIC) { /* @@@ */
59:
60: }
61: if (request->ResponseMask & HT_S_RETRY_AFTER) { /* @@@ */
62:
63: }
64: if (request->ResponseMask & HT_S_SERVER) {
65: PUTS("Server: ");
66: PUTS(HTLib_appName());
67: PUTC('/');
68: PUTS(HTLib_appVersion());
69: PUTC(' ');
70: PUTS(HTLib_name());
71: PUTC('/');
72: PUTS(HTLib_version());
73: PUTBLOCK(crlf, 2);
74: }
75: if (request->ResponseMask & HT_S_WWW_AUTH) { /* @@@ */
2.1 frystyk 76:
77: }
2.7 eric 78: if(PROT_TRACE)HTTrace("HTTP........ Generating Response Headers\n");
2.4 frystyk 79: return HT_OK;
2.1 frystyk 80: }
81:
2.8 ! frystyk 82: PRIVATE int HTTPResponse_put_block (HTStream * me, const char * b, int l)
2.1 frystyk 83: {
2.4 frystyk 84: if (me->target) {
85: if (me->transparent)
86: return PUTBLOCK(b, l);
87: else {
88: HTTPMakeResponse(me, me->request); /* Generate header */
89: me->transparent = YES;
90: return b ? PUTBLOCK(b, l) : HT_OK;
91: }
2.1 frystyk 92: }
2.4 frystyk 93: return HT_WOULD_BLOCK;
2.1 frystyk 94: }
95:
96: PRIVATE int HTTPResponse_put_character (HTStream * me, char c)
97: {
98: return HTTPResponse_put_block(me, &c, 1);
99: }
100:
2.8 ! frystyk 101: PRIVATE int HTTPResponse_put_string (HTStream * me, const char * s)
2.1 frystyk 102: {
103: return HTTPResponse_put_block(me, s, strlen(s));
104: }
105:
106: /*
107: ** Flushes data but doesn't free stream object
108: */
109: PRIVATE int HTTPResponse_flush (HTStream * me)
110: {
2.4 frystyk 111: if (!me->transparent) {
112: int status = HTTPMakeResponse(me, me->request);
113: if (status != HT_OK) return status;
114: }
115: return (*me->target->isa->flush)(me->target);
2.1 frystyk 116: }
117:
118: /*
119: ** Flushes data and frees stream object
120: */
121: PRIVATE int HTTPResponse_free (HTStream * me)
122: {
2.4 frystyk 123: if (me->target) {
124: int status;
125: if (!me->transparent)
126: if ((status = HTTPMakeResponse(me, me->request)) != HT_OK)
127: return status;
128: if ((status = (*me->target->isa->_free)(me->target)) != HT_OK)
129: return status;
2.1 frystyk 130: }
2.4 frystyk 131: return HT_OK;
2.1 frystyk 132: }
133:
134: PRIVATE int HTTPResponse_abort (HTStream * me, HTList * e)
135: {
136: if (me->target) (*me->target->isa->abort)(me->target, e);
2.7 eric 137: if (PROT_TRACE) HTTrace("HTTPResponse ABORTING...\n");
2.1 frystyk 138: return HT_ERROR;
139: }
140:
141: /* HTTPResponse Stream
142: ** -----------------
143: */
2.8 ! frystyk 144: PRIVATE const HTStreamClass HTTPResponseClass =
2.1 frystyk 145: {
146: "HTTPResponse",
147: HTTPResponse_flush,
148: HTTPResponse_free,
149: HTTPResponse_abort,
150: HTTPResponse_put_character,
151: HTTPResponse_put_string,
152: HTTPResponse_put_block
153: };
154:
2.4 frystyk 155: /*
2.5 frystyk 156: ** This stream generates server specific headers
2.4 frystyk 157: */
2.5 frystyk 158: PUBLIC HTStream * HTTPResponse_new (HTRequest * request, HTStream * target,
159: BOOL endHeader)
160: {
2.6 frystyk 161: HTStream * me;
162: if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
163: HT_OUTOFMEM("HTTPResponse_new");
2.1 frystyk 164: me->isa = &HTTPResponseClass;
2.5 frystyk 165: me->target = target;
2.1 frystyk 166: me->request = request;
2.5 frystyk 167: me->transparent = NO;
168: return HTTPGen_new(request, me, endHeader);
2.1 frystyk 169: }
Webmaster