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

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

Webmaster