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

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.11      frystyk    49:     HTParentAnchor *entity = request->source_anchor ?
                     50:        request->source_anchor : request->anchor;
2.1       frystyk    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;
2.12    ! frystyk   180:        HT_FREE(me);
2.1       frystyk   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);
2.12    ! frystyk   188:     HT_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: {
2.12    ! frystyk   210:     HTStream * me;
        !           211:     if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
        !           212:         HT_OUTOFMEM("HTMIMERequest_new");
2.1       frystyk   213:     me->isa = &MIMERequestClass;
                    214:     me->target = target;
                    215:     me->request = request;
2.10      frystyk   216:     me->endHeader = endHeader;
2.1       frystyk   217:     me->transparent = NO;
                    218:     return me;
                    219: }

Webmaster