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

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.34    ! frystyk     6: **     @(#) $Id: HTSocket.c,v 2.33 1998/12/15 05:34:28 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: 
2.34    ! frystyk    57:     HTTRACE(PROT_TRACE, "Raw clean... Called with status %d, net %p\n" _ status _ raw->accepted);
2.33      frystyk    58: 
                     59:     if (status == HT_INTERRUPTED) {
                     60:        HTAlertCallback * cbf = HTAlert_find(HT_PROG_INTERRUPT);
                     61:        if (cbf) (*cbf)(request, HT_PROG_INTERRUPT,
                     62:            HT_MSG_NULL, NULL, NULL, NULL);
                     63:     } else if (status == HT_TIMEOUT) {
                     64:        HTAlertCallback * cbf = HTAlert_find(HT_PROG_TIMEOUT);
                     65:        if (cbf) (*cbf)(request, HT_PROG_TIMEOUT,
                     66:            HT_MSG_NULL, NULL, NULL, NULL);
                     67:     }  
                     68: 
                     69:     /* Delete both of the Net objects */
                     70:     if (raw->accepted) {
                     71:        HTNet_deleteDup(listen);
                     72:        HTNet_delete(raw->accepted, status);
                     73:     } else {
                     74:        HTNet_delete(listen, HT_ERROR);
                     75:     }
                     76: 
                     77:     HT_FREE(raw);
                     78:     return YES;
                     79: }
                     80: 
2.17      frystyk    81: /*     HTLoadSocket
                     82: **     ------------
                     83: **     Given an open socket, this routine loads what ever is on the socket
                     84: **
                     85: ** On entry,
                     86: **      request                This is the request structure
                     87: ** On Exit
                     88: **     returns         HT_ERROR        Error has occured in call back
                     89: **                     HT_OK           Call back was OK
                     90: */
2.31      frystyk    91: PRIVATE int SocketEvent (SOCKET soc, void * pVoid, HTEventType type);
                     92: 
                     93: PUBLIC int HTLoadSocket (SOCKET soc, HTRequest * request)
2.17      frystyk    94: {
2.33      frystyk    95:     raw_info * raw;                        /* Specific protocol information */
2.30      frystyk    96:     HTNet * net = HTRequest_net(request);
2.34    ! frystyk    97:     HTTRACE(PROT_TRACE, "Load socket. Setting up socket for accept\n");
2.33      frystyk    98:     if ((raw = (raw_info *) HT_CALLOC(1, sizeof(raw_info))) == NULL)
                     99:       HT_OUTOFMEM("HTLoadSocket");
                    100:     raw->state = RAW_BEGIN;
                    101:     raw->listen = net;
                    102:     raw->request = request;
                    103:     HTNet_setContext(net, raw);
2.31      frystyk   104:     HTNet_setEventCallback(net, SocketEvent);
2.33      frystyk   105:     HTNet_setEventParam(net, raw);
2.31      frystyk   106: 
2.33      frystyk   107:     /* Get it started - ops is ignored */
                    108:     return SocketEvent(soc, raw, HTEvent_BEGIN);
2.31      frystyk   109: }
                    110: 
                    111: PRIVATE int SocketEvent (SOCKET soc, void * pVoid, HTEventType type)
                    112: {
2.33      frystyk   113:     raw_info * raw = (raw_info *)pVoid;
                    114:     int status = HT_ERROR;
                    115:     HTNet * listen = raw->listen;
                    116:     HTRequest * request = HTNet_request(listen);
                    117:     HTParentAnchor * anchor = HTRequest_anchor(request);
                    118:     HTHost * host = HTNet_host(listen);
                    119: 
                    120:     /*
                    121:     **  Check whether we have been interrupted or timed out
                    122:     */
                    123:     if (type == HTEvent_BEGIN) {
                    124:        raw->state = RAW_BEGIN;
                    125:     } else if (type == HTEvent_CLOSE) {                              /* Interrupted */
                    126:        RawCleanup(request, HT_INTERRUPTED);
                    127:        return HT_OK;
                    128:     } else if (type == HTEvent_TIMEOUT) {
                    129:        HTRequest_addError(request, ERR_FATAL, NO, HTERR_TIME_OUT,
                    130:                           NULL, 0, "HTLoadSocket");
                    131:        RawCleanup(request, HT_TIMEOUT);
                    132:        return HT_OK;
                    133:     } else if (type == HTEvent_END) {
                    134:        RawCleanup(request, HT_OK);
2.17      frystyk   135:        return HT_OK;
                    136:     }
2.33      frystyk   137:        
                    138:     /* Now jump into the state machine */
                    139:     while (1) {
                    140:        switch(raw->state) {
                    141:        case RAW_BEGIN:
                    142:            status = HTHost_accept(host, listen, &raw->accepted, HTAnchor_physical(anchor), RAW_PORT);
                    143:            host = HTNet_host(listen);
                    144:             if (status == HT_OK) {
                    145:                raw->state = RAW_NEED_STREAM;
                    146:            } else if (status == HT_WOULD_BLOCK || status == HT_PENDING) {
                    147:                return HT_OK;
                    148:            } else      
                    149:                raw->state = RAW_ERROR;        /* Error or interrupt */
                    150:            break;
                    151: 
                    152:        case RAW_NEED_STREAM:
                    153:        {
                    154:            /* 
                    155:            ** Create the stream pipe FROM the channel to the application.
                    156:            ** The target for the input stream pipe is set up using the
                    157:            ** stream stack.
                    158:            */
                    159:             HTStream * in_stream =
                    160:                HTStreamStack(WWW_RAW,
                    161:                              HTRequest_outputFormat(request),
                    162:                              HTRequest_outputStream(request),
                    163:                              request, YES);
                    164:            HTNet_setReadStream(raw->accepted, in_stream);
                    165:             HTRequest_setOutputConnected(request, YES);
                    166: 
                    167:            raw->state = RAW_READ;
                    168:            break;
                    169:        }
                    170: 
                    171:        case RAW_READ:
                    172:            status = HTHost_read(host, raw->accepted);
                    173:            if (status == HT_WOULD_BLOCK)
                    174:                return HT_OK;
                    175:            else if (status==HT_CLOSED)
                    176:                raw->state = RAW_OK;
                    177:            else 
                    178:                raw->state = RAW_ERROR;
                    179:            break;
                    180: 
                    181:        case RAW_OK:
                    182:            RawCleanup(request, HT_OK);
                    183:            return HT_OK;
                    184:            break;
                    185: 
                    186:        case RAW_ERROR:
                    187:            RawCleanup(request, HT_ERROR);
                    188:            return HT_OK;
                    189:            break;
                    190: 
                    191:        default:
2.34    ! frystyk   192:            HTDEBUGBREAK("Bad raw state %d\n" _ raw->state);
2.33      frystyk   193:        }
2.17      frystyk   194:     }
                    195:     return HT_OK;
                    196: }
2.27      frystyk   197: 

Webmaster