Annotation of libwww/Library/src/HTMIMERq.c, revision 2.10

2.1       frystyk     1: /*                                                                  HTMIMERq.c
2.10    ! frystyk     2: **     MIME ENTITY HEADERS GENERATION
2.1       frystyk     3: **
                      4: **     This module implements the output stream for MIME used for sending
2.10    ! frystyk     5: **     requests with a entity body to HTTP, NEWS, etc. or for generating
        !             6: **     responses
2.1       frystyk     7: **
                      8: ** History:
                      9: **     Jan 95 HFN      Written
                     10: */
                     11: 
                     12: /* Library Includes */
                     13: #include "tcp.h"
                     14: #include "HTUtils.h"
                     15: #include "HTString.h"
2.5       frystyk    16: #include "HTWWWStr.h"
2.1       frystyk    17: #include "HTParse.h"
                     18: #include "HTFormat.h"
2.7       frystyk    19: #include "HTAncMan.h"
2.1       frystyk    20: #include "HTNetMan.h"
                     21: #include "HTDNS.h"
                     22: #include "HTTCP.h"
                     23: #include "HTWriter.h"
2.2       frystyk    24: #include "HTHeader.h"
2.1       frystyk    25: #include "HTReqMan.h"
                     26: #include "HTTPReq.h"                                          /* Implements */
                     27: 
                     28: #define PUTBLOCK(b, l) (*me->target->isa->put_block)(me->target, b, l)
                     29: 
                     30: struct _HTStream {
                     31:     CONST HTStreamClass *      isa;
                     32:     HTStream *                 target;
                     33:     HTRequest *                        request;
2.10    ! frystyk    34:     BOOL                       endHeader;
2.1       frystyk    35:     BOOL                       transparent;
                     36: };
                     37: 
                     38: /* ------------------------------------------------------------------------- */
                     39: /*                         MIME Output Request Stream                       */
                     40: /* ------------------------------------------------------------------------- */
                     41: 
                     42: /*     MIMEMakeRequest
                     43: **     ---------------
2.10    ! frystyk    44: **     Generates the BODY parts of a MIME message.
2.1       frystyk    45: */
2.2       frystyk    46: PRIVATE int MIMEMakeRequest (HTStream * me, HTRequest * request)
2.1       frystyk    47: {
2.10    ! frystyk    48:     char linebuf[256];                 /* @@@ */
2.1       frystyk    49:     HTParentAnchor *entity = (request->source && request->source->anchor) ?
                     50:        request->source->anchor : request->anchor;
                     51: 
2.10    ! frystyk    52:     if (request->EntityMask & HT_E_ALLOW) {
        !            53:        /* @@@@@@@@@@ */
        !            54:     }
        !            55:     if (request->EntityMask & HT_E_CONTENT_ENCODING &&
        !            56:        entity->content_encoding) {
        !            57:        sprintf(linebuf, "Content-Encoding: %s%c%c",
        !            58:                HTAtom_name(entity->content_encoding), CR, LF);
2.2       frystyk    59:        PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1       frystyk    60:     }
2.10    ! frystyk    61:     
        !            62:     /* @@@ SHOULD BE A LIST @@@ */
        !            63:     if (request->EntityMask & HT_E_CONTENT_LANGUAGE &&
        !            64:        entity->content_language) {
        !            65:        sprintf(linebuf, "Content-Language: %s%c%c",
        !            66:                HTAtom_name(entity->content_language), CR, LF);
2.2       frystyk    67:        PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1       frystyk    68:     }
2.10    ! frystyk    69:     if (request->EntityMask & HT_E_CONTENT_LENGTH) { /* Must be there!!! */
        !            70:        sprintf(linebuf, "Content-Length: %ld%c%c",
        !            71:                entity->content_length, CR, LF);
        !            72:        PUTBLOCK(linebuf, (int) strlen(linebuf));       
        !            73:     }
        !            74:     if (request->EntityMask & HT_E_CTE && entity->cte) {
        !            75:        sprintf(linebuf, "Content-Transfer-Encoding: %s%c%c",
        !            76:                HTAtom_name(entity->cte), CR, LF);
2.2       frystyk    77:        PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1       frystyk    78:     }
2.10    ! frystyk    79:     if (request->EntityMask & HT_E_CONTENT_TYPE && entity->content_type) {
        !            80:        int len;
        !            81:        sprintf(linebuf, "Content-Type: %s",
        !            82:                HTAtom_name(entity->content_type));
        !            83:        if (entity->charset) {
        !            84:            strcat(linebuf, "; charset=");
        !            85:            strcat(linebuf, HTAtom_name(entity->charset));
        !            86:        }
        !            87:        if (entity->level) {
        !            88:            strcat(linebuf, "; level=");
        !            89:            strcat(linebuf, HTAtom_name(entity->level));
        !            90:        }
        !            91:        len = strlen(linebuf);
        !            92:        *(linebuf+len) = CR;
        !            93:        *(linebuf+len+1) = LF;
        !            94:        *(linebuf+len+2) = '\0';
        !            95:        PUTBLOCK(linebuf, (int) len+2);
        !            96:     }
        !            97:     if (request->EntityMask & HT_E_DERIVED_FROM && entity->derived_from) {
        !            98:        sprintf(linebuf, "Derived-From: %s%c%c", entity->derived_from,
        !            99:                CR, LF);
2.2       frystyk   100:        PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1       frystyk   101:     }
2.10    ! frystyk   102:     if (request->EntityMask & HT_E_EXPIRES) {
        !           103:        if (entity->expires != -1) {
        !           104:            sprintf(linebuf, "Expires: %s%c%c",
        !           105:                    HTDateTimeStr(&entity->expires, NO), CR,LF);
2.2       frystyk   106:            PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1       frystyk   107:        }
2.10    ! frystyk   108:     }
        !           109:     if (request->EntityMask & HT_E_LAST_MODIFIED) {
        !           110:        if (entity->last_modified != -1) {
        !           111:            sprintf(linebuf, "Last-Modified: %s%c%c",
        !           112:                    HTDateTimeStr(&entity->last_modified, NO), CR,LF);
2.2       frystyk   113:            PUTBLOCK(linebuf, (int) strlen(linebuf));
2.1       frystyk   114:        }
2.10    ! frystyk   115:     }
        !           116:     if (request->EntityMask & HT_E_LINK) {             /* @@@@@@@@@@ */
2.1       frystyk   117: 
2.10    ! frystyk   118:     }
        !           119:     if (request->EntityMask & HT_E_TITLE) {            /* @@@@@@@@@@ */
2.1       frystyk   120: 
2.10    ! frystyk   121:     }
        !           122:     if (request->EntityMask & HT_E_URI) {              /* @@@@@@@@@@ */
2.1       frystyk   123: 
                    124:     }
2.10    ! frystyk   125:     if (request->EntityMask & HT_E_VERSION && entity->version) {
        !           126:        sprintf(linebuf, "Version: %s%c%c", entity->version, CR, LF);
        !           127:        PUTBLOCK(linebuf, (int) strlen(linebuf));
        !           128:     }
        !           129:     if (me->endHeader) {
        !           130:        sprintf(linebuf, "%c%c", CR, LF);          /* Blank line means "end" */
        !           131:        PUTBLOCK(linebuf, (int) strlen(linebuf));
2.2       frystyk   132:     }
2.10    ! frystyk   133:     if (PROT_TRACE) TTYPrint(TDEST,"MIME........ Generating Entity Headers\n");
2.2       frystyk   134:     return HT_OK;
2.1       frystyk   135: }
                    136: 
                    137: PRIVATE int MIMERequest_put_block (HTStream * me, CONST char * b, int l)
                    138: {
                    139:     if (me->transparent)
                    140:        return b ? PUTBLOCK(b, l) : HT_OK;
                    141:     else {
                    142:        MIMEMakeRequest(me, me->request);
2.9       frystyk   143:        if (HTRequest_isDestination(me->request)) {
                    144:            (*me->target->isa->flush)(me->target);
                    145:            HTNet_setBytesWritten(me->request->net, 0);
2.1       frystyk   146:        }
2.9       frystyk   147:        me->transparent = YES;  
2.2       frystyk   148:        return b ? PUTBLOCK(b, l) : HT_OK;
2.1       frystyk   149:     }
                    150: }
                    151: 
                    152: PRIVATE int MIMERequest_put_character (HTStream * me, char c)
                    153: {
                    154:     return MIMERequest_put_block(me, &c, 1);
                    155: }
                    156: 
                    157: PRIVATE int MIMERequest_put_string (HTStream * me, CONST char * s)
                    158: {
                    159:     return MIMERequest_put_block(me, s, strlen(s));
                    160: }
                    161: 
                    162: /*
                    163: **     Flushes header but doesn't free stream object
                    164: */
                    165: PRIVATE int MIMERequest_flush (HTStream * me)
                    166: {
                    167:     int status = MIMERequest_put_block(me, NULL, 0);
                    168:     return status==HT_OK ? (*me->target->isa->flush)(me->target) : status;
                    169: }
                    170: 
                    171: /*
                    172: **     Flushes data and frees stream object
                    173: */
                    174: PRIVATE int MIMERequest_free (HTStream * me)
                    175: {
                    176:     int status = MIMERequest_flush(me);
                    177:     if (status != HT_WOULD_BLOCK) {
                    178:        if ((status = (*me->target->isa->_free)(me->target)) == HT_WOULD_BLOCK)
                    179:            return HT_WOULD_BLOCK;
                    180:        free(me);
                    181:     }
                    182:     return status;
                    183: }
                    184: 
2.4       frystyk   185: PRIVATE int MIMERequest_abort (HTStream * me, HTList * e)
2.1       frystyk   186: {
                    187:     if (me->target) (*me->target->isa->abort)(me->target, e);
                    188:     free(me);
2.3       frystyk   189:     if (PROT_TRACE) TTYPrint(TDEST, "MIMERequest. ABORTING...\n");
2.1       frystyk   190:     return HT_ERROR;
                    191: }
                    192: 
                    193: /*     MIMERequest Stream
                    194: **     -----------------
                    195: */
                    196: PRIVATE CONST HTStreamClass MIMERequestClass =
                    197: {              
                    198:     "MIMERequest",
                    199:     MIMERequest_flush,
                    200:     MIMERequest_free,
                    201:     MIMERequest_abort,
                    202:     MIMERequest_put_character,
                    203:     MIMERequest_put_string,
                    204:     MIMERequest_put_block
                    205: };
                    206: 
2.10    ! frystyk   207: PUBLIC HTStream * HTMIMERequest_new (HTRequest * request, HTStream * target,
        !           208:                                     BOOL endHeader)
2.1       frystyk   209: {
                    210:     HTStream * me = (HTStream *) calloc(1, sizeof(HTStream));
                    211:     if (!me) outofmem(__FILE__, "HTMIMERequest_new");
                    212:     me->isa = &MIMERequestClass;
                    213:     me->target = target;
                    214:     me->request = request;
2.10    ! frystyk   215:     me->endHeader = endHeader;
2.1       frystyk   216:     me->transparent = NO;
                    217:     return me;
                    218: }

Webmaster