Annotation of libwww/Library/src/HTTPGen.c, revision 2.2

2.1       frystyk     1: /*                                                                  HTTPGen.c
                      2: **     HTTP GENERAL HEADER GENERATION
                      3: **
                      4: **     This module implements the output stream for General HTTP headers
                      5: **
                      6: ** History:
                      7: **     Jan 96 HFN      Written
                      8: */
                      9: 
                     10: /* Library Includes */
                     11: #include "tcp.h"
                     12: #include "HTUtils.h"
                     13: #include "HTString.h"
                     14: #include "HTWWWStr.h"
                     15: #include "HTParse.h"
                     16: #include "HTFormat.h"
                     17: #include "HTAncMan.h"
                     18: #include "HTNetMan.h"
                     19: #include "HTTCP.h"
                     20: #include "HTWriter.h"
                     21: #include "HTHeader.h"
                     22: #include "HTReqMan.h"
                     23: #include "HTTPReq.h"                                          /* Implements */
                     24: 
                     25: #define MIME_VERSION   "MIME/1.0"
                     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:     BOOL                       endHeader;
                     33:     BOOL                       transparent;
                     34: };
                     35: 
                     36: /* ------------------------------------------------------------------------- */
                     37: /*                         HTTP General Header Stream                       */
                     38: /* ------------------------------------------------------------------------- */
                     39: 
                     40: /*     HTTPGenMake
                     41: **     ------------
                     42: **     Makes a MIME/1.0 request header.
                     43: */
                     44: PRIVATE int HTTPGenMake (HTStream * me, HTRequest * request)
                     45: {
                     46:     char linebuf[256];
                     47:     if (request->GenMask & HT_G_DATE) {
                     48:        time_t local = time(NULL);
                     49:        sprintf(linebuf, "Date: %s%c%c", HTDateTimeStr(&local, NO), CR,LF);
                     50:        PUTBLOCK(linebuf, (int) strlen(linebuf));
                     51:     }
                     52:     if (request->GenMask & HT_G_FORWARDED) {
                     53:        /* @@@@@@ */
                     54:     }
                     55:     if (request->GenMask & HT_G_MESSAGE_ID) {
                     56:        CONST char *msgid = HTMessageIdStr();
                     57:        if (msgid) {
                     58:            sprintf(linebuf, "Message-ID: %s%c%c", msgid, CR, LF);
                     59:            PUTBLOCK(linebuf, (int) strlen(linebuf));
                     60:        }
                     61:     }
                     62:     if (request->GenMask & HT_G_MIME) {
                     63:        sprintf(linebuf, "MIME-Version: %s%c%c", MIME_VERSION, CR, LF);
                     64:        PUTBLOCK(linebuf, (int) strlen(linebuf));
                     65:     }
                     66:     if (request->GenMask & HT_G_CONNECTION) {
                     67:        sprintf(linebuf, "Connection: Keep-Alive%c%c", CR, LF);
                     68:        PUTBLOCK(linebuf, (int) strlen(linebuf));
                     69:     }
                     70:     if (request->RequestMask & HT_G_NO_CACHE) {
                     71:        sprintf(linebuf, "Pragma: %s%c%c", "no-cache", CR, LF);
                     72:        PUTBLOCK(linebuf, (int) strlen(linebuf));
                     73:     }
                     74: 
                     75:     /* Put out extra information if any */
                     76:     {
                     77:        HTList * list;
                     78:        BOOL override;
                     79:        if ((list = HTRequest_generator(request, &override))) {
                     80:            HTList *local = list;
                     81:            HTPostCallback *pres;
                     82:            if (STREAM_TRACE) TTYPrint(TDEST,"HTTPGen..... Extra local\n");
                     83:            while ((pres = (HTPostCallback *) HTList_nextObject(local)))
                     84:                (*pres)(request, me->target);
                     85:        } else if (!override && (list = HTHeader_generator())) {
                     86:            HTList *global = list;
                     87:            HTPostCallback *pres;
                     88:            if (STREAM_TRACE) TTYPrint(TDEST,"HTTPGen..... Extra global\n");
                     89:            while ((pres = (HTPostCallback *) HTList_nextObject(global)))
                     90:                (*pres)(request, me->target);
                     91:        }
                     92:     }
                     93:     if (me->endHeader) {
                     94:        sprintf(linebuf, "%c%c", CR, LF);          /* Blank line means "end" */
                     95:        PUTBLOCK(linebuf, (int) strlen(linebuf));
                     96:     }
                     97:     if (PROT_TRACE)TTYPrint(TDEST,"HTTP........ Generating General Headers\n");
                     98:     return HT_OK;
                     99: }
                    100: 
                    101: PRIVATE int HTTPGen_put_block (HTStream * me, CONST char * b, int l)
                    102: {
                    103:     if (me->transparent)
                    104:        return b ? PUTBLOCK(b, l) : HT_OK;
                    105:     else {
                    106:        HTTPGenMake(me, me->request);
                    107:        me->transparent = YES;  
                    108:        return b ? PUTBLOCK(b, l) : HT_OK;
                    109:     }
                    110: }
                    111: 
                    112: PRIVATE int HTTPGen_put_character (HTStream * me, char c)
                    113: {
                    114:     return HTTPGen_put_block(me, &c, 1);
                    115: }
                    116: 
                    117: PRIVATE int HTTPGen_put_string (HTStream * me, CONST char * s)
                    118: {
                    119:     return HTTPGen_put_block(me, s, strlen(s));
                    120: }
                    121: 
                    122: /*
                    123: **     Flushes header but doesn't free stream object
                    124: */
                    125: PRIVATE int HTTPGen_flush (HTStream * me)
                    126: {
                    127:     int status = HTTPGen_put_block(me, NULL, 0);
                    128:     return status==HT_OK ? (*me->target->isa->flush)(me->target) : status;
                    129: }
                    130: 
                    131: /*
                    132: **     Flushes data and frees stream object
                    133: */
                    134: PRIVATE int HTTPGen_free (HTStream * me)
                    135: {
                    136:     int status = HTTPGen_flush(me);
                    137:     if (status != HT_WOULD_BLOCK) {
                    138:        if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)
                    139:            return HT_WOULD_BLOCK;
2.2     ! frystyk   140:        HT_FREE(me);
2.1       frystyk   141:     }
                    142:     return status;
                    143: }
                    144: 
                    145: PRIVATE int HTTPGen_abort (HTStream * me, HTList * e)
                    146: {
                    147:     if (me->target) (*me->target->isa->abort)(me->target, e);
2.2     ! frystyk   148:     HT_FREE(me);
2.1       frystyk   149:     if (PROT_TRACE) TTYPrint(TDEST, "HTTPGen..... ABORTING...\n");
                    150:     return HT_ERROR;
                    151: }
                    152: 
                    153: /*     HTTPGen Stream
                    154: **     -----------------
                    155: */
                    156: PRIVATE CONST HTStreamClass HTTPGenClass =
                    157: {              
                    158:     "HTTPGen",
                    159:     HTTPGen_flush,
                    160:     HTTPGen_free,
                    161:     HTTPGen_abort,
                    162:     HTTPGen_put_character,
                    163:     HTTPGen_put_string,
                    164:     HTTPGen_put_block
                    165: };
                    166: 
                    167: PUBLIC HTStream * HTTPGen_new (HTRequest * request, HTStream * target,
                    168:                               BOOL endHeader)
                    169: {
2.2     ! frystyk   170:     HTStream * me;
        !           171:     if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
        !           172:         HT_OUTOFMEM("HTTPGen_new");
2.1       frystyk   173:     me->isa = &HTTPGenClass;
                    174:     me->target = target;
                    175:     me->request = request;
                    176:     me->endHeader = endHeader;
                    177:     me->transparent = NO;
                    178:     return me;
                    179: }

Webmaster