⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hthost.c

📁 www工具包. 这是W3C官方支持的www支撑库. 其中提供通用目的的客户端的WebAPI: complete HTTP/1.1 (with caching, pipelining, PUT, POS
💻 C
📖 第 1 页 / 共 4 页
字号:
PUBLIC int HTHost_listen (HTHost * host, HTNet * net, char * url){    HTRequest * request = HTNet_request(net);    int status = HT_OK;    if (!host) {	HTProtocol * protocol = HTNet_protocol(net);	if ((host = HTHost_newWParse(request, url, HTProtocol_id(protocol))) == NULL)	    return HT_ERROR;	/*	** If not already locked and without a channel	** then lock the darn thing with the first Net object	** pending.	*/	if (!host->lock && !host->channel) {	    host->forceWriteFlush = YES;	    host->lock = net;	}	HTNet_setHost(net, host);    }    /*    ** See if we already have a dedicated listen Net object. If not     ** then create one.    */    if (!host->listening) host->listening = HTNet_new(host);    /*    ** Start listening on the Net object    */    status = HTDoListen(host->listening, net, HT_BACKLOG);    if (status != HT_OK) {	HTTRACE(CORE_TRACE, "Host listen. On Host %p resulted in %d\n" _ host _ status);	return status;    }    return HT_OK;}PUBLIC int HTHost_accept (HTHost * host, HTNet * net, char * url){    int status = HT_OK;    if (!host || !host->listening) {	HTTRACE(CORE_TRACE, "Host accept. No host object or not listening on anything\n");	return HT_ERROR;    }    if (!host->lock || (host->lock && host->lock == net)) {	status = HTDoAccept(host->listening, net);	if (status == HT_PENDING)	    return HT_WOULD_BLOCK;	else if (status == HT_WOULD_BLOCK) {	    host->lock = net;	    return status;	} else {	    /*	    **  See if there is already a new pending request that should	    **  take over the current lock	    */	    HTNet * next_pending = NULL;	    if ((next_pending = HTList_firstObject(host->pending))) {		HTTRACE(CORE_TRACE, "Host connect Changing lock on Host %p to %p\n" _ 			host _ next_pending);		host->lock = next_pending;	    	    } else {		HTTRACE(CORE_TRACE, "Host connect Unlocking Host %p\n" _ host);		host->lock = NULL;	    	    }	    return status;	}    } else {	HTTRACE(CORE_TRACE, "Host connect Host %p already locked with %p\n" _ host _ host->lock);	if ((status = HTHost_addNet(host, net)) == HT_PENDING) {	    return HT_PENDING;	}    }    return HT_ERROR;}/***	Rules: SINGLE: one element in pipe, either reading or writing**		 PIPE: n element in pipe, n-1 reading, 1 writing*/PUBLIC int HTHost_register (HTHost * host, HTNet * net, HTEventType type){  HTEvent *event;    if (host && net) {	if (type == HTEvent_CLOSE) {	    /*	    **  Unregister this host for all events	    */	    HTEvent_unregister(HTChannel_socket(host->channel), HTEvent_READ);	    HTEvent_unregister(HTChannel_socket(host->channel), HTEvent_WRITE);	    host->registeredFor = 0;	    return YES;	} else {	    /* net object may already be registered */	    if (HTEvent_BITS(type) & net->registeredFor)		return NO;	    net->registeredFor ^= HTEvent_BITS(type);	    /* host object may already be registered */	    if (host->registeredFor & HTEvent_BITS(type))		return YES;	    host->registeredFor ^= HTEvent_BITS(type);#ifdef WWW_WIN_ASYNC            /* Make sure we are registered for CLOSE on windows */	    event =  *(host->events+HTEvent_INDEX(HTEvent_CLOSE));	    HTEvent_register(HTChannel_socket(host->channel), HTEvent_CLOSE, event);#endif /* WWW_WIN_ASYNC */                        /* JK:  register a request in the event structure */	    event =  *(host->events+HTEvent_INDEX(type));	    event->request = HTNet_request (net);	    return HTEvent_register(HTChannel_socket(host->channel),				    type, event);	}	return YES;    }    HTTRACE(CORE_TRACE, "HTHost...... Don't register event with bad arguments\n");    return NO;}PUBLIC int HTHost_unregister (HTHost * host, HTNet * net, HTEventType type){    if (host && net) {	/* net object may not be registered */	if (!(HTEvent_BITS(type) & net->registeredFor))	    return NO;	net->registeredFor ^= HTEvent_BITS(type);	/* host object may not be registered */	if (!(host->registeredFor & HTEvent_BITS(type)))	    return YES;	host->registeredFor ^= HTEvent_BITS(type);	/* stay registered for READ to catch a socket close */	/* WRITE and CONNECT can be unregistered, though */	if ((type == HTEvent_WRITE && isLastInPipe(host, net)) || 	    type == HTEvent_CONNECT)	    /* if we are blocked downstream, shut down the whole pipe */	    HTEvent_unregister(HTChannel_socket(host->channel), type);	return YES;    }    return NO;}/***	The reader tells HostEvent that it's stream did not finish the data*/PUBLIC BOOL HTHost_setRemainingRead (HTHost * host, size_t remaining){    if (host == NULL) return NO;    host->remainingRead = remaining;    HTTRACE(PROT_TRACE, "Host........ %d bytes remaining \n" _ remaining);    if (host->broken_pipe && remaining == 0) {	HTTRACE(PROT_TRACE, "Host........ Emtied out connection\n");    }    return YES;}PUBLIC size_t HTHost_remainingRead (HTHost * host){    return host ? host->remainingRead : -1;}PUBLIC SockA * HTHost_getSockAddr (HTHost * host){    if (!host) return NULL;    return &host->sock_addr;}PUBLIC BOOL HTHost_setHome (HTHost * host, int home){    if (!host) return NO;    host->home = home;    return YES;}PUBLIC int HTHost_home (HTHost * host){    if (!host) return 0;    return host->home;}PUBLIC BOOL HTHost_setRetry (HTHost * host, int retry){    if (!host) return NO;    host->retry = retry;    return YES;}PUBLIC BOOL HTHost_decreaseRetry (HTHost * host){    if (!host) return NO;    if (host->retry > 0) host->retry--;    return YES;}PUBLIC int HTHost_retry (HTHost * host){    if (!host) return 0;    return host->retry;}#if 0	/* Is a macro right now */PRIVATE BOOL HTHost_setDNS5 (HTHost * host, HTdns * dns){    if (!host) return NO;    host->dns = dns;    return YES;}#endifPUBLIC BOOL HTHost_setChannel (HTHost * host, HTChannel * channel){    if (!host) return NO;    host->channel = channel;    return YES;}PUBLIC HTNet * HTHost_getReadNet(HTHost * host){    return host ? (HTNet *) HTList_firstObject(host->pipeline) : NULL;}PUBLIC HTNet * HTHost_getWriteNet(HTHost * host){    return host ? (HTNet *) HTList_lastObject(host->pipeline) : NULL;}/***	Create the input stream and bind it to the channel**	Please read the description in the HTIOStream module for the parameters*/PUBLIC HTInputStream * HTHost_getInput (HTHost * host, HTTransport * tp,					void * param, int mode){    if (host && host->channel && tp) {	HTChannel * ch = host->channel;	HTInputStream * input = (*tp->input_new)(host, ch, param, mode);	HTChannel_setInput(ch, input);	return HTChannel_getChannelIStream(ch);    }    HTTRACE(CORE_TRACE, "Host Object. Can't create input stream\n");    return NULL;}PUBLIC HTOutputStream * HTHost_getOutput (HTHost * host, HTTransport * tp,					  void * param, int mode){    if (host && host->channel && tp) {	HTChannel * ch = host->channel;	HTOutputStream * output = (*tp->output_new)(host, ch, param, mode);	HTChannel_setOutput(ch, output);	return output;    }    HTTRACE(CORE_TRACE, "Host Object. Can't create output stream\n");    return NULL;}PUBLIC HTOutputStream * HTHost_output (HTHost * host, HTNet * net){    if (host && host->channel && net) {	HTOutputStream * output = HTChannel_output(host->channel);	return output;    }    return NULL;}PUBLIC int HTHost_read(HTHost * host, HTNet * net){    HTInputStream * input = HTChannel_input(host->channel);    if (net != HTHost_getReadNet(host)) {	HTHost_register(host, net, HTEvent_READ);	return HT_WOULD_BLOCK;    }    /*    **  If there is no input channel then this can either mean that    **  we have lost the channel or an error occurred. We return    **  HT_CLOSED as this is a sign to the caller that we don't     **  have a channel    */    return input ? (*input->isa->read)(input) : HT_CLOSED;}PUBLIC BOOL HTHost_setConsumed(HTHost * host, size_t bytes){    HTInputStream * input;    if (!host || !host->channel) return NO;    if ((input = HTChannel_input(host->channel)) == NULL)	return NO;    HTTRACE(CORE_TRACE, "Host........ passing %d bytes as consumed to %p\n" _ bytes _ input);    return (*input->isa->consumed)(input, bytes);}PUBLIC int HTHost_hash (HTHost * host){    return host ? host->hash : -1;}PUBLIC BOOL HTHost_setWriteDelay (HTHost * host, ms_t delay){    if (host && delay >= 0) {	host->delay = delay;	return YES;    }    return NO;}PUBLIC ms_t HTHost_writeDelay (HTHost * host){    return host ? host->delay : 0;}PUBLIC int HTHost_findWriteDelay (HTHost * host, ms_t lastFlushTime, int buffSize){#if 0    unsigned short mtu;    int ret = -1;    int socket = HTChannel_socket(host->channel);#ifndef WWW_MSWINDOWS    ret = ioctl(socket, 666, (unsigned long)&mtu);#endif /* WWW_MSWINDOWS */    if ((ret == 0 && buffSize >= mtu) || host->forceWriteFlush)	return 0;    return host->delay;#else    return host->forceWriteFlush ? 0 : host->delay;#endif}PUBLIC BOOL HTHost_setDefaultWriteDelay (ms_t delay){    if (delay >= 0) {	WriteDelay = delay;	HTTRACE(CORE_TRACE, "Host........ Default write delay is %d ms\n" _ delay);	return YES;    }    return NO;}PUBLIC ms_t HTHost_defaultWriteDelay (void){    return WriteDelay;}PUBLIC int HTHost_forceFlush(HTHost * host){    HTNet * targetNet = (HTNet *) HTList_lastObject(host->pipeline);    int ret;    if (targetNet == NULL) return HT_ERROR;    /* 2000/28/07 JK: The following test was proposed by Heiner Kallweit, as there's a problem    ** while using SSL because of a recursive call to this function. We tested the    ** fix and it doesn't seem to introduce any side effects... but one never knows,    ** thus this comment. This seems more like a bug in the SSL code than here.    */    if (host->inFlush) {	HTTRACE(CORE_TRACE, "Host Event.. FLUSH requested for  `%s\'\n, but ignoring it as we're already processing a flush in this host" _ 		HTAnchor_physical(HTRequest_anchor(HTNet_request(targetNet))));	return HT_OK;    }    HTTRACE(CORE_TRACE, "Host Event.. FLUSH passed to `%s\'\n" _ 		HTAnchor_physical(HTRequest_anchor(HTNet_request(targetNet))));    host->forceWriteFlush = YES;    host->inFlush = YES;    ret = (*targetNet->event.cbf)(HTChannel_socket(host->channel), targetNet->event.param, HTEvent_FLUSH);    host->forceWriteFlush = NO;    host->inFlush = NO;    return ret;}/*** Context pointer to be used as a user defined context */PUBLIC void HTHost_setContext (HTHost * me, void * context){  if (me) me->context = context;}PUBLIC void * HTHost_context (HTHost * me){  return me ? me->context : NULL;}PUBLIC int HTHost_eventTimeout (void){    return EventTimeout;}PUBLIC void HTHost_setEventTimeout (int millis){    EventTimeout = millis;    HTTRACE(CORE_TRACE, "Host........ Setting event timeout to %d ms\n" _ millis);}PUBLIC BOOL HTHost_setMaxPipelinedRequests (int max){    if (max > 1) {	MaxPipelinedRequests = max;	return YES;    }    return NO;}PUBLIC int HTHost_maxPipelinedRequests (void){    return MaxPipelinedRequests;}PUBLIC void HTHost_setActivateRequestCallback (HTHost_ActivateRequestCallback * cbf){    HTTRACE(CORE_TRACE, "HTHost...... Registering %p\n" _ cbf);    ActivateReqCBF = cbf;}PRIVATE int HTHost_ActivateRequest (HTNet * net){    HTRequest * request = NULL;    if (!ActivateReqCBF) {	HTTRACE(CORE_TRACE, "HTHost...... No ActivateRequest callback handler registered\n");	return HT_ERROR;    }    request = HTNet_request(net);    return (*ActivateReqCBF)(request);}PUBLIC void HTHost_disable_PendingReqLaunch (void){    DoPendingReqLaunch = NO;}PUBLIC void HTHost_enable_PendingReqLaunch (void){    DoPendingReqLaunch = YES;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -