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