📄 htnet.c
字号:
/* HTNet.c** HTNet Class**** (c) COPYRIGHT MIT 1995.** Please first read the full copyright statement in the file COPYRIGH.** @(#) $Id: HTNet.c,v 2.103 1999/02/22 22:10:11 frystyk Exp $**** This is the implementation of the internal library multithreading** functions. This includes an interrupt handler and a event loop.** ** History:** 12 June 94 Written by Henrik Frystyk, frystyk@w3.org** 31 May 95 Charlie Brooks cbrooks@osf.org***//* Implemention dependent include files */#include "wwwsys.h"/* Library include files */#include "WWWUtil.h"#include "HTProt.h"#include "HTError.h"#include "HTAlert.h"#include "HTParse.h"#include "HTTrans.h"#include "HTHost.h"#include "HTReq.h"#include "HTEvent.h"#include "HTStream.h"#include "HTHstMan.h"#include "HTIOStream.h"#include "HTNetMan.h" /* Implemented here */#ifndef HT_MAX_SOCKETS#define HT_MAX_SOCKETS 25#endiftypedef struct _BeforeFilter { HTNetBefore * before; /* Filter function */ char * tmplate; /* URL template for when to call filter */ int order; /* Relative execution order */ void * param; /* Local context */} BeforeFilter;typedef struct _AfterFilter { HTNetAfter * after; /* Filter function */ char * tmplate; /* URL template for when to call filter */ int order; /* Relative execution order */ void * param; /* Local context */ int status; /* Status of load for when to call filter */} AfterFilter;struct _HTStream { const HTStreamClass * isa; /* ... */};struct _HTInputStream { const HTInputStreamClass * isa; /* ... */};typedef struct _HTFilterEvent { HTRequest * request; int status; HTTimer * timer;} HTFilterEvent;PRIVATE HTList * HTBefore = NULL; /* List of global BEFORE filters */PRIVATE HTList * HTAfter = NULL; /* List of global AFTER filters */PRIVATE int MaxActive = HT_MAX_SOCKETS; /* Max active requests */PRIVATE int Active = 0; /* Counts open sockets */PRIVATE int Persistent = 0; /* Counts persistent sockets */PRIVATE HTList ** NetTable = NULL; /* List of net objects */PRIVATE int HTNetCount = 0; /* Counting elements in table *//* ------------------------------------------------------------------------- *//* GENERIC BEFORE and AFTER filter Management *//* ------------------------------------------------------------------------- */PRIVATE int HTBeforeOrder (const void * a, const void * b){ return ((BeforeFilter *) b)->order - ((BeforeFilter *) a)->order;}PRIVATE int HTAfterOrder (const void * a, const void * b){ return ((AfterFilter *) b)->order - ((AfterFilter *) a)->order;}PRIVATE int check_order (HTFilterOrder order){ return (order<HT_FILTER_FIRST) ? HT_FILTER_FIRST : (order>HT_FILTER_LAST) ? HT_FILTER_LAST : order;}/*** Register a BEFORE filter in the list provided by the caller.** Several filters can be registered in which case they are called** with the filter ordering in mind.*/PUBLIC BOOL HTNetCall_addBefore (HTList * list, HTNetBefore * before, const char * tmplate, void * param, HTFilterOrder order){ if (list && before) { BeforeFilter * me; if ((me = (BeforeFilter *) HT_CALLOC(1, sizeof(BeforeFilter)))==NULL) HT_OUTOFMEM("HTNetCall_addBefore"); me->before = before; if (tmplate) StrAllocCopy(me->tmplate, tmplate); me->order = check_order(order); me->param = param; HTTRACE(CORE_TRACE, "Net Before.. Add %p with order %d tmplate `%s\' context %p\n" _ before _ me->order _ tmplate ? tmplate : "<null>" _ param); return (HTList_addObject(list, me) && HTList_insertionSort(list, HTBeforeOrder)); } return NO;}/*** Unregister all instances of a BEFORE filter from a list.*/PUBLIC BOOL HTNetCall_deleteBefore (HTList * list, HTNetBefore * before){ HTTRACE(CORE_TRACE, "Net Before.. Delete %p\n" _ before); if (list && before) { HTList * cur = list; BeforeFilter * pres; while ((pres = (BeforeFilter *) HTList_nextObject(cur))) { if (pres->before == before) { HTList_removeObject(list, (void *) pres); HT_FREE(pres->tmplate); HT_FREE(pres); cur = list; } } } return NO;}/*** Deletes all BEFORE filters in list*/PUBLIC BOOL HTNetCall_deleteBeforeAll (HTList * list){ HTTRACE(CORE_TRACE, "Net Before. Delete All filters\n"); if (list) { HTList * cur = list; BeforeFilter * pres; while ((pres = (BeforeFilter *) HTList_nextObject(cur))) { HT_FREE(pres->tmplate); HT_FREE(pres); } HTList_delete(list); return YES; } return NO;}/*** Call all the BEFORE filters in the order specified at registration** time. We also check for any template and whether it matches or not. ** If a filter returns other than HT_OK then stop and return immediately.** Otherwise return what the last filter returns.*/PUBLIC int HTNetCall_executeBefore (HTList * list, HTRequest * request){ HTParentAnchor * anchor = HTRequest_anchor(request); char * url = HTAnchor_physical(anchor); char * addr = url ? url : HTAnchor_address((HTAnchor *) anchor); int ret = HT_OK; int mode = 0; if (list && request && addr) { BeforeFilter * pres; while ((pres = (BeforeFilter *) HTList_nextObject(list))) { if (!pres->tmplate || (pres->tmplate && HTStrMatch(pres->tmplate, addr))) { HTTRACE(CORE_TRACE, "Net Before.. calling %p (request %p, context %p)\n" _ pres->before _ request _ pres->param); ret = (*pres->before)(request, pres->param, mode); if (ret != HT_OK) break; /* ** Update the address to match against if the filter changed ** the physical address. */ if ((url = HTAnchor_physical(anchor))) addr = url; } } } if (!url) HT_FREE(addr); return ret;}/*** Register a AFTER filter in the list provided by the caller.** Several filters can be registered in which case they are called** with the filter ordering in mind.*/PUBLIC BOOL HTNetCall_addAfter (HTList * list, HTNetAfter * after, const char * tmplate, void * param, int status, HTFilterOrder order){ if (list && after) { AfterFilter * me; if ((me = (AfterFilter *) HT_CALLOC(1, sizeof(AfterFilter)))==NULL) HT_OUTOFMEM("HTNetCall_addAfter"); me->after = after; if (tmplate) StrAllocCopy(me->tmplate, tmplate); me->order = check_order(order); me->param = param; me->status = status; HTTRACE(CORE_TRACE, "Net After... Add %p with order %d tmplate `%s\' code %d context %p\n" _ after _ me->order _ tmplate ? tmplate : "<null>" _ status _ param); return (HTList_addObject(list, me) && HTList_insertionSort(list, HTAfterOrder)); } return NO;}/*** Unregister all instances of an AFTER filter from a list.*/PUBLIC BOOL HTNetCall_deleteAfter (HTList * list, HTNetAfter * after){ HTTRACE(CORE_TRACE, "Net After... Delete %p\n" _ after); if (list && after) { HTList * cur = list; AfterFilter * pres; while ((pres = (AfterFilter *) HTList_nextObject(cur))) { if (pres->after == after) { HTList_removeObject(list, (void *) pres); HT_FREE(pres->tmplate); HT_FREE(pres); cur = list; } } } return NO;}/*** Unregister all filters registered for a given status.*/PUBLIC BOOL HTNetCall_deleteAfterStatus (HTList * list, int status){ HTTRACE(CORE_TRACE, "Net After... Delete all with status %d\n" _ status); if (list) { HTList * cur = list; AfterFilter * pres; while ((pres = (AfterFilter *) HTList_nextObject(cur))) { if (pres->status == status) { HTList_removeObject(list, (void *) pres); HT_FREE(pres->tmplate); HT_FREE(pres); cur = list; } } return YES; } return NO;}/*** Deletes all AFTER filters in list*/PUBLIC BOOL HTNetCall_deleteAfterAll (HTList * list){ HTTRACE(CORE_TRACE, "Net After. Delete All filters\n"); if (list) { HTList * cur = list; AfterFilter * pres; while ((pres = (AfterFilter *) HTList_nextObject(cur))) { HT_FREE(pres->tmplate); HT_FREE(pres); } HTList_delete(list); return YES; } return NO;}/*** Call all the AFTER filters in the order specified at registration** time and if it has the right status code and it's not HT_IGNORE.** We also check for any template and whether it matches or not.** If a filter returns other than HT_OK then stop and return immediately.** Otherwise return what the last filter returns.*/PUBLIC int HTNetCall_executeAfter (HTList * list, HTRequest * request, int status){ int ret = HT_OK; if (status != HT_IGNORE) { HTParentAnchor * anchor = HTRequest_anchor(request); char * url = HTAnchor_physical(anchor); char * addr = url ? url : HTAnchor_address((HTAnchor *) anchor); HTResponse * response = HTRequest_response(request); if (list && request && addr) { AfterFilter * pres; while ((pres = (AfterFilter *) HTList_nextObject(list))) { if ((pres->status == status || pres->status == HT_ALL) && (!pres->tmplate || (pres->tmplate && HTStrMatch(pres->tmplate, addr)))) { HTTRACE(CORE_TRACE, "Net After... calling %p (request %p, response %p, status %d, context %p)\n" _ pres->after _ request _ response _ status _ pres->param); ret = (*pres->after)(request, response, pres->param, status); if (ret != HT_OK) break; /* ** Update the address to match against if the filter changed ** the physical address. */ if ((url = HTAnchor_physical(anchor))) addr = url; } } } if (!url) HT_FREE(addr); } return ret;}/* ------------------------------------------------------------------------- *//* GLOBAL BEFORE and AFTER filter Management *//* ------------------------------------------------------------------------- *//*** Global set of callback functions BEFORE the request is issued** list can be NULL*/PUBLIC BOOL HTNet_setBefore (HTList *list){ HTBefore = list; return YES;}PUBLIC HTList * HTNet_before (void){ return HTBefore;}PUBLIC BOOL HTNet_addBefore (HTNetBefore * before, const char * tmplate, void * param, HTFilterOrder order){ if (!HTBefore) HTBefore = HTList_new(); return HTNetCall_addBefore(HTBefore, before, tmplate, param, order);}PUBLIC BOOL HTNet_deleteBefore (HTNetBefore * cbf){ return HTNetCall_deleteBefore(HTBefore, cbf);}/*** Call both the local and the global BEFORE filters (if any)*/PUBLIC int HTNet_executeBeforeAll (HTRequest * request){ int ret; BOOL override = NO; HTList * befores; if ((befores = HTRequest_before(request, &override))) { if ((ret = HTNetCall_executeBefore(befores, request)) != HT_OK) return ret; } return override ? HT_OK : HTNetCall_executeBefore(HTBefore, request);}/*** Global set of callback functions AFTER the request is issued** list can be NULL*/PUBLIC BOOL HTNet_setAfter (HTList *list){ HTAfter = list; return YES;}PUBLIC HTList * HTNet_after (void){ return HTAfter;}PUBLIC BOOL HTNet_addAfter (HTNetAfter * after, const char * tmplate, void * param, int status, HTFilterOrder order){ if (!HTAfter) HTAfter = HTList_new(); return HTNetCall_addAfter(HTAfter, after, tmplate, param, status, order);}PUBLIC BOOL HTNet_deleteAfter (HTNetAfter * cbf){ return HTNetCall_deleteAfter(HTAfter, cbf);}PUBLIC BOOL HTNet_deleteAfterStatus (int status){ return HTNetCall_deleteAfterStatus(HTAfter, status);}/*** Call both the local and the global AFTER filters (if any)*/PUBLIC int HTNet_executeAfterAll (HTRequest * request, int status){ int ret; BOOL override = NO; HTList * afters; if ((afters = HTRequest_after(request, &override))) { if ((ret = HTNetCall_executeAfter(afters, request, status)) != HT_OK) return ret; } return override ? HT_OK : HTNetCall_executeAfter(HTAfter, request, status);}/* ------------------------------------------------------------------------- *//* Socket Management *//* ------------------------------------------------------------------------- */PUBLIC int HTNet_maxSocket (void){ return MaxActive;}PUBLIC BOOL HTNet_setMaxSocket (int newmax){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -