Annotation of libwww/Library/src/HTSocket.c, revision 2.33

2.1       frystyk     1: /*                                                                  HTSocket.c
2.29      frystyk     2: **     LOAD A SOCKET
2.1       frystyk     3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.33    ! frystyk     6: **     @(#) $Id: HTSocket.c,v 2.32 1998/05/04 19:37:21 frystyk Exp $
2.1       frystyk     7: **
                      8: **
                      9: ** HISTORY:
2.29      frystyk    10: **     6 June 95  HFN  Written
2.1       frystyk    11: */
                     12: 
                     13: /* Library Include files */
2.32      frystyk    14: #include "wwwsys.h"
2.30      frystyk    15: #include "WWWUtil.h"
                     16: #include "WWWCore.h"
                     17: #include "WWWTrans.h"
2.8       frystyk    18: #include "HTNetMan.h"
2.1       frystyk    19: #include "HTSocket.h"                                   /* Implemented here */
                     20: 
2.33    ! frystyk    21: #ifndef RAW_PORT
        !            22: #define RAW_PORT 1024
        !            23: #endif
        !            24: 
        !            25: /* Final states have negative value */
        !            26: typedef enum _RAWState {
        !            27:     RAW_ERROR          = -2,
        !            28:     RAW_OK             = -1,
        !            29:     RAW_BEGIN          = 0,
        !            30:     RAW_NEED_STREAM,
        !            31:     RAW_READ
        !            32: } RawState;
        !            33: 
        !            34: /* This is the context structure for the this module */
        !            35: typedef struct _raw_info {
        !            36:     RawState           state;            /* Current State of the connection */
        !            37:     HTNet *            listen;
        !            38:     HTNet *            accepted;
        !            39:     HTRequest *                request;
        !            40: } raw_info;
        !            41: 
2.1       frystyk    42: struct _HTStream {
2.25      frystyk    43:     const HTStreamClass *      isa;
2.1       frystyk    44: };
                     45: 
2.30      frystyk    46: struct _HTInputStream {
                     47:     const HTInputStreamClass * isa;
                     48: };
                     49: 
2.1       frystyk    50: /* ------------------------------------------------------------------------- */
2.27      frystyk    51: 
2.33    ! frystyk    52: PRIVATE int RawCleanup (HTRequest * request, int status)
        !            53: {
        !            54:     HTNet * listen = HTRequest_net(request);
        !            55:     raw_info * raw = (raw_info *) HTNet_context(listen);
        !            56: 
        !            57:     if (PROT_TRACE)
        !            58:        HTTrace("Raw clean... Called with status %d, net %p\n", status, raw->accepted);
        !            59: 
        !            60:     if (status == HT_INTERRUPTED) {
        !            61:        HTAlertCallback * cbf = HTAlert_find(HT_PROG_INTERRUPT);
        !            62:        if (cbf) (*cbf)(request, HT_PROG_INTERRUPT,
        !            63:            HT_MSG_NULL, NULL, NULL, NULL);
        !            64:     } else if (status == HT_TIMEOUT) {
        !            65:        HTAlertCallback * cbf = HTAlert_find(HT_PROG_TIMEOUT);
        !            66:        if (cbf) (*cbf)(request, HT_PROG_TIMEOUT,
        !            67:            HT_MSG_NULL, NULL, NULL, NULL);
        !            68:     }  
        !            69: 
        !            70:     /* Delete both of the Net objects */
        !            71:     if (raw->accepted) {
        !            72:        HTNet_deleteDup(listen);
        !            73:        HTNet_delete(raw->accepted, status);
        !            74:     } else {
        !            75:        HTNet_delete(listen, HT_ERROR);
        !            76:     }
        !            77: 
        !            78:     HT_FREE(raw);
        !            79:     return YES;
        !            80: }
        !            81: 
2.17      frystyk    82: /*     HTLoadSocket
                     83: **     ------------
                     84: **     Given an open socket, this routine loads what ever is on the socket
                     85: **
                     86: ** On entry,
                     87: **      request                This is the request structure
                     88: ** On Exit
                     89: **     returns         HT_ERROR        Error has occured in call back
                     90: **                     HT_OK           Call back was OK
                     91: */
2.31      frystyk    92: PRIVATE int SocketEvent (SOCKET soc, void * pVoid, HTEventType type);
                     93: 
                     94: PUBLIC int HTLoadSocket (SOCKET soc, HTRequest * request)
2.17      frystyk    95: {
2.33    ! frystyk    96:     raw_info * raw;                        /* Specific protocol information */
2.30      frystyk    97:     HTNet * net = HTRequest_net(request);
2.33    ! frystyk    98:     if (PROT_TRACE) HTTrace("Load socket. Setting up socket for accept\n");
        !            99:     if ((raw = (raw_info *) HT_CALLOC(1, sizeof(raw_info))) == NULL)
        !           100:       HT_OUTOFMEM("HTLoadSocket");
        !           101:     raw->state = RAW_BEGIN;
        !           102:     raw->listen = net;
        !           103:     raw->request = request;
        !           104:     HTNet_setContext(net, raw);
2.31      frystyk   105:     HTNet_setEventCallback(net, SocketEvent);
2.33    ! frystyk   106:     HTNet_setEventParam(net, raw);
2.31      frystyk   107: 
2.33    ! frystyk   108:     /* Get it started - ops is ignored */
        !           109:     return SocketEvent(soc, raw, HTEvent_BEGIN);
2.31      frystyk   110: }
                    111: 
                    112: PRIVATE int SocketEvent (SOCKET soc, void * pVoid, HTEventType type)
                    113: {
2.33    ! frystyk   114:     raw_info * raw = (raw_info *)pVoid;
        !           115:     int status = HT_ERROR;
        !           116:     HTNet * listen = raw->listen;
        !           117:     HTRequest * request = HTNet_request(listen);
        !           118:     HTParentAnchor * anchor = HTRequest_anchor(request);
        !           119:     HTHost * host = HTNet_host(listen);
        !           120: 
        !           121:     /*
        !           122:     **  Check whether we have been interrupted or timed out
        !           123:     */
        !           124:     if (type == HTEvent_BEGIN) {
        !           125:        raw->state = RAW_BEGIN;
        !           126:     } else if (type == HTEvent_CLOSE) {                              /* Interrupted */
        !           127:        RawCleanup(request, HT_INTERRUPTED);
        !           128:        return HT_OK;
        !           129:     } else if (type == HTEvent_TIMEOUT) {
        !           130:        HTRequest_addError(request, ERR_FATAL, NO, HTERR_TIME_OUT,
        !           131:                           NULL, 0, "HTLoadSocket");
        !           132:        RawCleanup(request, HT_TIMEOUT);
        !           133:        return HT_OK;
        !           134:     } else if (type == HTEvent_END) {
        !           135:        RawCleanup(request, HT_OK);
2.17      frystyk   136:        return HT_OK;
                    137:     }
2.33    ! frystyk   138:        
        !           139:     /* Now jump into the state machine */
        !           140:     while (1) {
        !           141:        switch(raw->state) {
        !           142:        case RAW_BEGIN:
        !           143:            status = HTHost_accept(host, listen, &raw->accepted, HTAnchor_physical(anchor), RAW_PORT);
        !           144:            host = HTNet_host(listen);
        !           145:             if (status == HT_OK) {
        !           146:                raw->state = RAW_NEED_STREAM;
        !           147:            } else if (status == HT_WOULD_BLOCK || status == HT_PENDING) {
        !           148:                return HT_OK;
        !           149:            } else      
        !           150:                raw->state = RAW_ERROR;        /* Error or interrupt */
        !           151:            break;
        !           152: 
        !           153:        case RAW_NEED_STREAM:
        !           154:        {
        !           155:            /* 
        !           156:            ** Create the stream pipe FROM the channel to the application.
        !           157:            ** The target for the input stream pipe is set up using the
        !           158:            ** stream stack.
        !           159:            */
        !           160:             HTStream * in_stream =
        !           161:                HTStreamStack(WWW_RAW,
        !           162:                              HTRequest_outputFormat(request),
        !           163:                              HTRequest_outputStream(request),
        !           164:                              request, YES);
        !           165:            HTNet_setReadStream(raw->accepted, in_stream);
        !           166:             HTRequest_setOutputConnected(request, YES);
        !           167: 
        !           168:            raw->state = RAW_READ;
        !           169:            break;
        !           170:        }
        !           171: 
        !           172:        case RAW_READ:
        !           173:            status = HTHost_read(host, raw->accepted);
        !           174:            if (status == HT_WOULD_BLOCK)
        !           175:                return HT_OK;
        !           176:            else if (status==HT_CLOSED)
        !           177:                raw->state = RAW_OK;
        !           178:            else 
        !           179:                raw->state = RAW_ERROR;
        !           180:            break;
        !           181: 
        !           182:        case RAW_OK:
        !           183:            RawCleanup(request, HT_OK);
        !           184:            return HT_OK;
        !           185:            break;
        !           186: 
        !           187:        case RAW_ERROR:
        !           188:            RawCleanup(request, HT_ERROR);
        !           189:            return HT_OK;
        !           190:            break;
        !           191: 
        !           192:        default:
        !           193:            HTDebugBreak(__FILE__, __LINE__, "Bad raw state %d\n", raw->state);
        !           194:        }
2.17      frystyk   195:     }
                    196:     return HT_OK;
                    197: }
2.27      frystyk   198: 

Webmaster