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

📄 ilibwebclient.c

📁 intel upnp stack source code
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * INTEL CONFIDENTIAL * Copyright (c) 2002, 2003 Intel Corporation.  All rights reserved. *  * The source code contained or described herein and all documents * related to the source code ("Material") are owned by Intel * Corporation or its suppliers or licensors.  Title to the * Material remains with Intel Corporation or its suppliers and * licensors.  The Material contains trade secrets and proprietary * and confidential information of Intel or its suppliers and * licensors. The Material is protected by worldwide copyright and * trade secret laws and treaty provisions.  No part of the Material * may be used, copied, reproduced, modified, published, uploaded, * posted, transmitted, distributed, or disclosed in any way without * Intel's prior express written permission.  * No license under any patent, copyright, trade secret or other * intellectual property right is granted to or conferred upon you * by disclosure or delivery of the Materials, either expressly, by * implication, inducement, estoppel or otherwise. Any license * under such intellectual property rights must be express and * approved by Intel in writing. *  * $Workfile: ILibWebClient.c * $Revision: #1.0.1799.42459 * $Author:   Intel Corporation, Intel Device Builder * $Date:     Wednesday, January 19, 2005 * * * */#ifdef MEMORY_CHECK	#include <assert.h>	#define MEMCHECK(x) x#else	#define MEMCHECK(x)#endif#if defined(_WIN32_WCE)	#define _CRTDBG_MAP_ALLOC	#include <math.h>	#include <winerror.h>	#include <stdlib.h>	#include <stdio.h>	#include <stddef.h>	#include <string.h>	#include <winsock.h>	#include <wininet.h>	#include <windows.h>	#include <winioctl.h>	#include <winbase.h>#elif defined(WIN32)	#define _CRTDBG_MAP_ALLOC	#include <math.h>	#include <winerror.h>	#include <stdlib.h>	#include <stdio.h>	#include <stddef.h>	#include <string.h>	#ifdef WINSOCK2		#include <winsock2.h>		#include <ws2tcpip.h>	#else		#include <winsock.h>		#include <wininet.h>	#endif	#include <windows.h>	#include <winioctl.h>	#include <winbase.h>	#include <crtdbg.h>#elif defined(_POSIX)	#include <stdio.h>	#include <stdlib.h>	#include <sys/types.h>	#include <sys/socket.h>	#include <netinet/in.h>	#include <arpa/inet.h>	#include <sys/time.h>	#include <netdb.h>	#include <string.h>	#include <sys/ioctl.h>	#include <net/if.h>	#include <sys/utsname.h>	#include <sys/socket.h>	#include <netinet/in.h>	#include <unistd.h>	#include <fcntl.h>	#include <errno.h>#endif#if defined(WIN32)	#define strncasecmp(x,y,z) _strnicmp(x,y,z)#elif defined(_WIN32_WCE)	#define strncasecmp(x,y,z) _strnicmp(x,y,z)#else	#include <semaphore.h>#endif#ifdef SEMAPHORE_TRACKING#define SEM_TRACK(x) xvoid WebClient_TrackLock(const char* MethodName, int Occurance, void *data){	char v[100];	sprintf(v,"  LOCK[%s, %d] (%x)\r\n",MethodName,Occurance,data);#ifdef WIN32	OutputDebugString(v);#else	printf(v);#endif}void WebClient_TrackUnLock(const char* MethodName, int Occurance, void *data){	char v[100];	sprintf(v,"UNLOCK[%s, %d] (%x)\r\n",MethodName,Occurance,data);#ifdef WIN32	OutputDebugString(v);#else	printf(v);#endif}#else#define SEM_TRACK(x)#endif#include <memory.h>#include <math.h>#include "ILibParsers.h"#include "ILibWebClient.h"#include "ILibAsyncSocket.h"//// We keep a table of all the connections. This is the maximum number allowed to be// idle. Since we have in the constructor a pool size, this feature may be depracted.// ToDo: Look into depracating this//#define MAX_IDLE_SESSIONS 20//// This is the number of seconds that a connection must be idle for, before it will// be automatically closed. Idle means there are no pending requests//#define HTTP_SESSION_IDLE_TIMEOUT 3//// This is the number of times, an HTTP connection will be attempted, before it fails.// This module utilizes an exponential backoff algorithm. That is, it will retry immediately,// then it will retry after 1 second, then 2, then 4, etc.//#define HTTP_CONNECT_RETRY_COUNT 4//// This initial size of the receive buffer//#define INITIAL_BUFFER_SIZE 2048//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}//// This means the module doesn't know yet if the server supports persistent connections//#define PIPELINE_UNKNOWN 0//// The server does indeed support persistent connections//#define PIPELINE_YES 1//// The server does not support persistent connections//#define PIPELINE_NO 2//// Chunk processing flags//#define STARTCHUNK 0#define ENDCHUNK 1#define DATACHUNK 2#define FOOTERCHUNK 3//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}struct ILibWebRequest{	char **Buffer;	int *BufferLength;	int *UserFree;	int NumberOfBuffers;	struct sockaddr_in remote;	void *user1,*user2;	void (*OnResponse)(				void *WebReaderToken,				int InterruptFlag,				struct packetheader *header,				char *bodyBuffer,				int *beginPointer,				int endPointer,				int done,				void *user1,				void *user2,				int *PAUSE);};struct ILibWebClientManager{	void (*PreSelect)(void* object,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime);	void (*PostSelect)(void* object,int slct, fd_set *readset, fd_set *writeset, fd_set *errorset);	void (*Destroy)(void* object);	void **socks;	int socksLength;	void *DataTable;	void *idleTable;	void *backlogQueue;	void *timer;	int idleCount;	void *Chain;};//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}struct ILibWebClient_ChunkData{	int Flag;	char *buffer;	int offset;	int mallocSize;	int bytesLeft;};//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}struct ILibWebClientDataObject{	int PipelineFlag;	int ActivityCounter;	struct sockaddr_in remote;	struct ILibWebClientManager *Parent;	int FinHeader;	int Chunked;//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}	struct ILibWebClient_ChunkData *chunk;	int ConnectionCloseSpecified;//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}	int BytesLeft;	int WaitForClose;	int Closing;	int Server;	int DisconnectSent;	int HeaderLength;	int ExponentialBackoff;	struct packetheader *header;	int InitialRequestAnswered;	void* RequestQueue;	void *SOCK;	int LocalIP;	int PAUSE;};/// <summary>/// Internal method used to free resources associated with a WebClientDataObject/// </summary>/// <param name="token">The WebClientDataObject to free</param>void ILibWebClient_DestroyWebClientDataObject(void *token){	struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)token;	struct ILibWebRequest *wr;	int i;	int zero=0;	if(wcdo==NULL) {return;}	if(wcdo->Closing<0) 	{		//		// This connection is already in the process of closing somewhere, so we can just exit		//		return;	}	if(wcdo->SOCK!=NULL && ILibAsyncSocket_IsFree(wcdo->SOCK)==0)	{		//		// This connection needs to be disconnected first		//		wcdo->Closing = -1;		ILibAsyncSocket_Disconnect(wcdo->SOCK);	}		if(wcdo->header!=NULL)		{			//			// The header needs to be freed			//			ILibDestructPacket(wcdo->header);			wcdo->header = NULL;		}//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}		if(wcdo->chunk!=NULL)		{			//			// The resources associated with the Chunk Processing needs to be freed			//			if(wcdo->chunk->buffer!=NULL) {free(wcdo->chunk->buffer);}			free(wcdo->chunk);			wcdo->chunk = NULL;		}//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}		//		// Iterate through all the pending requests		//		wr = ILibQueue_DeQueue(wcdo->RequestQueue);		while(wr!=NULL)		{			for(i=0;i<wr->NumberOfBuffers;++i)			{				//				// If we own the memory, we need to free it				//				if(wr->UserFree[i]==0) {free(wr->Buffer[i]);}			}			free(wr->Buffer);			free(wr->BufferLength);			free(wr->UserFree);			if(wcdo->Server==0 && wr->OnResponse!=NULL)			{						//				// If this is a client request, then we need to signal				// that this request is being aborted				//				wr->OnResponse(						NULL,						WEBCLIENT_DESTROYED,						NULL,						NULL,						NULL,						0,						-1,						wr->user1,						wr->user2,						&zero);					}			free(wr);			wr = ILibQueue_DeQueue(wcdo->RequestQueue);		}	ILibQueue_Destroy(wcdo->RequestQueue);	free(wcdo);}/// <summary>/// Internal method to free resources associated with an ILibWebClient object/// </summary>/// <param name="object">The ILibWebClient to free</param>void ILibDestroyWebClient(void *object){	struct ILibWebClientManager *manager = (struct ILibWebClientManager*)object;	void *en;	void *wcdo;	char *key;	int keyLength;	//	// Iterate through all the WebClientDataObjects	//	en = ILibHashTree_GetEnumerator(manager->DataTable);	while(ILibHashTree_MoveNext(en)==0)	{		//		// Free the WebClientDataObject		//		ILibHashTree_GetValue(en,&key,&keyLength,&wcdo);		ILibWebClient_DestroyWebClientDataObject(wcdo);	}	ILibHashTree_DestroyEnumerator(en);		//	// Free all the other associated resources	//	ILibQueue_Destroy(manager->backlogQueue);	ILibDestroyHashTree(manager->idleTable);	ILibDestroyHashTree(manager->DataTable);	free(manager->socks);}static void ILibWebClient_TimerInterruptSink(void *object){}static void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo){	if(wcdo==NULL) {return;}	wcdo->Chunked = 0;	wcdo->FinHeader = 0;	wcdo->WaitForClose = 0;	wcdo->InitialRequestAnswered = 1;	wcdo->DisconnectSent=0;//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}	wcdo->ConnectionCloseSpecified=0;//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}	if(wcdo->header!=NULL)	{		ILibDestructPacket(wcdo->header);		wcdo->header = NULL;	}}/// <summary>/// Internal method dispatched by the LifeTimeMonitor/// </summary>/// <para>/// This timed callback is used to close idle sockets. A socket is considered idle/// if after a request is answered, another request isn't received /// within the time specified by HTTP_SESSION_IDLE_TIMEOUT/// </para>/// <param name="object">The WebClientDataObject</param>static void ILibWebClient_TimerSink(void *object){	void *enumerator;	char IPV4Address[22];	int IPV4AddressLength;	struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)object;	struct ILibWebClientDataObject *wcdo2;	char *key;	int keyLength;	void *data;	void *DisconnectSocket = NULL;	SEM_TRACK(WebClient_TrackLock("ILibWebClient_TimerSink",1,wcdo->Parent);)	if(ILibQueue_IsEmpty(wcdo->RequestQueue)!=0)	{		//		// This connection is idle, becuase there are no pending requests		//		if(wcdo->SOCK!=NULL && ILibAsyncSocket_IsFree(wcdo->SOCK)==0)		{			//			// We need to close this socket			//			wcdo->Closing = 1;			DisconnectSocket = wcdo->SOCK;		}		if(wcdo->Parent->idleCount>MAX_IDLE_SESSIONS)		{			//			// We need to remove an entry from th idleTable, if there are too			// many entries in it			//			--wcdo->Parent->idleCount;			enumerator = ILibHashTree_GetEnumerator(wcdo->Parent->idleTable);			ILibHashTree_MoveNext(enumerator);			ILibHashTree_GetValue(enumerator,&key,&keyLength,&data);			ILibHashTree_DestroyEnumerator(enumerator);			wcdo2 = ILibGetEntry(wcdo->Parent->DataTable,key,keyLength);			ILibDeleteEntry(wcdo->Parent->DataTable,key,keyLength);			ILibDeleteEntry(wcdo->Parent->idleTable,key,keyLength);			SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_TimerSink",2,wcdo->Parent);)			ILibWebClient_DestroyWebClientDataObject(wcdo2);			return;		}		else		{			//			// Add this DataObject into the idleTable for use later			//			IPV4AddressLength = sprintf(IPV4Address,"%s:%d",				inet_ntoa(wcdo->remote.sin_addr),				ntohs(wcdo->remote.sin_port));			MEMCHECK(assert(IPV4AddressLength<=21);)			ILibAddEntry(wcdo->Parent->idleTable,IPV4Address,IPV4AddressLength,wcdo);			++wcdo->Parent->idleCount;			wcdo->SOCK = NULL;			wcdo->DisconnectSent=0;		}	}	SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_TimerSink",3,wcdo->Parent);)	//	// Let the user know, the socket has been disconnected	//	if(DisconnectSocket!=NULL)	{		ILibAsyncSocket_Disconnect(DisconnectSocket);	}}/// <summary>/// Internal method called by ILibWebServer, when a response was completed/// </summary>/// <param name="_wcdo">The associated WebClientDataObject</param>void ILibWebClient_FinishedResponse_Server(void *_wcdo){	struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)_wcdo;	if(wcdo==NULL) {return;}//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}	if(wcdo->chunk!=NULL)	{		//		// Free any resources associated with the Chunk Processor		//		free(wcdo->chunk->buffer);		free(wcdo->chunk);		wcdo->chunk = NULL;	}//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}	if(wcdo->header!=NULL)	{		//

⌨️ 快捷键说明

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