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