Annotation of libwww/Library/src/HTNet.c, revision 2.107
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.107 ! vbancrof 6: ** @(#) $Id: HTNet.c,v 2.106 2000/07/04 15:26:25 kahan 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: /*
2.106 kahan 202: ** Register an AFTER filter in the list provided by the caller.
2.79 frystyk 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();
2.107 ! vbancrof 353: else HTNet_deleteBefore(before); /* Ensure not listed twice */
2.79 frystyk 354: return HTNetCall_addBefore(HTBefore, before, tmplate, param, order);
2.33 frystyk 355: }
356:
2.79 frystyk 357: PUBLIC BOOL HTNet_deleteBefore (HTNetBefore * cbf)
2.33 frystyk 358: {
2.79 frystyk 359: return HTNetCall_deleteBefore(HTBefore, cbf);
2.33 frystyk 360: }
361:
2.79 frystyk 362: /*
363: ** Call both the local and the global BEFORE filters (if any)
364: */
365: PUBLIC int HTNet_executeBeforeAll (HTRequest * request)
2.73 frystyk 366: {
2.79 frystyk 367: int ret;
368: BOOL override = NO;
369: HTList * befores;
370: if ((befores = HTRequest_before(request, &override))) {
371: if ((ret = HTNetCall_executeBefore(befores, request)) != HT_OK)
372: return ret;
373: }
374: return override ? HT_OK : HTNetCall_executeBefore(HTBefore, request);
2.73 frystyk 375: }
376:
2.33 frystyk 377: /*
378: ** Global set of callback functions AFTER the request is issued
379: ** list can be NULL
380: */
381: PUBLIC BOOL HTNet_setAfter (HTList *list)
382: {
383: HTAfter = list;
384: return YES;
385: }
386:
387: PUBLIC HTList * HTNet_after (void)
388: {
389: return HTAfter;
390: }
391:
2.79 frystyk 392: PUBLIC BOOL HTNet_addAfter (HTNetAfter * after, const char * tmplate,
2.80 frystyk 393: void * param, int status, HTFilterOrder order)
2.33 frystyk 394: {
2.79 frystyk 395: if (!HTAfter) HTAfter = HTList_new();
2.107 ! vbancrof 396: else HTNet_deleteAfter(after); /* Ensure not listed twice */
2.79 frystyk 397: return HTNetCall_addAfter(HTAfter, after, tmplate, param, status, order);
398: }
2.58 hallam 399:
2.79 frystyk 400: PUBLIC BOOL HTNet_deleteAfter (HTNetAfter * cbf)
401: {
402: return HTNetCall_deleteAfter(HTAfter, cbf);
2.33 frystyk 403: }
404:
2.79 frystyk 405: PUBLIC BOOL HTNet_deleteAfterStatus (int status)
2.33 frystyk 406: {
2.79 frystyk 407: return HTNetCall_deleteAfterStatus(HTAfter, status);
2.73 frystyk 408: }
409:
2.79 frystyk 410: /*
411: ** Call both the local and the global AFTER filters (if any)
412: */
413: PUBLIC int HTNet_executeAfterAll (HTRequest * request, int status)
2.73 frystyk 414: {
2.79 frystyk 415: int ret;
416: BOOL override = NO;
417: HTList * afters;
418: if ((afters = HTRequest_after(request, &override))) {
419: if ((ret = HTNetCall_executeAfter(afters, request, status)) != HT_OK)
420: return ret;
421: }
422: return override ? HT_OK : HTNetCall_executeAfter(HTAfter, request, status);
2.1 frystyk 423: }
424:
2.23 frystyk 425: /* ------------------------------------------------------------------------- */
2.74 frystyk 426: /* Socket Management */
2.23 frystyk 427: /* ------------------------------------------------------------------------- */
2.1 frystyk 428:
2.74 frystyk 429: PUBLIC int HTNet_maxSocket (void)
430: {
431: return MaxActive;
432: }
433:
434: PUBLIC BOOL HTNet_setMaxSocket (int newmax)
435: {
436: if (newmax > 0) {
437: MaxActive = newmax;
438: return YES;
439: }
440: return NO;
441: }
442:
443: PUBLIC void HTNet_increaseSocket (void)
444: {
445: Active++;
2.103 frystyk 446: HTTRACE(CORE_TRACE, "Net Manager. Increasing active sockets to %d, %d persistent sockets\n" _
447: Active _ Persistent);
2.74 frystyk 448: }
449:
450: PUBLIC void HTNet_decreaseSocket (void)
451: {
452: if (--Active < 0) Active = 0;
2.103 frystyk 453: HTTRACE(CORE_TRACE, "Net Manager. Decreasing active sockets to %d, %d persistent sockets\n" _
454: Active _ Persistent);
2.74 frystyk 455: }
456:
457: PUBLIC int HTNet_availableSockets (void)
458: {
459: int available = MaxActive - Active;
460: return available > 0 ? available : 0;
461: }
462:
463: PUBLIC void HTNet_increasePersistentSocket (void)
464: {
465: Persistent++;
2.103 frystyk 466: HTTRACE(CORE_TRACE, "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.103 frystyk 473: HTTRACE(CORE_TRACE, "Net Manager. %d active sockets, decreasing persistent sockets to %d\n" _
474: Active _ Persistent);
2.23 frystyk 475: }
2.17 frystyk 476:
2.74 frystyk 477: PUBLIC int HTNet_availablePersistentSockets (void)
2.28 frystyk 478: {
2.74 frystyk 479: int available = MaxActive - 2 - Persistent;
480: return available > 0 ? available : 0;
2.28 frystyk 481: }
482:
2.74 frystyk 483: /*
484: ** Returns whether there are any Net objects pending or active
2.40 frystyk 485: */
2.74 frystyk 486: PUBLIC BOOL HTNet_isIdle (void)
2.40 frystyk 487: {
2.74 frystyk 488: return (HTNetCount > 0);
2.40 frystyk 489: }
490:
2.74 frystyk 491: PUBLIC BOOL HTNet_isEmpty (void)
2.1 frystyk 492: {
2.74 frystyk 493: return (HTNetCount <= 0);
2.1 frystyk 494: }
495:
2.81 frystyk 496: PUBLIC int HTNet_count (void)
497: {
498: return HTNetCount;
499: }
500:
2.23 frystyk 501: /* ------------------------------------------------------------------------- */
502: /* Creation and deletion methods */
503: /* ------------------------------------------------------------------------- */
504:
2.99 frystyk 505: PRIVATE int AfterFilterEvent (HTTimer * timer, void * param, HTEventType type)
506: {
507: HTFilterEvent * fe = (HTFilterEvent *) param;
508: if (fe) {
509: HTRequest * request = fe->request;
510: int status = fe->status;
511: if (timer != fe->timer)
2.103 frystyk 512: HTDEBUGBREAK("Net timer. %p not in sync\n" _ timer);
513: HTTRACE(CORE_TRACE, "HTNet....... Continuing calling AFTER filters %p with timer %p\n" _
514: fe _ timer);
2.99 frystyk 515:
516: /* Delete the event context */
517: HT_FREE(fe);
518:
519: /* Now call the remaining AFTER filters */
520: return HTNet_executeAfterAll(request, status);
521: }
522: return HT_ERROR;
523: }
524:
525: PRIVATE BOOL createAfterFilterEvent (HTRequest * request, int status)
526: {
527: HTFilterEvent * me = NULL;
528: if ((me = (HTFilterEvent *) HT_CALLOC(1, sizeof(HTFilterEvent))) == NULL)
529: HT_OUTOFMEM("createAfterFilterEvent");
530: me->request = request;
531: me->status = status;
532: me->timer = HTTimer_new(NULL, AfterFilterEvent, me, 1, YES, NO);
533: return YES;
534: }
535:
2.74 frystyk 536: PRIVATE HTNet * create_object (void)
537: {
538: static int net_hash = 0;
539: HTNet * me = NULL;
540:
541: /* Create new object */
542: if ((me = (HTNet *) HT_CALLOC(1, sizeof(HTNet))) == NULL)
543: HT_OUTOFMEM("HTNet_new");
2.100 frystyk 544: me->hash = net_hash++ % HT_XL_HASH_SIZE;
2.74 frystyk 545:
546: /* Insert into hash table */
547: if (!NetTable) {
2.100 frystyk 548: if ((NetTable = (HTList **) HT_CALLOC(HT_XL_HASH_SIZE, sizeof(HTList *))) == NULL)
2.74 frystyk 549: HT_OUTOFMEM("create_object");
550: }
551: if (!NetTable[me->hash]) NetTable[me->hash] = HTList_new();
552: HTList_addObject(NetTable[me->hash], (void *) me);
553: HTNetCount++;
2.103 frystyk 554: HTTRACE(CORE_TRACE, "Net Object.. %p created with hash %d\n" _ me _ me->hash);
2.74 frystyk 555: return me;
556: }
557:
2.27 frystyk 558: /* HTNet_duplicate
559: ** ---------------
560: ** Creates a new HTNet object as a duplicate of the same request.
561: ** Returns YES if OK, else NO
562: ** BUG: We do not check if we have a socket free!
563: */
2.43 frystyk 564: PUBLIC HTNet * HTNet_dup (HTNet * src)
2.27 frystyk 565: {
2.74 frystyk 566: if (src) {
567: HTNet * me;
2.75 frystyk 568: int hash;
2.74 frystyk 569: if ((me = create_object()) == NULL) return NULL;
2.75 frystyk 570: hash = me->hash;
2.103 frystyk 571: HTTRACE(CORE_TRACE, "Net Object.. Duplicated %p\n" _ src);
2.74 frystyk 572: memcpy((void *) me, src, sizeof(HTNet));
2.75 frystyk 573: me->hash = hash; /* Carry over hash entry */
2.74 frystyk 574: return me;
575: }
576: return NULL;
2.27 frystyk 577: }
578:
2.81 frystyk 579: PUBLIC BOOL HTNet_execute (HTNet * net, HTEventType type)
580: {
581: if (net && net->event.cbf && net->request) {
2.103 frystyk 582: HTTRACE(CORE_TRACE, "Net Object.. %p calling %p with event type %d and context %p\n" _
583: net _ net->event.cbf _ type _ net->event.param);
2.82 frystyk 584: (*(net->event.cbf))(HTNet_socket(net), net->event.param, type);
2.81 frystyk 585: return YES;
586: }
587: return NO;
588: }
589:
2.74 frystyk 590: /*
591: ** Start a Net obejct by calling the protocol module.
2.30 frystyk 592: */
2.74 frystyk 593: PUBLIC BOOL HTNet_start (HTNet * net)
2.30 frystyk 594: {
2.81 frystyk 595: if (net && net->event.cbf && net->request) {
2.103 frystyk 596: HTTRACE(CORE_TRACE, "Net Object.. Launching %p\n" _ net);
2.81 frystyk 597: (*(net->event.cbf))(HTNet_socket(net), net->event.param, HTEvent_BEGIN);
2.30 frystyk 598: return YES;
599: }
600: return NO;
601: }
602:
2.37 frystyk 603: /* HTNet_new
604: ** ---------
605: ** This function creates a new HTNet object and assigns the socket number
606: ** to it. This is intended to be used when you are going to listen on a
607: ** socket using the HTDoListen() function in HTTCP.c. The function do NOT
2.104 frystyk 608: ** call any of the before or after filter functions.
2.37 frystyk 609: ** Returns new object or NULL on error
610: */
2.104 frystyk 611: PUBLIC HTNet * HTNet_new (HTHost * host)
2.37 frystyk 612: {
2.104 frystyk 613: if (host) {
614: HTNet * me;
615: HTTRACE(CORE_TRACE, "Net Object.. Creating listen object for host %p\n" _ host);
616: me = create_object();
617: me->host = host;
618: return me;
619: }
620: return NULL;
2.37 frystyk 621: }
622:
2.67 frystyk 623: /* HTNet_newServer
624: ** ---------------
625: ** Create a new HTNet object as a new request to be handled. If we have
2.74 frystyk 626: ** more than MaxActive connections already then return NO.
2.67 frystyk 627: ** Returns YES if OK, else NO
2.37 frystyk 628: */
2.98 frystyk 629: PUBLIC BOOL HTNet_newServer (HTRequest * request)
2.37 frystyk 630: {
2.98 frystyk 631: HTParentAnchor * anchor = HTRequest_anchor(request);
632: HTNet * me = NULL;
2.37 frystyk 633: HTProtocol * protocol;
2.67 frystyk 634: HTTransport * tp = NULL; /* added JTD:5/28/96 */
2.98 frystyk 635: char * physical = NULL;
636: int status;
2.81 frystyk 637: HTProtCallback * cbf;
2.98 frystyk 638:
2.37 frystyk 639: if (!request) return NO;
640:
2.98 frystyk 641: /*
642: ** First we do all the "BEFORE" callbacks in order to see if we are to
643: ** continue with this request or not. If we receive a callback status
644: ** that is NOT HT_OK then jump directly to the after callbacks and return
645: */
646: if ((status = HTNet_executeBeforeAll(request)) != HT_OK) {
2.99 frystyk 647:
648: /*
649: ** If in non-blocking mode then return here and call AFTER
650: ** filters from a timer event handler. As Olga Antropova
651: ** points out, otherwise, the stack can grow if new requests
652: ** are started directly from the after filters
653: */
654: if (HTEvent_isCallbacksRegistered() && !HTRequest_preemptive(request))
655: createAfterFilterEvent(request, status);
656: else
657: HTNet_executeAfterAll(request, status);
2.98 frystyk 658: return YES;
659: }
660:
661: /*
662: ** If no translation was provided by the filters then use the anchor
663: ** address directly
664: */
665: if (!(physical = HTAnchor_physical(anchor))) {
666: char * addr = HTAnchor_address((HTAnchor *) anchor);
2.103 frystyk 667: HTTRACE(CORE_TRACE, "Net Object.. Using default address\n");
2.98 frystyk 668: HTAnchor_setPhysical(anchor, addr);
669: physical = HTAnchor_physical(anchor);
670: HT_FREE(addr);
671: }
672:
2.37 frystyk 673: /* Find a protocol object for this access scheme */
2.98 frystyk 674: {
675: char * access = HTParse(physical, "", PARSE_ACCESS);
676: if ((protocol = HTProtocol_find(request, access)) == NULL) {
2.103 frystyk 677: HTTRACE(CORE_TRACE, "Net Object.. NO PROTOCOL Object found for URI scheme `%s\'\n" _ access);
2.98 frystyk 678: HT_FREE(access);
679: return NO;
680: }
681: if (!(cbf = HTProtocol_server(protocol))) {
2.103 frystyk 682: HTTRACE(CORE_TRACE, "Net Object.. NO SERVER HANDLER for URI scheme `%s\'\n" _ access);
2.98 frystyk 683: HT_FREE(access);
684: HT_FREE(me);
685: return NO;
686: }
687: HT_FREE(access);
688: }
2.67 frystyk 689:
690: /* Find a transport object for this protocol */
2.98 frystyk 691: if ((tp = HTTransport_find(request, HTProtocol_transport(protocol))) == NULL) {
2.103 frystyk 692: HTTRACE(CORE_TRACE, "Net Object.. NO TRANSPORT found for protocol `%s\'\n" _ HTProtocol_name(protocol));
2.67 frystyk 693: return NO;
694: }
695:
2.98 frystyk 696: /* Create new net object and bind to request object */
697: if ((me = create_object()) == NULL) return NO;
698: me->preemptive = (HTProtocol_preemptive(protocol) || HTRequest_preemptive(request));
699: HTNet_setEventPriority(me, HTRequest_priority(request));
700: me->protocol = protocol;
701: me->transport = tp; /* added - JTD:5/28/96 */
702: me->request = request;
703: HTRequest_setNet(request, me);
2.37 frystyk 704:
705: /* Start the server request */
2.103 frystyk 706: HTTRACE(CORE_TRACE, "Net Object.. starting SERVER request %p and net object %p\n" _ request _ me);
2.98 frystyk 707: (*(cbf))(INVSOC, request);
2.37 frystyk 708: return YES;
709: }
2.36 frystyk 710:
2.104 frystyk 711: /* HTNet_newClient
712: ** ---------------
2.23 frystyk 713: ** Create a new HTNet object as a new request to be handled. If we have
2.74 frystyk 714: ** more than MaxActive connections already then put this into the
2.23 frystyk 715: ** pending queue, else start the request by calling the call back
716: ** function registered with this access method.
717: ** Returns YES if OK, else NO
718: */
2.37 frystyk 719: PUBLIC BOOL HTNet_newClient (HTRequest * request)
2.23 frystyk 720: {
2.74 frystyk 721: HTParentAnchor * anchor = HTRequest_anchor(request);
2.59 frystyk 722: HTNet * me = NULL;
723: HTProtocol * protocol = NULL;
724: HTTransport * tp = NULL;
2.37 frystyk 725: char * physical = NULL;
2.74 frystyk 726: int status;
2.81 frystyk 727: HTProtCallback * cbf;
728:
2.27 frystyk 729: if (!request) return NO;
2.98 frystyk 730:
2.33 frystyk 731: /*
732: ** First we do all the "BEFORE" callbacks in order to see if we are to
733: ** continue with this request or not. If we receive a callback status
734: ** that is NOT HT_OK then jump directly to the after callbacks and return
735: */
2.79 frystyk 736: if ((status = HTNet_executeBeforeAll(request)) != HT_OK) {
2.99 frystyk 737:
738: /*
739: ** If in non-blocking mode then return here and call AFTER
740: ** filters from a timer event handler. As Olga Antropova
741: ** points out, otherwise, the stack can grow if new requests
742: ** are started directly from the after filters
743: */
744: if (HTEvent_isCallbacksRegistered() && !HTRequest_preemptive(request))
745: createAfterFilterEvent(request, status);
746: else
747: HTNet_executeAfterAll(request, status);
2.33 frystyk 748: return YES;
749: }
750:
2.36 frystyk 751: /*
2.79 frystyk 752: ** If no translation was provided by the filters then use the anchor
2.36 frystyk 753: ** address directly
754: */
2.74 frystyk 755: if (!(physical = HTAnchor_physical(anchor))) {
756: char * addr = HTAnchor_address((HTAnchor *) anchor);
2.103 frystyk 757: HTTRACE(CORE_TRACE, "Net Object.. Using default address\n");
2.74 frystyk 758: HTAnchor_setPhysical(anchor, addr);
759: physical = HTAnchor_physical(anchor);
2.49 frystyk 760: HT_FREE(addr);
2.33 frystyk 761: }
762:
2.37 frystyk 763: /* Find a protocol object for this access scheme */
764: {
2.81 frystyk 765: char * proxy = HTRequest_proxy(request);
766: char * access = HTParse(proxy ? proxy : physical, "", PARSE_ACCESS);
2.37 frystyk 767: if ((protocol = HTProtocol_find(request, access)) == NULL) {
2.103 frystyk 768: HTTRACE(CORE_TRACE, "Net Object.. NO PROTOCOL Object found for URI scheme `%s\'\n" _ access);
2.49 frystyk 769: HT_FREE(access);
2.37 frystyk 770: return NO;
771: }
2.98 frystyk 772: if (!(cbf = HTProtocol_client(protocol))) {
2.103 frystyk 773: HTTRACE(CORE_TRACE, "Net Object.. NO CLIENT HANDLER for URI scheme `%s\'\n" _ access);
2.98 frystyk 774: HT_FREE(access);
775: HT_FREE(me);
776: return NO;
777: }
2.49 frystyk 778: HT_FREE(access);
2.37 frystyk 779: }
2.59 frystyk 780:
781: /* Find a transport object for this protocol */
782: tp = HTTransport_find(request, HTProtocol_transport(protocol));
783: if (tp == NULL) {
2.103 frystyk 784: HTTRACE(CORE_TRACE, "Net Object.. NO TRANSPORT found for protocol `%s\'\n" _ HTProtocol_name(protocol));
2.59 frystyk 785: return NO;
786: }
787:
2.23 frystyk 788: /* Create new net object and bind it to the request object */
2.69 frystyk 789: if ((me = create_object()) == NULL) return NO;
2.74 frystyk 790: me->preemptive = (HTProtocol_preemptive(protocol) || HTRequest_preemptive(request));
2.81 frystyk 791: #if 0
2.69 frystyk 792: me->priority = HTRequest_priority(request);
2.81 frystyk 793: #endif
794: HTNet_setEventPriority(me, HTRequest_priority(request));
2.59 frystyk 795: me->protocol = protocol;
796: me->transport = tp;
2.69 frystyk 797: me->request = request;
798: HTRequest_setNet(request, me);
2.74 frystyk 799:
800: /* Increase the number of retrys for this download */
801: HTRequest_addRetry(request);
2.23 frystyk 802:
803: /*
804: ** Check if we can start the request, else put it into pending queue
805: ** If so then call the call back function associated with the anchor.
806: ** We use the INVSOC as we don't have a valid socket yet!
807: */
2.103 frystyk 808: HTTRACE(CORE_TRACE, "Net Object.. starting request %p (retry=%d) with net object %p\n" _
809: request _ HTRequest_retrys(request) _ me);
2.81 frystyk 810: (*(cbf))(INVSOC, request);
2.36 frystyk 811: return YES;
812: }
813:
2.101 frystyk 814: /*
815: ** Check whether we have any pending HTNet objects and if so
816: ** then start the next one.
2.40 frystyk 817: ** Return YES if OK, else NO
2.15 frystyk 818: */
2.101 frystyk 819: PRIVATE BOOL check_pending (HTNet * net)
2.15 frystyk 820: {
2.103 frystyk 821: HTTRACE(CORE_TRACE, "Net Object.. Check for pending Net objects\n");
2.23 frystyk 822: if (net) {
823:
2.74 frystyk 824: /*
825: ** As we may have a socket available we check for whether
826: ** we can start any pending requests. We do this by asking for
827: ** pending Host objects. If none then use the current object
828: */
2.101 frystyk 829: HTHost_launchPending(net->host);
2.74 frystyk 830:
2.101 frystyk 831: return YES;
832: }
833: return NO;
834: }
2.89 frystyk 835:
2.101 frystyk 836: PRIVATE BOOL free_net (HTNet * net)
837: {
2.103 frystyk 838: HTTRACE(CORE_TRACE, "Net Object.. Freeing object %p\n" _ net);
2.101 frystyk 839: if (net) {
2.104 frystyk 840: if (net == HTRequest_net(net->request)) HTRequest_setNet(net->request, NULL);
2.101 frystyk 841: HT_FREE(net);
2.81 frystyk 842: return YES;
843: }
844: return NO;
845: }
846:
2.101 frystyk 847: /*
848: ** Unregister the net object from the global list
849: ** and see if we can start a new pending request.
850: */
851: PRIVATE BOOL unregister_net (HTNet * net)
2.81 frystyk 852: {
853: if (net && NetTable) {
854: HTList * list = NetTable[net->hash];
855: if (list) {
856: HTList_removeObject(list, (void *) net);
2.101 frystyk 857: check_pending(net);
2.81 frystyk 858: HTNetCount--;
859: return YES;
860: }
2.23 frystyk 861: }
862: return NO;
863: }
864:
2.74 frystyk 865: /*
866: ** Clears the contents of the Net object so that we can use it again.
867: */
868: PUBLIC BOOL HTNet_clear (HTNet * net)
869: {
870: if (net) {
2.81 frystyk 871: net->host->channel = NULL;
872: net->readStream = NULL;
873: net->bytesRead = 0;
2.95 frystyk 874: net->headerBytesRead = 0;
2.81 frystyk 875: net->bytesWritten = 0;
2.95 frystyk 876: net->headerBytesWritten = 0;
2.74 frystyk 877: return YES;
878: }
879: return NO;
880: }
881:
2.23 frystyk 882: /* HTNet_delete
883: ** ------------
884: ** Deletes the HTNet object from the list of active requests and calls
885: ** any registered call back functions IF not the status is HT_IGNORE.
886: ** This is used if we have internal requests that the app doesn't know
887: ** about. We also see if we have pending requests that can be started
888: ** up now when we have a socket free.
889: ** The callback functions are called in the reverse order of which they
890: ** were registered (last one first)
2.40 frystyk 891: ** Return YES if OK, else NO
2.23 frystyk 892: */
893: PUBLIC BOOL HTNet_delete (HTNet * net, int status)
894: {
2.103 frystyk 895: HTTRACE(CORE_TRACE, "Net Object.. Delete %p and call AFTER filters\n" _ net);
2.74 frystyk 896: if (net) {
897: HTRequest * request = net->request;
2.23 frystyk 898:
2.25 frystyk 899: /*
2.74 frystyk 900: ** If we have a premature close then recover the request. Otherwise
901: ** break the link to the Host object and continue deleting the net
902: ** object
2.25 frystyk 903: */
2.74 frystyk 904: if (net->host) {
2.81 frystyk 905: HTHost_unregister (net->host, net, HTEvent_READ);
906: HTHost_unregister (net->host, net, HTEvent_WRITE);
2.74 frystyk 907: if (status == HT_RECOVER_PIPE) {
908: HTNet_clear(net);
2.103 frystyk 909: HTTRACE(CORE_TRACE, "Net Object.. Restarting request %p (retry=%d) with net object %p\n" _
910: request _ HTRequest_retrys(request) _ net);
2.74 frystyk 911: return YES;
2.81 frystyk 912: }
2.97 frystyk 913: HTHost_deleteNet(net->host, net, status);
2.92 frystyk 914: if (HTHost_doRecover(net->host)) HTHost_recoverPipe(net->host);
2.89 frystyk 915: }
2.74 frystyk 916:
917: /* Remove object from the table of Net Objects */
2.101 frystyk 918: unregister_net(net);
2.102 frystyk 919: free_net(net);
2.82 frystyk 920:
2.74 frystyk 921: /* Call AFTER filters */
2.104 frystyk 922: if (status != HT_IGNORE) HTNet_executeAfterAll(request, status);
2.101 frystyk 923:
924: /*
925: ** Truely delete the HTNet object. Thanks to Mikhail Grouchinski
926: ** we now do this after having called the after filters so that
927: ** these filters can use the information in the Net object
928: */
929:
930: return YES;
2.23 frystyk 931: }
932: return NO;
2.98 frystyk 933: }
934:
935: PUBLIC BOOL HTNet_deleteDup (HTNet * dup)
936: {
2.101 frystyk 937: return dup ? (unregister_net(dup) && free_net(dup)) : NO;
2.23 frystyk 938: }
939:
940: /* HTNet_deleteAll
941: ** ---------------
942: ** Deletes all HTNet object that might either be active or pending
2.74 frystyk 943: ** We DO NOT call the AFTER filters - A crude way of saying goodbye!
2.23 frystyk 944: */
945: PUBLIC BOOL HTNet_deleteAll (void)
946: {
2.103 frystyk 947: HTTRACE(CORE_TRACE, "Net Object.. Remove all Net objects, NO filters\n");
2.74 frystyk 948: if (NetTable) {
949: HTList * cur = NULL;
950: HTNet * pres = NULL;
951: int cnt;
2.100 frystyk 952: for (cnt=0; cnt<HT_XL_HASH_SIZE; cnt++) {
2.74 frystyk 953: if ((cur = NetTable[cnt])) {
2.101 frystyk 954: while ((pres = (HTNet *) HTList_nextObject(cur)) != NULL) {
955: check_pending(pres);
956: free_net(pres);
957: }
2.74 frystyk 958: }
959: HTList_delete(NetTable[cnt]);
2.25 frystyk 960: }
2.74 frystyk 961: HT_FREE(NetTable);
962: HTNetCount = 0;
963: return YES;
2.25 frystyk 964: }
965: return NO;
2.97 frystyk 966: }
967:
968: /*
969: ** When pipelining, it is not possible to kill a single request
970: ** as we then loose track of where we are in the pipe. It is
971: ** therefore necessary to kill the whole pipeline.
972: */
973: PUBLIC BOOL HTNet_killPipe (HTNet * net)
974: {
975: return (net && net->host) ? HTHost_killPipe(net->host) : NO;
2.25 frystyk 976: }
977:
2.23 frystyk 978: /* HTNet_kill
979: ** ----------
980: ** Kill the request by calling the call back function with a request for
981: ** closing the connection. Does not remove the object. This is done by
982: ** HTNet_delete() function which is called by the load routine.
983: ** Returns OK if success, NO on error
984: */
2.74 frystyk 985: PUBLIC BOOL HTNet_kill (HTNet * net)
2.23 frystyk 986: {
2.81 frystyk 987: if (net) {
2.94 frystyk 988: HTAlertCallback * cbf = HTAlert_find(HT_PROG_INTERRUPT);
989: if (cbf) (*cbf)(net->request, HT_PROG_INTERRUPT, HT_MSG_NULL, NULL, NULL, NULL);
2.103 frystyk 990: HTTRACE(CORE_TRACE, "Net Object.. Killing %p\n" _ net);
2.81 frystyk 991: if (net->event.cbf) {
992: (*(net->event.cbf))(HTNet_socket(net), net->event.param, HTEvent_CLOSE);
993: return YES;
994: }
2.101 frystyk 995: return unregister_net(net) && free_net(net);
2.23 frystyk 996: }
2.103 frystyk 997: HTTRACE(CORE_TRACE, "Net Object.. No object to kill\n");
2.23 frystyk 998: return NO;
999: }
1000:
1001: /* HTNet_killAll
1002: ** -------------
2.74 frystyk 1003: ** Kills all registered net objects by calling the call
2.23 frystyk 1004: ** back function with a request for closing the connection. We do not
1005: ** remove the HTNet object as it is done by HTNet_delete().
1006: ** Returns OK if success, NO on error
1007: */
1008: PUBLIC BOOL HTNet_killAll (void)
1009: {
2.103 frystyk 1010: HTTRACE(CORE_TRACE, "Net Object.. Kill ALL Net objects!!!\n");
2.74 frystyk 1011: if (NetTable) {
1012: HTList * cur = NULL;
1013: HTNet * pres = NULL;
1014: int cnt;
2.100 frystyk 1015: for (cnt=0; cnt<HT_XL_HASH_SIZE; cnt++) {
2.74 frystyk 1016: if ((cur = NetTable[cnt])) {
2.105 kahan 1017: while ((pres = (HTNet *) HTList_lastObject(cur)) != NULL) {
1018: HTNet_kill(pres);
1019: cur = NetTable[cnt];
1020: }
2.74 frystyk 1021: }
2.25 frystyk 1022: }
2.74 frystyk 1023: return YES;
2.25 frystyk 1024: }
2.103 frystyk 1025: HTTRACE(CORE_TRACE, "Net Object.. No objects to kill\n");
2.74 frystyk 1026: return NO;
2.23 frystyk 1027: }
2.38 frystyk 1028:
1029: /* ------------------------------------------------------------------------- */
2.59 frystyk 1030: /* Connection Specifics */
1031: /* ------------------------------------------------------------------------- */
1032:
2.74 frystyk 1033: /* HTNet_priority
1034: ** --------------
1035: ** Get the current priority of the Net object
1036: */
1037: PUBLIC HTPriority HTNet_priority (HTNet * net)
1038: {
2.81 frystyk 1039: return (net ? net->event.priority : HT_PRIORITY_INV);
2.74 frystyk 1040: }
1041:
1042: /* HTNet_setPriority
1043: ** -----------------
1044: ** Set the current priority of the Net object
1045: ** This will change the priority next time the thread is blocked
1046: */
1047: PUBLIC BOOL HTNet_setPriority (HTNet * net, HTPriority priority)
1048: {
1049: if (net) {
2.81 frystyk 1050: net->event.priority = priority;
2.74 frystyk 1051: return YES;
1052: }
1053: return NO;
1054: }
1055:
2.59 frystyk 1056: /* HTNet_Persistent
1057: ** ----------------
1058: ** Check whether the net object handles persistent connections
1059: ** If we have a DNS entry then check that as well.
1060: */
1061: PUBLIC BOOL HTNet_persistent (HTNet * net)
1062: {
1063: return (net && HTHost_isPersistent(net->host));
1064: }
1065:
1066: /* HTNet_persistent
1067: ** ----------------
1068: ** Set the net object to handle persistent connections
1069: ** If we also have a DNS entry then update that as well
1070: */
2.74 frystyk 1071: PUBLIC BOOL HTNet_setPersistent (HTNet * net,
1072: BOOL persistent,
1073: HTTransportMode mode)
2.59 frystyk 1074: {
1075: if (net) {
2.81 frystyk 1076: BOOL result = HTHost_setPersistent(net->host, persistent, mode);
2.103 frystyk 1077: HTTRACE(CORE_TRACE, "Net Object.. Persistent connection set %s %s\n" _
1078: persistent ? "ON" : "OFF" _
2.74 frystyk 1079: result ? "succeeded" : "failed");
2.81 frystyk 1080: return result;
2.59 frystyk 1081: }
1082: return NO;
1083: }
1084:
2.66 frystyk 1085: /*
1086: ** Context pointer to be used in context call back function
1087: */
1088: PUBLIC BOOL HTNet_setContext (HTNet * net, void * context)
1089: {
1090: if (net) {
1091: net->context = context;
1092: return YES;
1093: }
1094: return NO;
1095: }
1096:
1097: PUBLIC void * HTNet_context (HTNet * net)
1098: {
1099: return net ? net->context : NULL;
1100: }
2.38 frystyk 1101:
1102: /*
2.60 frystyk 1103: ** Get and set the socket number
1104: */
1105: PUBLIC BOOL HTNet_setSocket (HTNet * net, SOCKET sockfd)
1106: {
2.81 frystyk 1107: if (net && net->host && net->host->channel) {
1108: HTChannel_setSocket(net->host->channel, sockfd);
2.60 frystyk 1109: return YES;
1110: }
1111: return NO;
1112: }
1113:
1114: PUBLIC SOCKET HTNet_socket (HTNet * net)
1115: {
2.81 frystyk 1116: return (net && net->host && net->host->channel ? HTChannel_socket(net->host->channel) : INVSOC);
2.69 frystyk 1117: }
1118:
1119: /*
1120: ** Get and set the HTRequest object
1121: */
1122: PUBLIC BOOL HTNet_setRequest (HTNet * net, HTRequest * request)
1123: {
1124: if (net && request) {
1125: net->request = request;
1126: return YES;
1127: }
1128: return NO;
1129: }
1130:
1131: PUBLIC HTRequest * HTNet_request (HTNet * net)
1132: {
1133: return (net ? net->request : NULL);
2.60 frystyk 1134: }
1135:
1136: /*
2.59 frystyk 1137: ** Get and set the HTChannel object
2.55 frystyk 1138: */
2.59 frystyk 1139: PUBLIC BOOL HTNet_setChannel (HTNet * net, HTChannel * channel)
2.55 frystyk 1140: {
2.81 frystyk 1141: return (net && channel) ? HTHost_setChannel(net->host, channel) : NO;
2.55 frystyk 1142: }
1143:
2.59 frystyk 1144: PUBLIC HTChannel * HTNet_channel (HTNet * net)
2.55 frystyk 1145: {
2.81 frystyk 1146: return net ? HTHost_channel(net->host) : NULL;
2.59 frystyk 1147: }
1148:
1149: /*
1150: ** Get and set the HTHost object
1151: */
1152: PUBLIC BOOL HTNet_setHost (HTNet * net, HTHost * host)
1153: {
1154: if (net && host) {
1155: net->host = host;
1156: return YES;
1157: }
1158: return NO;
1159: }
1160:
1161: PUBLIC HTHost * HTNet_host (HTNet * net)
1162: {
1163: return (net ? net->host : NULL);
1164: }
1165:
1166: /*
1167: ** Get and set the HTdns object
1168: */
1169: PUBLIC BOOL HTNet_setDns (HTNet * net, HTdns * dns)
1170: {
1171: if (net && dns) {
2.81 frystyk 1172: net->host->dns = dns;
2.59 frystyk 1173: return YES;
1174: }
1175: return NO;
1176: }
1177:
1178: PUBLIC HTdns * HTNet_dns (HTNet * net)
1179: {
2.81 frystyk 1180: return (net ? net->host->dns : NULL);
2.59 frystyk 1181: }
1182:
2.81 frystyk 1183: PUBLIC BOOL HTNet_setProtocol (HTNet * net, HTProtocol * protocol)
1184: {
1185: if (net && protocol) {
1186: net->protocol = protocol;
1187: return YES;
1188: }
1189: return NO;
1190: }
1191:
1192: PUBLIC HTProtocol * HTNet_protocol (HTNet * net)
2.72 frystyk 1193: {
2.81 frystyk 1194: return (net ? net->protocol : NULL);
2.72 frystyk 1195: }
2.59 frystyk 1196:
2.86 frystyk 1197: PUBLIC BOOL HTNet_setTransport (HTNet * net, HTTransport * tp)
1198: {
1199: if (net && tp) {
1200: net->transport = tp;
1201: return YES;
1202: }
1203: return NO;
1204: }
1205:
1206: PUBLIC HTTransport * HTNet_transport (HTNet * net)
1207: {
1208: return (net ? net->transport : NULL);
1209: }
1210:
1211: PUBLIC BOOL HTNet_preemptive (HTNet * net)
1212: {
1213: return (net ? net->preemptive : NO);
1214: }
1215:
2.59 frystyk 1216: /*
1217: ** Create the output stream and bind it to the channel
1218: ** Please read the description in the HTIOStream module on the parameters
1219: */
2.81 frystyk 1220: PUBLIC HTOutputStream * HTNet_getOutput (HTNet * me, void * param, int mode)
2.59 frystyk 1221: {
2.81 frystyk 1222: if (me && me->host && me->host->channel && me->transport) {
1223: HTTransport * tp = me->transport;
1224: HTChannel * ch = me->host->channel;
1225: HTOutputStream * output = (*tp->output_new)(me->host, ch, param, mode);
2.74 frystyk 1226: HTChannel_setOutput(ch, output);
2.59 frystyk 1227: return output;
1228: }
2.103 frystyk 1229: HTTRACE(CORE_TRACE, "Host Object.. Can't create output stream\n");
2.59 frystyk 1230: return NULL;
2.81 frystyk 1231: }
1232:
2.87 frystyk 1233: PUBLIC HTEvent * HTNet_event (HTNet * net)
2.81 frystyk 1234: {
2.87 frystyk 1235: return net ? &net->event : NULL;
1236: }
1237:
1238: PUBLIC BOOL HTNet_setEventParam (HTNet * net, void * eventParam)
1239: {
2.81 frystyk 1240: if (net) return HTEvent_setParam(&net->event, eventParam);
1241: return NO;
1242: }
1243:
2.87 frystyk 1244: PUBLIC void * HTNet_eventParam (HTNet * net)
2.81 frystyk 1245: {
2.87 frystyk 1246: return net ? net->event.param : NULL;
2.81 frystyk 1247: }
1248:
1249: PUBLIC BOOL HTNet_setEventCallback(HTNet * net, HTEventCallback * cbf)
1250: {
1251: if (net) return HTEvent_setCallback(&net->event, cbf);
1252: return NO;
1253: }
1254:
1255: PUBLIC HTEventCallback * HTNet_eventCallback(HTNet * net)
1256: {
1257: return net->event.cbf;
1258: }
1259:
1260: PUBLIC BOOL HTNet_setEventPriority(HTNet * net, HTPriority priority)
1261: {
1262: if (net) return HTEvent_setPriority(&net->event, priority);
1263: return NO;
1264: }
1265:
1266: PUBLIC HTPriority HTNet_eventPriority(HTNet * net)
1267: {
1268: return net->event.priority;
1269: }
1270:
1271: PUBLIC HTStream * HTNet_readStream(HTNet * net)
1272: {
1273: if (!net) return NULL;
1274: return net->readStream;
1275: }
1276:
1277: PUBLIC BOOL HTNet_setReadStream (HTNet * net, HTStream * stream)
1278: {
1279: if (net) {
1280: net->readStream = stream;
1281: return YES;
1282: }
1283: return NO;
2.96 frystyk 1284: }
1285:
1286: /*
1287: ** Should we do raw byte count at the network or later?
1288: ** Normally it is later but in cases like FTP we need it
1289: ** in the raw form
1290: */
1291: PUBLIC BOOL HTNet_setRawBytesCount (HTNet * net, BOOL mode)
1292: {
1293: if (net) {
1294: net->countRawBytes = mode;
1295: return YES;
1296: }
1297: return NO;
1298: }
1299:
1300: PUBLIC BOOL HTNet_rawBytesCount (HTNet * net)
1301: {
1302: return (net && net->countRawBytes);
2.55 frystyk 1303: }
Webmaster