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