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