Annotation of libwww/Library/src/HTTPRes.c, revision 2.1
2.1 ! frystyk 1: /* HTTPRes.c
! 2: ** HTTP MESSAGES GENERATION
! 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 */
! 13: #include "tcp.h"
! 14: #include "HTUtils.h"
! 15: #include "HTString.h"
! 16: #include "HTWWWStr.h"
! 17: #include "HTAccess.h"
! 18: #include "HTWriter.h"
! 19: #include "HTEvntrg.h"
! 20: #include "HTNetMan.h"
! 21: #include "HTReqMan.h"
! 22: #include "HTMIMERq.h"
! 23: #include "HTTPUtil.h"
! 24: #include "HTTPRes.h" /* Implements */
! 25:
! 26: #define PUTBLOCK(b, l) (*me->target->isa->put_block)(me->target, b, l)
! 27:
! 28: struct _HTStream {
! 29: CONST HTStreamClass * isa;
! 30: HTStream * target;
! 31: HTRequest * request;
! 32: SOCKET sockfd;
! 33: BOOL transparent;
! 34: };
! 35:
! 36: /* ------------------------------------------------------------------------- */
! 37: /* HTTP Output Request Stream */
! 38: /* ------------------------------------------------------------------------- */
! 39:
! 40: /* HTTPMakeResponse
! 41: ** ----------------
! 42: ** Makes a HTTP/1.0-1.1 response header.
! 43: */
! 44: PRIVATE void HTTPMakeResponse (HTStream * me, HTRequest * request)
! 45: {
! 46: char linebuf[256];
! 47: HTParentAnchor *anchor = HTRequest_anchor(request);
! 48:
! 49: /* Generate the HTTP/1.0 ResponseLine */
! 50: if (request->error_stack) {
! 51:
! 52: /* @@@ WRITE A SMALL HTError_response() function */
! 53: sprintf(linebuf, "HTTP/1.0 404 Not Found%c%c", CR, LF);
! 54:
! 55: PUTBLOCK(linebuf, (int) strlen(linebuf));
! 56: } else {
! 57: sprintf(linebuf, "HTTP/1.0 200 OK%c%c", CR, LF);
! 58: PUTBLOCK(linebuf, (int) strlen(linebuf));
! 59:
! 60: /* Response Headers */
! 61: if (request->ResponseMask & HT_S_SERVER) {
! 62: sprintf(linebuf, "Server: %s/%s %s/%s%c%c",
! 63: HTLib_appName(), HTLib_appVersion(),
! 64: HTLib_name(), HTLib_version(), CR, LF);
! 65: PUTBLOCK(linebuf, (int) strlen(linebuf));
! 66: }
! 67: }
! 68: }
! 69:
! 70: PRIVATE int HTTPResponse_put_block (HTStream * me, CONST char * b, int l)
! 71: {
! 72: if (!me->target) {
! 73: return HT_WOULD_BLOCK;
! 74: } else if (me->transparent)
! 75: return b ? PUTBLOCK(b, l) : HT_OK;
! 76: else {
! 77: HTTPMakeResponse(me, me->request); /* Generate header */
! 78: me->transparent = YES;
! 79: return b ? PUTBLOCK(b, l) : HT_OK;
! 80: }
! 81: }
! 82:
! 83: PRIVATE int HTTPResponse_put_character (HTStream * me, char c)
! 84: {
! 85: return HTTPResponse_put_block(me, &c, 1);
! 86: }
! 87:
! 88: PRIVATE int HTTPResponse_put_string (HTStream * me, CONST char * s)
! 89: {
! 90: return HTTPResponse_put_block(me, s, strlen(s));
! 91: }
! 92:
! 93: /*
! 94: ** Flushes data but doesn't free stream object
! 95: */
! 96: PRIVATE int HTTPResponse_flush (HTStream * me)
! 97: {
! 98: int status = HTTPResponse_put_block(me, NULL, 0);
! 99: return status==HT_OK ? (*me->target->isa->flush)(me->target) : status;
! 100: }
! 101:
! 102: /*
! 103: ** Flushes data and frees stream object
! 104: */
! 105: PRIVATE int HTTPResponse_free (HTStream * me)
! 106: {
! 107: int status = HTTPResponse_flush(me);
! 108: if (status != HT_WOULD_BLOCK) {
! 109: if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)
! 110: return HT_WOULD_BLOCK;
! 111: free(me);
! 112: }
! 113: return status;
! 114: }
! 115:
! 116: PRIVATE int HTTPResponse_abort (HTStream * me, HTList * e)
! 117: {
! 118: if (me->target) (*me->target->isa->abort)(me->target, e);
! 119: free(me);
! 120: if (PROT_TRACE) TTYPrint(TDEST, "HTTPResponse ABORTING...\n");
! 121: return HT_ERROR;
! 122: }
! 123:
! 124: /* HTTPResponse Stream
! 125: ** -----------------
! 126: */
! 127: PRIVATE CONST HTStreamClass HTTPResponseClass =
! 128: {
! 129: "HTTPResponse",
! 130: HTTPResponse_flush,
! 131: HTTPResponse_free,
! 132: HTTPResponse_abort,
! 133: HTTPResponse_put_character,
! 134: HTTPResponse_put_string,
! 135: HTTPResponse_put_block
! 136: };
! 137:
! 138: PUBLIC HTStream * HTTPResponse_new (HTRequest * request, HTStream * target)
! 139: {
! 140: HTStream * me = (HTStream *) calloc(1, sizeof(HTStream));
! 141: if (!me) outofmem(__FILE__, "HTTPResponse_new");
! 142: me->isa = &HTTPResponseClass;
! 143: me->target = target;
! 144: me->request = request;
! 145: me->transparent = NO;
! 146: return HTMIMERequest_new(request, me);
! 147: }
Webmaster