Annotation of libwww/Library/src/HTTPGen.c, revision 2.1
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;
! 140: free(me);
! 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);
! 148: free(me);
! 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: {
! 170: HTStream * me = (HTStream *) calloc(1, sizeof(HTStream));
! 171: if (!me) outofmem(__FILE__, "HTTPGen_new");
! 172: me->isa = &HTTPGenClass;
! 173: me->target = target;
! 174: me->request = request;
! 175: me->endHeader = endHeader;
! 176: me->transparent = NO;
! 177: return me;
! 178: }
Webmaster