Annotation of libwww/Library/src/HTNet.c, revision 2.98
2.23 frystyk 1: /* HTNet.c
2.79 frystyk 2: ** HTNet Class
2.1 frystyk 3: **
2.10 frystyk 4: ** (c) COPYRIGHT MIT 1995.
2.4 frystyk 5: ** Please first read the full copyright statement in the file COPYRIGH.
2.98 ! frystyk 6: ** @(#) $Id: HTNet.c,v 2.97 1998/10/20 13:17:19 frystyk Exp $
2.4 frystyk 7: **
8: ** This is the implementation of the internal library multithreading
2.1 frystyk 9: ** functions. This includes an interrupt handler and a event loop.
10: **
11: ** History:
2.14 frystyk 12: ** 12 June 94 Written by Henrik Frystyk, frystyk@w3.org
2.17 frystyk 13: ** 31 May 95 Charlie Brooks cbrooks@osf.org
14: **
2.1 frystyk 15: */
16:
2.9 frystyk 17: /* Implemention dependent include files */
2.93 frystyk 18: #include "wwwsys.h"
2.9 frystyk 19:
2.1 frystyk 20: /* Library include files */
2.59 frystyk 21: #include "WWWUtil.h"
2.16 frystyk 22: #include "HTProt.h"
2.1 frystyk 23: #include "HTError.h"
2.25 frystyk 24: #include "HTAlert.h"
2.37 frystyk 25: #include "HTParse.h"
2.59 frystyk 26: #include "HTTrans.h"
2.74 frystyk 27: #include "HTHost.h"
28: #include "HTReq.h"
2.65 frystyk 29: #include "HTEvent.h"
2.23 frystyk 30: #include "HTStream.h"
2.81 frystyk 31: #include "HTHstMan.h"
32: #include "HTIOStream.h"
2.24 frystyk 33: #include "HTNetMan.h" /* Implemented here */
2.1 frystyk 34:
2.23 frystyk 35: #ifndef HT_MAX_SOCKETS
2.93 frystyk 36: #define HT_MAX_SOCKETS 25
2.23 frystyk 37: #endif
38:
2.91 frystyk 39: #define HASH_SIZE 599
2.74 frystyk 40:
2.79 frystyk 41: typedef struct _BeforeFilter {
42: HTNetBefore * before; /* Filter function */
43: char * tmplate; /* URL template for when to call filter */
44: int order; /* Relative execution order */
2.60 frystyk 45: void * param; /* Local context */
2.79 frystyk 46: } BeforeFilter;
47:
48: typedef struct _AfterFilter {
49: HTNetAfter * after; /* Filter function */
50: char * tmplate; /* URL template for when to call filter */
51: int order; /* Relative execution order */
52: void * param; /* Local context */
53: int status; /* Status of load for when to call filter */
54: } AfterFilter;
2.23 frystyk 55:
56: struct _HTStream {
2.52 frystyk 57: const HTStreamClass * isa;
2.23 frystyk 58: /* ... */
59: };
60:
2.81 frystyk 61: struct _HTInputStream {
62: const HTInputStreamClass * isa;
63: /* ... */
64: };
65:
2.79 frystyk 66: PRIVATE HTList * HTBefore = NULL; /* List of global BEFORE filters */
67: PRIVATE HTList * HTAfter = NULL; /* List of global AFTER filters */
2.24 frystyk 68:
2.74 frystyk 69: PRIVATE int MaxActive = HT_MAX_SOCKETS; /* Max active requests */
70: PRIVATE int Active = 0; /* Counts open sockets */
71: PRIVATE int Persistent = 0; /* Counts persistent sockets */
2.1 frystyk 72:
2.74 frystyk 73: PRIVATE HTList ** NetTable = NULL; /* List of net objects */
74: PRIVATE int HTNetCount = 0; /* Counting elements in table */
2.23 frystyk 75:
76: /* ------------------------------------------------------------------------- */
2.79 frystyk 77: /* GENERIC BEFORE and AFTER filter Management */
2.23 frystyk 78: /* ------------------------------------------------------------------------- */
79:
2.79 frystyk 80: PRIVATE int HTBeforeOrder (const void * a, const void * b)
81: {
82: return ((BeforeFilter *) b)->order - ((BeforeFilter *) a)->order;
83: }
84:
85: PRIVATE int HTAfterOrder (const void * a, const void * b)
86: {
87: return ((AfterFilter *) b)->order - ((AfterFilter *) a)->order;
88: }
89:
2.80 frystyk 90: PRIVATE int check_order (HTFilterOrder order)
2.79 frystyk 91: {
92: return (order<HT_FILTER_FIRST) ? HT_FILTER_FIRST :
93: (order>HT_FILTER_LAST) ? HT_FILTER_LAST : order;
94: }
95:
96: /*
97: ** Register a BEFORE filter in the list provided by the caller.
98: ** Several filters can be registered in which case they are called
99: ** with the filter ordering in mind.
100: */
101: PUBLIC BOOL HTNetCall_addBefore (HTList * list, HTNetBefore * before,
102: const char * tmplate, void * param,
2.80 frystyk 103: HTFilterOrder order)
2.79 frystyk 104: {
105: if (list && before) {
106: BeforeFilter * me;
107: if ((me = (BeforeFilter *) HT_CALLOC(1, sizeof(BeforeFilter)))==NULL)
108: HT_OUTOFMEM("HTNetCall_addBefore");
109: me->before = before;
110: if (tmplate) StrAllocCopy(me->tmplate, tmplate);
111: me->order = check_order(order);
112: me->param = param;
113: if (CORE_TRACE)
114: HTTrace("Net Before.. Add %p with order %d tmplate `%s\' context %p\n",
115: before, me->order, tmplate ? tmplate : "<null>", param);
116: return (HTList_addObject(list, me) &&
117: HTList_insertionSort(list, HTBeforeOrder));
118: }
119: return NO;
120: }
121:
122: /*
123: ** Unregister all instances of a BEFORE filter from a list.
124: */
125: PUBLIC BOOL HTNetCall_deleteBefore (HTList * list, HTNetBefore * before)
126: {
127: if (CORE_TRACE) HTTrace("Net Before.. Delete %p\n", before);
128: if (list && before) {
129: HTList * cur = list;
130: BeforeFilter * pres;
2.94 frystyk 131: while ((pres = (BeforeFilter *) HTList_nextObject(cur))) {
2.79 frystyk 132: if (pres->before == before) {
133: HTList_removeObject(list, (void *) pres);
134: HT_FREE(pres->tmplate);
135: HT_FREE(pres);
136: cur = list;
137: }
138: }
139: }
140: return NO;
141: }
142:
143: /*
144: ** Deletes all BEFORE filters in list
145: */
146: PUBLIC BOOL HTNetCall_deleteBeforeAll (HTList * list)
147: {
148: if (CORE_TRACE) HTTrace("Net Before. Delete All filters\n");
149: if (list) {
150: HTList * cur = list;
151: BeforeFilter * pres;
152: while ((pres = (BeforeFilter *) HTList_nextObject(cur))) {
153: HT_FREE(pres->tmplate);
154: HT_FREE(pres);
155: }
156: HTList_delete(list);
157: return YES;
158: }
159: return NO;
160: }
161:
162: /*
163: ** Call all the BEFORE filters in the order specified at registration
164: ** time. We also check for any template and whether it matches or not.
165: ** If a filter returns other than HT_OK then stop and return immediately.
166: ** Otherwise return what the last filter returns.
2.23 frystyk 167: */
2.79 frystyk 168: PUBLIC int HTNetCall_executeBefore (HTList * list, HTRequest * request)
2.23 frystyk 169: {
2.79 frystyk 170: HTParentAnchor * anchor = HTRequest_anchor(request);
171: char * url = HTAnchor_physical(anchor);
172: char * addr = url ? url : HTAnchor_address((HTAnchor *) anchor);
173: int ret = HT_OK;
174: int mode = 0;
175: if (list && request && addr) {
176: BeforeFilter * pres;
177: while ((pres = (BeforeFilter *) HTList_nextObject(list))) {
178: if (!pres->tmplate ||
179: (pres->tmplate && HTStrMatch(pres->tmplate, addr))) {
180: if (CORE_TRACE) HTTrace("Net Before.. calling %p (request %p, context %p)\n",
181: pres->before,
182: request, pres->param);
183: ret = (*pres->before)(request, pres->param, mode);
184: if (ret != HT_OK) break;
2.88 frystyk 185:
186: /*
187: ** Update the address to match against if the filter changed
188: ** the physical address.
189: */
190: if ((url = HTAnchor_physical(anchor))) addr = url;
2.79 frystyk 191: }
192: }
193: }
194: if (!url) HT_FREE(addr);
195: return ret;
196: }
197:
198: /*
199: ** Register a AFTER filter in the list provided by the caller.
200: ** Several filters can be registered in which case they are called
201: ** with the filter ordering in mind.
202: */
203: PUBLIC BOOL HTNetCall_addAfter (HTList * list, HTNetAfter * after,
204: const char * tmplate, void * param,
2.80 frystyk 205: int status, HTFilterOrder order)
2.79 frystyk 206: {
207: if (list && after) {
208: AfterFilter * me;
209: if ((me = (AfterFilter *) HT_CALLOC(1, sizeof(AfterFilter)))==NULL)
210: HT_OUTOFMEM("HTNetCall_addAfter");
211: me->after = after;
212: if (tmplate) StrAllocCopy(me->tmplate, tmplate);
213: me->order = check_order(order);
2.60 frystyk 214: me->param = param;
2.33 frystyk 215: me->status = status;
2.79 frystyk 216: if (CORE_TRACE)
217: HTTrace("Net After... Add %p with order %d tmplate `%s\' code %d context %p\n",
218: after, me->order, tmplate ? tmplate : "<null>", status, param);
219: return (HTList_addObject(list, me) &&
220: HTList_insertionSort(list, HTAfterOrder));
221: }
222: return NO;
223: }
224:
225: /*
226: ** Unregister all instances of an AFTER filter from a list.
227: */
228: PUBLIC BOOL HTNetCall_deleteAfter (HTList * list, HTNetAfter * after)
229: {
230: if (CORE_TRACE) HTTrace("Net After... Delete %p\n", after);
231: if (list && after) {
232: HTList * cur = list;
233: AfterFilter * pres;
234: while ((pres = (AfterFilter *) HTList_nextObject(cur))) {
235: if (pres->after == after) {
236: HTList_removeObject(list, (void *) pres);
237: HT_FREE(pres->tmplate);
238: HT_FREE(pres);
239: cur = list;
240: }
241: }
2.23 frystyk 242: }
243: return NO;
244: }
245:
2.79 frystyk 246: /*
247: ** Unregister all filters registered for a given status.
2.23 frystyk 248: */
2.79 frystyk 249: PUBLIC BOOL HTNetCall_deleteAfterStatus (HTList * list, int status)
2.23 frystyk 250: {
2.79 frystyk 251: if (CORE_TRACE) HTTrace("Net After... Delete all with status %d\n",status);
252: if (list) {
253: HTList * cur = list;
254: AfterFilter * pres;
255: while ((pres = (AfterFilter *) HTList_nextObject(cur))) {
256: if (pres->status == status) {
2.33 frystyk 257: HTList_removeObject(list, (void *) pres);
2.79 frystyk 258: HT_FREE(pres->tmplate);
2.49 frystyk 259: HT_FREE(pres);
2.79 frystyk 260: cur = list;
2.23 frystyk 261: }
262: }
2.79 frystyk 263: return YES;
2.23 frystyk 264: }
265: return NO;
266: }
2.1 frystyk 267:
2.79 frystyk 268: /*
269: ** Deletes all AFTER filters in list
2.23 frystyk 270: */
2.79 frystyk 271: PUBLIC BOOL HTNetCall_deleteAfterAll (HTList * list)
2.23 frystyk 272: {
2.79 frystyk 273: if (CORE_TRACE) HTTrace("Net After. Delete All filters\n");
2.33 frystyk 274: if (list) {
2.79 frystyk 275: HTList * cur = list;
276: AfterFilter * pres;
277: while ((pres = (AfterFilter *) HTList_nextObject(cur))) {
278: HT_FREE(pres->tmplate);
2.49 frystyk 279: HT_FREE(pres);
2.23 frystyk 280: }
2.33 frystyk 281: HTList_delete(list);
2.23 frystyk 282: return YES;
283: }
284: return NO;
285: }
286:
2.79 frystyk 287: /*
288: ** Call all the AFTER filters in the order specified at registration
289: ** time and if it has the right status code and it's not HT_IGNORE.
290: ** We also check for any template and whether it matches or not.
291: ** If a filter returns other than HT_OK then stop and return immediately.
292: ** Otherwise return what the last filter returns.
2.23 frystyk 293: */
2.79 frystyk 294: PUBLIC int HTNetCall_executeAfter (HTList * list, HTRequest * request,
295: int status)
2.23 frystyk 296: {
2.33 frystyk 297: int ret = HT_OK;
2.79 frystyk 298: if (status != HT_IGNORE) {
299: HTParentAnchor * anchor = HTRequest_anchor(request);
300: char * url = HTAnchor_physical(anchor);
301: char * addr = url ? url : HTAnchor_address((HTAnchor *) anchor);
302: HTResponse * response = HTRequest_response(request);
303: if (list && request && addr) {
304: AfterFilter * pres;
305: while ((pres = (AfterFilter *) HTList_nextObject(list))) {
306: if ((pres->status == status || pres->status == HT_ALL) &&
307: (!pres->tmplate ||
308: (pres->tmplate && HTStrMatch(pres->tmplate, addr)))) {
309: if (CORE_TRACE)
310: HTTrace("Net After... calling %p (request %p, response %p, status %d, context %p)\n",
311: pres->after, request, response,
312: status, pres->param);
313: ret = (*pres->after)(request, response, pres->param, status);
314: if (ret != HT_OK) break;
2.88 frystyk 315:
316: /*
317: ** Update the address to match against if the filter changed
318: ** the physical address.
319: */
320: if ((url = HTAnchor_physical(anchor))) addr = url;
2.79 frystyk 321: }
2.23 frystyk 322: }
323: }
2.79 frystyk 324: if (!url) HT_FREE(addr);
2.1 frystyk 325: }
2.33 frystyk 326: return ret;
327: }
328:
2.79 frystyk 329: /* ------------------------------------------------------------------------- */
330: /* GLOBAL BEFORE and AFTER filter Management */
331: /* ------------------------------------------------------------------------- */
332:
2.33 frystyk 333: /*
334: ** Global set of callback functions BEFORE the request is issued
335: ** list can be NULL
336: */
337: PUBLIC BOOL HTNet_setBefore (HTList *list)
338: {
339: HTBefore = list;
340: return YES;
341: }
342:
343: PUBLIC HTList * HTNet_before (void)
344: {
345: return HTBefore;
346: }
347:
2.79 frystyk 348: PUBLIC BOOL HTNet_addBefore (HTNetBefore * before, const char * tmplate,
2.80 frystyk 349: void * param, HTFilterOrder order)
2.33 frystyk 350: {
2.79 frystyk 351: if (!HTBefore) HTBefore = HTList_new();
352: return HTNetCall_addBefore(HTBefore, before, tmplate, param, order);
2.33 frystyk 353: }
354:
2.79 frystyk 355: PUBLIC BOOL HTNet_deleteBefore (HTNetBefore * cbf)
2.33 frystyk 356: {
2.79 frystyk 357: return HTNetCall_deleteBefore(HTBefore, cbf);
2.33 frystyk 358: }
359:
2.79 frystyk 360: /*
361: ** Call both the local and the global BEFORE filters (if any)
362: */
363: PUBLIC int HTNet_executeBeforeAll (HTRequest * request)
2.73 frystyk 364: {
2.79 frystyk 365: int ret;
366: BOOL override = NO;
367: HTList * befores;
368: if ((befores = HTRequest_before(request, &override))) {
369: if ((ret = HTNetCall_executeBefore(befores, request)) != HT_OK)
370: return ret;
371: }
372: return override ? HT_OK : HTNetCall_executeBefore(HTBefore, request);
2.73 frystyk 373: }
374:
2.33 frystyk 375: /*
376: ** Global set of callback functions AFTER the request is issued
377: ** list can be NULL
378: */
379: PUBLIC BOOL HTNet_setAfter (HTList *list)
380: {
381: HTAfter = list;
382: return YES;
383: }
384:
385: PUBLIC HTList * HTNet_after (void)
386: {
387: return HTAfter;
388: }
389:
2.79 frystyk 390: PUBLIC BOOL HTNet_addAfter (HTNetAfter * after, const char * tmplate,
2.80 frystyk 391: void * param, int status, HTFilterOrder order)
2.33 frystyk 392: {
2.79 frystyk 393: if (!HTAfter) HTAfter = HTList_new();
394: return HTNetCall_addAfter(HTAfter, after, tmplate, param, status, order);
395: }
2.58 hallam 396:
2.79 frystyk 397: PUBLIC BOOL HTNet_deleteAfter (HTNetAfter * cbf)
398: {
399: return HTNetCall_deleteAfter(HTAfter, cbf);
2.33 frystyk 400: }
401:
2.79 frystyk 402: PUBLIC BOOL HTNet_deleteAfterStatus (int status)
2.33 frystyk 403: {
2.79 frystyk 404: return HTNetCall_deleteAfterStatus(HTAfter, status);
2.73 frystyk 405: }
406:
2.79 frystyk 407: /*
408: ** Call both the local and the global AFTER filters (if any)
409: */
410: PUBLIC int HTNet_executeAfterAll (HTRequest * request, int status)
2.73 frystyk 411: {
2.79 frystyk 412: int ret;
413: BOOL override = NO;
414: HTList * afters;
415: if ((afters = HTRequest_after(request, &override))) {
416: if ((ret = HTNetCall_executeAfter(afters, request, status)) != HT_OK)
417: return ret;
418: }
419: return override ? HT_OK : HTNetCall_executeAfter(HTAfter, request, status);
2.1 frystyk 420: }
421:
2.23 frystyk 422: /* ------------------------------------------------------------------------- */
2.74 frystyk 423: /* Socket Management */
2.23 frystyk 424: /* ------------------------------------------------------------------------- */
2.1 frystyk 425:
2.74 frystyk 426: PUBLIC int HTNet_maxSocket (void)
427: {
428: return MaxActive;
429: }
430:
431: PUBLIC BOOL HTNet_setMaxSocket (int newmax)
432: {
433: if (newmax > 0) {
434: MaxActive = newmax;
435: return YES;
436: }
437: return NO;
438: }
439:
440: PUBLIC void HTNet_increaseSocket (void)
441: {
442: Active++;
2.87 frystyk 443: if (CORE_TRACE)
444: HTTrace("Net Manager. Increasing active sockets to %d, %d persistent sockets\n",
445: Active, Persistent);
2.74 frystyk 446: }
447:
448: PUBLIC void HTNet_decreaseSocket (void)
449: {
450: if (--Active < 0) Active = 0;
2.87 frystyk 451: if (CORE_TRACE)
452: HTTrace("Net Manager. Decreasing active sockets to %d, %d persistent sockets\n",
453: Active, Persistent);
2.74 frystyk 454: }
455:
456: PUBLIC int HTNet_availableSockets (void)
457: {
458: int available = MaxActive - Active;
459: return available > 0 ? available : 0;
460: }
461:
462: PUBLIC void HTNet_increasePersistentSocket (void)
463: {
464: Persistent++;
2.87 frystyk 465: if (CORE_TRACE)
466: HTTrace("Net Manager. %d active sockets, increasing persistent sockets to %d\n",
467: Active, Persistent);
2.74 frystyk 468: }
469:
470: PUBLIC void HTNet_decreasePersistentSocket (void)
2.23 frystyk 471: {
2.74 frystyk 472: if (--Persistent < 0) Persistent = 0;
2.87 frystyk 473: if (CORE_TRACE)
474: HTTrace("Net Manager. %d active sockets, decreasing persistent sockets to %d\n",
475: Active, Persistent);
2.23 frystyk 476: }
2.17 frystyk 477:
2.74 frystyk 478: PUBLIC int HTNet_availablePersistentSockets (void)
2.28 frystyk 479: {
2.74 frystyk 480: int available = MaxActive - 2 - Persistent;
481: return available > 0 ? available : 0;
2.28 frystyk 482: }
483:
2.74 frystyk 484: /*
485: ** Returns whether there are any Net objects pending or active
2.40 frystyk 486: */
2.74 frystyk 487: PUBLIC BOOL HTNet_isIdle (void)
2.40 frystyk 488: {
2.74 frystyk 489: return (HTNetCount > 0);
2.40 frystyk 490: }
491:
2.74 frystyk 492: PUBLIC BOOL HTNet_isEmpty (void)
2.1 frystyk 493: {
2.74 frystyk 494: return (HTNetCount <= 0);
2.1 frystyk 495: }
496:
2.81 frystyk 497: PUBLIC int HTNet_count (void)
498: {
499: return HTNetCount;
500: }
501:
2.23 frystyk 502: /* ------------------------------------------------------------------------- */
503: /* Creation and deletion methods */
504: /* ------------------------------------------------------------------------- */
505:
2.74 frystyk 506: PRIVATE HTNet * create_object (void)
507: {
508: static int net_hash = 0;
509: HTNet * me = NULL;
510:
511: /* Create new object */
512: if ((me = (HTNet *) HT_CALLOC(1, sizeof(HTNet))) == NULL)
513: HT_OUTOFMEM("HTNet_new");
514: me->hash = net_hash++ % HASH_SIZE;
515:
516: /* Insert into hash table */
517: if (!NetTable) {
518: if ((NetTable = (HTList **) HT_CALLOC(HASH_SIZE, sizeof(HTList *))) == NULL)
519: HT_OUTOFMEM("create_object");
520: }
521: if (!NetTable[me->hash]) NetTable[me->hash] = HTList_new();
522: HTList_addObject(NetTable[me->hash], (void *) me);
523: HTNetCount++;
524: if (CORE_TRACE)
525: HTTrace("Net Object.. %p created with hash %d\n",me, me->hash);
526: return me;
527: }
528:
2.27 frystyk 529: /* HTNet_duplicate
530: ** ---------------
531: ** Creates a new HTNet object as a duplicate of the same request.
532: ** Returns YES if OK, else NO
533: ** BUG: We do not check if we have a socket free!
534: */
2.43 frystyk 535: PUBLIC HTNet * HTNet_dup (HTNet * src)
2.27 frystyk 536: {
2.74 frystyk 537: if (src) {
538: HTNet * me;
2.75 frystyk 539: int hash;
2.74 frystyk 540: if ((me = create_object()) == NULL) return NULL;
2.75 frystyk 541: hash = me->hash;
2.74 frystyk 542: if (CORE_TRACE) HTTrace("Net Object.. Duplicated %p\n", src);
543: memcpy((void *) me, src, sizeof(HTNet));
2.75 frystyk 544: me->hash = hash; /* Carry over hash entry */
2.74 frystyk 545: return me;
546: }
547: return NULL;
2.27 frystyk 548: }
549:
2.81 frystyk 550: PUBLIC BOOL HTNet_execute (HTNet * net, HTEventType type)
551: {
552: if (net && net->event.cbf && net->request) {
553: if (CORE_TRACE)
2.82 frystyk 554: HTTrace("Net Object.. %p calling %p with event type %d and context %p\n",
555: net, net->event.cbf, type, net->event.param);
556: (*(net->event.cbf))(HTNet_socket(net), net->event.param, type);
2.81 frystyk 557: return YES;
558: }
559: return NO;
560: }
561:
2.74 frystyk 562: /*
563: ** Start a Net obejct by calling the protocol module.
2.30 frystyk 564: */
2.74 frystyk 565: PUBLIC BOOL HTNet_start (HTNet * net)
2.30 frystyk 566: {
2.81 frystyk 567: if (net && net->event.cbf && net->request) {
2.74 frystyk 568: if (CORE_TRACE) HTTrace("Net Object.. Launching %p\n", net);
2.81 frystyk 569: (*(net->event.cbf))(HTNet_socket(net), net->event.param, HTEvent_BEGIN);
2.30 frystyk 570: return YES;
571: }
572: return NO;
573: }
574:
2.37 frystyk 575: /* HTNet_new
576: ** ---------
577: ** This function creates a new HTNet object and assigns the socket number
578: ** to it. This is intended to be used when you are going to listen on a
579: ** socket using the HTDoListen() function in HTTCP.c. The function do NOT
580: ** call any of the callback functions.
581: ** Returns new object or NULL on error
582: */
2.81 frystyk 583: PUBLIC HTNet * HTNet_new (HTRequest * request)
2.37 frystyk 584: {
2.81 frystyk 585: HTNet * me;
586: if ((me = create_object()) == NULL) return NULL;
587: me->preemptive = HTRequest_preemptive(request);
588: HTNet_setEventPriority(me, HTRequest_priority(request));
589: me->request = request;
590: HTRequest_setNet(request, me);
591: return me;
2.37 frystyk 592: }
593:
2.67 frystyk 594: /* HTNet_newServer
595: ** ---------------
596: ** Create a new HTNet object as a new request to be handled. If we have
2.74 frystyk 597: ** more than MaxActive connections already then return NO.
2.67 frystyk 598: ** Returns YES if OK, else NO
2.37 frystyk 599: */
2.98 ! frystyk 600: PUBLIC BOOL HTNet_newServer (HTRequest * request)
2.37 frystyk 601: {
2.98 ! frystyk 602: HTParentAnchor * anchor = HTRequest_anchor(request);
! 603: HTNet * me = NULL;
2.37 frystyk 604: HTProtocol * protocol;
2.67 frystyk 605: HTTransport * tp = NULL; /* added JTD:5/28/96 */
2.98 ! frystyk 606: char * physical = NULL;
! 607: int status;
2.81 frystyk 608: HTProtCallback * cbf;
2.98 ! frystyk 609:
2.37 frystyk 610: if (!request) return NO;
611:
2.98 ! frystyk 612: /*
! 613: ** First we do all the "BEFORE" callbacks in order to see if we are to
! 614: ** continue with this request or not. If we receive a callback status
! 615: ** that is NOT HT_OK then jump directly to the after callbacks and return
! 616: */
! 617: if ((status = HTNet_executeBeforeAll(request)) != HT_OK) {
! 618: HTNet_executeAfterAll(request, status);
! 619: return YES;
! 620: }
! 621:
! 622: /*
! 623: ** If no translation was provided by the filters then use the anchor
! 624: ** address directly
! 625: */
! 626: if (!(physical = HTAnchor_physical(anchor))) {
! 627: char * addr = HTAnchor_address((HTAnchor *) anchor);
! 628: if (CORE_TRACE) HTTrace("Net Object.. Using default address\n");
! 629: HTAnchor_setPhysical(anchor, addr);
! 630: physical = HTAnchor_physical(anchor);
! 631: HT_FREE(addr);
! 632: }
! 633:
2.37 frystyk 634: /* Find a protocol object for this access scheme */
2.98 ! frystyk 635: {
! 636: char * access = HTParse(physical, "", PARSE_ACCESS);
! 637: if ((protocol = HTProtocol_find(request, access)) == NULL) {
! 638: if (CORE_TRACE) HTTrace("Net Object.. NO PROTOCOL Object found for URI scheme `%s\'\n", access);
! 639: HT_FREE(access);
! 640: return NO;
! 641: }
! 642: if (!(cbf = HTProtocol_server(protocol))) {
! 643: if (CORE_TRACE) HTTrace("Net Object.. NO SERVER HANDLER for URI scheme `%s\'\n", access);
! 644: HT_FREE(access);
! 645: HT_FREE(me);
! 646: return NO;
! 647: }
! 648: HT_FREE(access);
! 649: }
2.67 frystyk 650:
651: /* Find a transport object for this protocol */
2.98 ! frystyk 652: if ((tp = HTTransport_find(request, HTProtocol_transport(protocol))) == NULL) {
! 653: if (CORE_TRACE) HTTrace("Net Object.. NO TRANSPORT found for protocol `%s\'\n", HTProtocol_name(protocol));
2.67 frystyk 654: return NO;
655: }
656:
2.98 ! frystyk 657: /* Create new net object and bind to request object */
! 658: if ((me = create_object()) == NULL) return NO;
! 659: me->preemptive = (HTProtocol_preemptive(protocol) || HTRequest_preemptive(request));
! 660: HTNet_setEventPriority(me, HTRequest_priority(request));
! 661: me->protocol = protocol;
! 662: me->transport = tp; /* added - JTD:5/28/96 */
! 663: me->request = request;
! 664: HTRequest_setNet(request, me);
2.37 frystyk 665:
666: /* Start the server request */
2.58 hallam 667: if (CORE_TRACE)
2.98 ! frystyk 668: HTTrace("Net Object.. starting SERVER request %p and net object %p\n", request, me);
! 669: (*(cbf))(INVSOC, request);
2.37 frystyk 670: return YES;
671: }
2.36 frystyk 672:
2.30 frystyk 673: /* HTNet_new
674: ** ---------
2.23 frystyk 675: ** Create a new HTNet object as a new request to be handled. If we have
2.74 frystyk 676: ** more than MaxActive connections already then put this into the
2.23 frystyk 677: ** pending queue, else start the request by calling the call back
678: ** function registered with this access method.
679: ** Returns YES if OK, else NO
680: */
2.37 frystyk 681: PUBLIC BOOL HTNet_newClient (HTRequest * request)
2.23 frystyk 682: {
2.74 frystyk 683: HTParentAnchor * anchor = HTRequest_anchor(request);
2.59 frystyk 684: HTNet * me = NULL;
685: HTProtocol * protocol = NULL;
686: HTTransport * tp = NULL;
2.37 frystyk 687: char * physical = NULL;
2.74 frystyk 688: int status;
2.81 frystyk 689: HTProtCallback * cbf;
690:
2.27 frystyk 691: if (!request) return NO;
2.98 ! frystyk 692:
2.33 frystyk 693: /*
694: ** First we do all the "BEFORE" callbacks in order to see if we are to
695: ** continue with this request or not. If we receive a callback status
696: ** that is NOT HT_OK then jump directly to the after callbacks and return
697: */
2.79 frystyk 698: if ((status = HTNet_executeBeforeAll(request)) != HT_OK) {
699: HTNet_executeAfterAll(request, status);
2.33 frystyk 700: return YES;
701: }
702:
2.36 frystyk 703: /*
2.79 frystyk 704: ** If no translation was provided by the filters then use the anchor
2.36 frystyk 705: ** address directly
706: */
2.74 frystyk 707: if (!(physical = HTAnchor_physical(anchor))) {
708: char * addr = HTAnchor_address((HTAnchor *) anchor);
709: if (CORE_TRACE) HTTrace("Net Object.. Using default address\n");
710: HTAnchor_setPhysical(anchor, addr);
711: physical = HTAnchor_physical(anchor);
2.49 frystyk 712: HT_FREE(addr);
2.33 frystyk 713: }
714:
2.37 frystyk 715: /* Find a protocol object for this access scheme */
716: {
2.81 frystyk 717: char * proxy = HTRequest_proxy(request);
718: char * access = HTParse(proxy ? proxy : physical, "", PARSE_ACCESS);
2.37 frystyk 719: if ((protocol = HTProtocol_find(request, access)) == NULL) {
2.98 ! frystyk 720: if (CORE_TRACE) HTTrace("Net Object.. NO PROTOCOL Object found for URI scheme `%s\'\n", access);
2.49 frystyk 721: HT_FREE(access);
2.37 frystyk 722: return NO;
723: }
2.98 ! frystyk 724: if (!(cbf = HTProtocol_client(protocol))) {
! 725: if (CORE_TRACE) HTTrace("Net Object.. NO CLIENT HANDLER for URI scheme `%s\'\n", access);
! 726: HT_FREE(access);
! 727: HT_FREE(me);
! 728: return NO;
! 729: }
2.49 frystyk 730: HT_FREE(access);
2.37 frystyk 731: }
2.59 frystyk 732:
733: /* Find a transport object for this protocol */
734: tp = HTTransport_find(request, HTProtocol_transport(protocol));
735: if (tp == NULL) {
2.98 ! frystyk 736: if (CORE_TRACE) HTTrace("Net Object.. NO TRANSPORT found for protocol `%s\'\n", HTProtocol_name(protocol));
2.59 frystyk 737: return NO;
738: }
739:
2.23 frystyk 740: /* Create new net object and bind it to the request object */
2.69 frystyk 741: if ((me = create_object()) == NULL) return NO;
2.74 frystyk 742: me->preemptive = (HTProtocol_preemptive(protocol) || HTRequest_preemptive(request));
2.81 frystyk 743: #if 0
2.69 frystyk 744: me->priority = HTRequest_priority(request);
2.81 frystyk 745: #endif
746: HTNet_setEventPriority(me, HTRequest_priority(request));
2.59 frystyk 747: me->protocol = protocol;
748: me->transport = tp;
2.69 frystyk 749: me->request = request;
750: HTRequest_setNet(request, me);
2.74 frystyk 751:
752: /* Increase the number of retrys for this download */
753: HTRequest_addRetry(request);
2.23 frystyk 754:
755: /*
756: ** Check if we can start the request, else put it into pending queue
757: ** If so then call the call back function associated with the anchor.
758: ** We use the INVSOC as we don't have a valid socket yet!
759: */
2.74 frystyk 760: if (CORE_TRACE)
761: HTTrace("Net Object.. starting request %p (retry=%d) with net object %p\n",
762: request, HTRequest_retrys(request), me);
2.81 frystyk 763: (*(cbf))(INVSOC, request);
2.36 frystyk 764: return YES;
765: }
766:
2.23 frystyk 767: /* delete_object
768: ** -------------
769: ** Deletes an HTNet object
2.40 frystyk 770: ** Return YES if OK, else NO
2.15 frystyk 771: */
2.81 frystyk 772: PRIVATE BOOL delete_object (HTNet * net)
2.15 frystyk 773: {
2.74 frystyk 774: if (CORE_TRACE) HTTrace("Net Object.. Remove object %p\n", net);
2.23 frystyk 775: if (net) {
776:
777: /* Close socket */
2.74 frystyk 778: /*
779: ** As we may have a socket available we check for whether
780: ** we can start any pending requests. We do this by asking for
781: ** pending Host objects. If none then use the current object
782: */
2.81 frystyk 783: /* (*net->input->isa->consumed)(net->input, net->header_length + net->bytes_read);
784: */
2.74 frystyk 785:
2.89 frystyk 786: HTHost_launchPending(net->host);
787:
788: /*
2.74 frystyk 789: ** Break the link to the request and free the Net object
790: */
791: HTRequest_setNet(net->request, NULL);
2.49 frystyk 792: HT_FREE(net);
2.81 frystyk 793: return YES;
794: }
795: return NO;
796: }
797:
798: PRIVATE BOOL remove_net (HTNet * net)
799: {
800: if (net && NetTable) {
801: HTList * list = NetTable[net->hash];
802: if (list) {
803: HTList_removeObject(list, (void *) net);
804: delete_object(net);
805: HTNetCount--;
806: return YES;
807: }
2.23 frystyk 808: }
809: return NO;
810: }
811:
2.74 frystyk 812: /*
813: ** Clears the contents of the Net object so that we can use it again.
814: */
815: PUBLIC BOOL HTNet_clear (HTNet * net)
816: {
817: if (net) {
2.81 frystyk 818: net->host->channel = NULL;
819: net->readStream = NULL;
820: net->bytesRead = 0;
2.95 frystyk 821: net->headerBytesRead = 0;
2.81 frystyk 822: net->bytesWritten = 0;
2.95 frystyk 823: net->headerBytesWritten = 0;
2.74 frystyk 824: return YES;
825: }
826: return NO;
827: }
828:
2.23 frystyk 829: /* HTNet_delete
830: ** ------------
831: ** Deletes the HTNet object from the list of active requests and calls
832: ** any registered call back functions IF not the status is HT_IGNORE.
833: ** This is used if we have internal requests that the app doesn't know
834: ** about. We also see if we have pending requests that can be started
835: ** up now when we have a socket free.
836: ** The callback functions are called in the reverse order of which they
837: ** were registered (last one first)
2.40 frystyk 838: ** Return YES if OK, else NO
2.23 frystyk 839: */
840: PUBLIC BOOL HTNet_delete (HTNet * net, int status)
841: {
2.58 hallam 842: if (CORE_TRACE)
2.74 frystyk 843: HTTrace("Net Object.. Delete %p and call AFTER filters\n", net);
844: if (net) {
845: HTRequest * request = net->request;
2.23 frystyk 846:
2.25 frystyk 847: /*
2.74 frystyk 848: ** If we have a premature close then recover the request. Otherwise
849: ** break the link to the Host object and continue deleting the net
850: ** object
2.25 frystyk 851: */
2.74 frystyk 852: if (net->host) {
2.81 frystyk 853: HTHost_unregister (net->host, net, HTEvent_READ);
854: HTHost_unregister (net->host, net, HTEvent_WRITE);
2.74 frystyk 855: if (status == HT_RECOVER_PIPE) {
856: HTNet_clear(net);
2.58 hallam 857: if (CORE_TRACE)
2.74 frystyk 858: HTTrace("Net Object.. Restarting request %p (retry=%d) with net object %p\n",
859: request, HTRequest_retrys(request), net);
860: return YES;
2.81 frystyk 861: }
2.97 frystyk 862: HTHost_deleteNet(net->host, net, status);
2.92 frystyk 863: if (HTHost_doRecover(net->host)) HTHost_recoverPipe(net->host);
2.89 frystyk 864: }
2.74 frystyk 865:
866: /* Remove object from the table of Net Objects */
2.81 frystyk 867: remove_net(net);
2.82 frystyk 868:
2.74 frystyk 869: /* Call AFTER filters */
2.79 frystyk 870: HTNet_executeAfterAll(request, status);
2.74 frystyk 871: return YES;
2.23 frystyk 872: }
873: return NO;
2.98 ! frystyk 874: }
! 875:
! 876: PUBLIC BOOL HTNet_deleteDup (HTNet * dup)
! 877: {
! 878: return dup ? remove_net(dup) : NO;
2.23 frystyk 879: }
880:
881: /* HTNet_deleteAll
882: ** ---------------
883: ** Deletes all HTNet object that might either be active or pending
2.74 frystyk 884: ** We DO NOT call the AFTER filters - A crude way of saying goodbye!
2.23 frystyk 885: */
886: PUBLIC BOOL HTNet_deleteAll (void)
887: {
2.58 hallam 888: if (CORE_TRACE)
2.74 frystyk 889: HTTrace("Net Object.. Remove all Net objects, NO filters\n");
890: if (NetTable) {
891: HTList * cur = NULL;
892: HTNet * pres = NULL;
893: int cnt;
894: for (cnt=0; cnt<HASH_SIZE; cnt++) {
895: if ((cur = NetTable[cnt])) {
896: while ((pres = (HTNet *) HTList_nextObject(cur)) != NULL)
2.81 frystyk 897: delete_object(pres);
2.74 frystyk 898: }
899: HTList_delete(NetTable[cnt]);
2.25 frystyk 900: }
2.74 frystyk 901: HT_FREE(NetTable);
902: HTNetCount = 0;
903: return YES;
2.25 frystyk 904: }
905: return NO;
2.97 frystyk 906: }
907:
908: /*
909: ** When pipelining, it is not possible to kill a single request
910: ** as we then loose track of where we are in the pipe. It is
911: ** therefore necessary to kill the whole pipeline.
912: */
913: PUBLIC BOOL HTNet_killPipe (HTNet * net)
914: {
915: return (net && net->host) ? HTHost_killPipe(net->host) : NO;
2.25 frystyk 916: }
917:
2.23 frystyk 918: /* HTNet_kill
919: ** ----------
920: ** Kill the request by calling the call back function with a request for
921: ** closing the connection. Does not remove the object. This is done by
922: ** HTNet_delete() function which is called by the load routine.
923: ** Returns OK if success, NO on error
924: */
2.74 frystyk 925: PUBLIC BOOL HTNet_kill (HTNet * net)
2.23 frystyk 926: {
2.81 frystyk 927: if (net) {
2.94 frystyk 928: HTAlertCallback * cbf = HTAlert_find(HT_PROG_INTERRUPT);
929: if (cbf) (*cbf)(net->request, HT_PROG_INTERRUPT, HT_MSG_NULL, NULL, NULL, NULL);
2.81 frystyk 930: if (CORE_TRACE) HTTrace("Net Object.. Killing %p\n", net);
931: if (net->event.cbf) {
932: (*(net->event.cbf))(HTNet_socket(net), net->event.param, HTEvent_CLOSE);
933: return YES;
934: }
935: return remove_net(net);
2.23 frystyk 936: }
2.81 frystyk 937: if (CORE_TRACE) HTTrace("Net Object.. No object to kill\n");
2.23 frystyk 938: return NO;
939: }
940:
941: /* HTNet_killAll
942: ** -------------
2.74 frystyk 943: ** Kills all registered net objects by calling the call
2.23 frystyk 944: ** back function with a request for closing the connection. We do not
945: ** remove the HTNet object as it is done by HTNet_delete().
946: ** Returns OK if success, NO on error
947: */
948: PUBLIC BOOL HTNet_killAll (void)
949: {
2.74 frystyk 950: if (CORE_TRACE) HTTrace("Net Object.. Kill ALL Net objects!!!\n");
951: if (NetTable) {
952: HTList * cur = NULL;
953: HTNet * pres = NULL;
954: int cnt;
955: for (cnt=0; cnt<HASH_SIZE; cnt++) {
956: if ((cur = NetTable[cnt])) {
2.75 frystyk 957: while ((pres = (HTNet *) HTList_lastObject(cur)) != NULL)
2.74 frystyk 958: HTNet_kill(pres);
959: }
2.25 frystyk 960: }
2.74 frystyk 961: return YES;
2.25 frystyk 962: }
2.74 frystyk 963: if (CORE_TRACE) HTTrace("Net Object.. No objects to kill\n");
964: return NO;
2.23 frystyk 965: }
2.38 frystyk 966:
967: /* ------------------------------------------------------------------------- */
2.59 frystyk 968: /* Connection Specifics */
969: /* ------------------------------------------------------------------------- */
970:
2.74 frystyk 971: /* HTNet_priority
972: ** --------------
973: ** Get the current priority of the Net object
974: */
975: PUBLIC HTPriority HTNet_priority (HTNet * net)
976: {
2.81 frystyk 977: return (net ? net->event.priority : HT_PRIORITY_INV);
2.74 frystyk 978: }
979:
980: /* HTNet_setPriority
981: ** -----------------
982: ** Set the current priority of the Net object
983: ** This will change the priority next time the thread is blocked
984: */
985: PUBLIC BOOL HTNet_setPriority (HTNet * net, HTPriority priority)
986: {
987: if (net) {
2.81 frystyk 988: net->event.priority = priority;
2.74 frystyk 989: return YES;
990: }
991: return NO;
992: }
993:
2.59 frystyk 994: /* HTNet_Persistent
995: ** ----------------
996: ** Check whether the net object handles persistent connections
997: ** If we have a DNS entry then check that as well.
998: */
999: PUBLIC BOOL HTNet_persistent (HTNet * net)
1000: {
1001: return (net && HTHost_isPersistent(net->host));
1002: }
1003:
1004: /* HTNet_persistent
1005: ** ----------------
1006: ** Set the net object to handle persistent connections
1007: ** If we also have a DNS entry then update that as well
1008: */
2.74 frystyk 1009: PUBLIC BOOL HTNet_setPersistent (HTNet * net,
1010: BOOL persistent,
1011: HTTransportMode mode)
2.59 frystyk 1012: {
1013: if (net) {
2.81 frystyk 1014: BOOL result = HTHost_setPersistent(net->host, persistent, mode);
2.74 frystyk 1015: if (CORE_TRACE)
1016: HTTrace("Net Object.. Persistent connection set %s %s\n",
1017: persistent ? "ON" : "OFF",
1018: result ? "succeeded" : "failed");
2.81 frystyk 1019: return result;
2.59 frystyk 1020: }
1021: return NO;
1022: }
1023:
2.66 frystyk 1024: /*
1025: ** Context pointer to be used in context call back function
1026: */
1027: PUBLIC BOOL HTNet_setContext (HTNet * net, void * context)
1028: {
1029: if (net) {
1030: net->context = context;
1031: return YES;
1032: }
1033: return NO;
1034: }
1035:
1036: PUBLIC void * HTNet_context (HTNet * net)
1037: {
1038: return net ? net->context : NULL;
1039: }
2.38 frystyk 1040:
1041: /*
2.60 frystyk 1042: ** Get and set the socket number
1043: */
1044: PUBLIC BOOL HTNet_setSocket (HTNet * net, SOCKET sockfd)
1045: {
2.81 frystyk 1046: if (net && net->host && net->host->channel) {
1047: HTChannel_setSocket(net->host->channel, sockfd);
2.60 frystyk 1048: return YES;
1049: }
1050: return NO;
1051: }
1052:
1053: PUBLIC SOCKET HTNet_socket (HTNet * net)
1054: {
2.81 frystyk 1055: return (net && net->host && net->host->channel ? HTChannel_socket(net->host->channel) : INVSOC);
2.69 frystyk 1056: }
1057:
1058: /*
1059: ** Get and set the HTRequest object
1060: */
1061: PUBLIC BOOL HTNet_setRequest (HTNet * net, HTRequest * request)
1062: {
1063: if (net && request) {
1064: net->request = request;
1065: return YES;
1066: }
1067: return NO;
1068: }
1069:
1070: PUBLIC HTRequest * HTNet_request (HTNet * net)
1071: {
1072: return (net ? net->request : NULL);
2.60 frystyk 1073: }
1074:
1075: /*
2.59 frystyk 1076: ** Get and set the HTChannel object
2.55 frystyk 1077: */
2.59 frystyk 1078: PUBLIC BOOL HTNet_setChannel (HTNet * net, HTChannel * channel)
2.55 frystyk 1079: {
2.81 frystyk 1080: return (net && channel) ? HTHost_setChannel(net->host, channel) : NO;
2.55 frystyk 1081: }
1082:
2.59 frystyk 1083: PUBLIC HTChannel * HTNet_channel (HTNet * net)
2.55 frystyk 1084: {
2.81 frystyk 1085: return net ? HTHost_channel(net->host) : NULL;
2.59 frystyk 1086: }
1087:
1088: /*
1089: ** Get and set the HTHost object
1090: */
1091: PUBLIC BOOL HTNet_setHost (HTNet * net, HTHost * host)
1092: {
1093: if (net && host) {
1094: net->host = host;
1095: return YES;
1096: }
1097: return NO;
1098: }
1099:
1100: PUBLIC HTHost * HTNet_host (HTNet * net)
1101: {
1102: return (net ? net->host : NULL);
1103: }
1104:
1105: /*
1106: ** Get and set the HTdns object
1107: */
1108: PUBLIC BOOL HTNet_setDns (HTNet * net, HTdns * dns)
1109: {
1110: if (net && dns) {
2.81 frystyk 1111: net->host->dns = dns;
2.59 frystyk 1112: return YES;
1113: }
1114: return NO;
1115: }
1116:
1117: PUBLIC HTdns * HTNet_dns (HTNet * net)
1118: {
2.81 frystyk 1119: return (net ? net->host->dns : NULL);
2.59 frystyk 1120: }
1121:
2.81 frystyk 1122: PUBLIC BOOL HTNet_setProtocol (HTNet * net, HTProtocol * protocol)
1123: {
1124: if (net && protocol) {
1125: net->protocol = protocol;
1126: return YES;
1127: }
1128: return NO;
1129: }
1130:
1131: PUBLIC HTProtocol * HTNet_protocol (HTNet * net)
2.72 frystyk 1132: {
2.81 frystyk 1133: return (net ? net->protocol : NULL);
2.72 frystyk 1134: }
2.59 frystyk 1135:
2.86 frystyk 1136: PUBLIC BOOL HTNet_setTransport (HTNet * net, HTTransport * tp)
1137: {
1138: if (net && tp) {
1139: net->transport = tp;
1140: return YES;
1141: }
1142: return NO;
1143: }
1144:
1145: PUBLIC HTTransport * HTNet_transport (HTNet * net)
1146: {
1147: return (net ? net->transport : NULL);
1148: }
1149:
1150: PUBLIC BOOL HTNet_preemptive (HTNet * net)
1151: {
1152: return (net ? net->preemptive : NO);
1153: }
1154:
2.59 frystyk 1155: /*
1156: ** Create the output stream and bind it to the channel
1157: ** Please read the description in the HTIOStream module on the parameters
1158: */
2.81 frystyk 1159: PUBLIC HTOutputStream * HTNet_getOutput (HTNet * me, void * param, int mode)
2.59 frystyk 1160: {
2.81 frystyk 1161: if (me && me->host && me->host->channel && me->transport) {
1162: HTTransport * tp = me->transport;
1163: HTChannel * ch = me->host->channel;
1164: HTOutputStream * output = (*tp->output_new)(me->host, ch, param, mode);
2.74 frystyk 1165: HTChannel_setOutput(ch, output);
2.59 frystyk 1166: return output;
1167: }
2.81 frystyk 1168: if (CORE_TRACE) HTTrace("Host Object.. Can't create output stream\n");
2.59 frystyk 1169: return NULL;
2.81 frystyk 1170: }
1171:
2.87 frystyk 1172: PUBLIC HTEvent * HTNet_event (HTNet * net)
2.81 frystyk 1173: {
2.87 frystyk 1174: return net ? &net->event : NULL;
1175: }
1176:
1177: PUBLIC BOOL HTNet_setEventParam (HTNet * net, void * eventParam)
1178: {
2.81 frystyk 1179: if (net) return HTEvent_setParam(&net->event, eventParam);
1180: return NO;
1181: }
1182:
2.87 frystyk 1183: PUBLIC void * HTNet_eventParam (HTNet * net)
2.81 frystyk 1184: {
2.87 frystyk 1185: return net ? net->event.param : NULL;
2.81 frystyk 1186: }
1187:
1188: PUBLIC BOOL HTNet_setEventCallback(HTNet * net, HTEventCallback * cbf)
1189: {
1190: if (net) return HTEvent_setCallback(&net->event, cbf);
1191: return NO;
1192: }
1193:
1194: PUBLIC HTEventCallback * HTNet_eventCallback(HTNet * net)
1195: {
1196: return net->event.cbf;
1197: }
1198:
1199: PUBLIC BOOL HTNet_setEventPriority(HTNet * net, HTPriority priority)
1200: {
1201: if (net) return HTEvent_setPriority(&net->event, priority);
1202: return NO;
1203: }
1204:
1205: PUBLIC HTPriority HTNet_eventPriority(HTNet * net)
1206: {
1207: return net->event.priority;
1208: }
1209:
1210: PUBLIC HTStream * HTNet_readStream(HTNet * net)
1211: {
1212: if (!net) return NULL;
1213: return net->readStream;
1214: }
1215:
1216: PUBLIC BOOL HTNet_setReadStream (HTNet * net, HTStream * stream)
1217: {
1218: if (net) {
1219: net->readStream = stream;
1220: return YES;
1221: }
1222: return NO;
2.96 frystyk 1223: }
1224:
1225: /*
1226: ** Should we do raw byte count at the network or later?
1227: ** Normally it is later but in cases like FTP we need it
1228: ** in the raw form
1229: */
1230: PUBLIC BOOL HTNet_setRawBytesCount (HTNet * net, BOOL mode)
1231: {
1232: if (net) {
1233: net->countRawBytes = mode;
1234: return YES;
1235: }
1236: return NO;
1237: }
1238:
1239: PUBLIC BOOL HTNet_rawBytesCount (HTNet * net)
1240: {
1241: return (net && net->countRawBytes);
2.55 frystyk 1242: }
Webmaster