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