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

📄 ilibwebclient.c

📁 intel upnp stack source code
💻 C
📖 第 1 页 / 共 4 页
字号:
						}						if(wcdo->BytesLeft==0)						{							//							// We already have the complete Response Packet							// 							if(wr->OnResponse!=NULL)							{								wr->OnResponse(									socketModule,									0,									wcdo->header,									NULL,									&zero,									0,									-1,									wr->user1,									wr->user2,									&(wcdo->PAUSE));							}							*p_beginPointer = *p_beginPointer + i + 4;							ILibWebClient_FinishedResponse(socketModule,wcdo);						}						else						{							//							// There is still data we need to read. Lets see if any of the 							// body arrived yet							//							if(wcdo->Chunked==0)							{								//								// This isn't chunked, so we can process normally								// 								if(wcdo->BytesLeft!=-1 && (endPointer-(*p_beginPointer)) - (i+4) >= wcdo->BytesLeft)								{									//									// We have the entire body now, so we have the entire packet									// 									if(wr->OnResponse!=NULL)									{										wr->OnResponse(											socketModule,											0,											wcdo->header,											buffer+i+4,											&zero,											wcdo->BytesLeft,											-1,											wr->user1,											wr->user2,											&(wcdo->PAUSE));									}									*p_beginPointer = *p_beginPointer + i + 4 + (zero==0?wcdo->BytesLeft:zero);									ILibWebClient_FinishedResponse(socketModule,wcdo);								}								else								{									//									// We read some of the body, but not all of it yet									//									if(wr->OnResponse!=NULL)									{										wr->OnResponse(											socketModule,											0,											wcdo->header,											buffer+i+4,											&zero,											(endPointer - (*p_beginPointer) - (i+4)),											0,											wr->user1,											wr->user2,											&(wcdo->PAUSE));									}									wcdo->HeaderLength = 0;									*p_beginPointer = i+4+zero;									wcdo->BytesLeft -= zero;									//									// We are consuming the header portion of the buffer									// so we need to copy it out, so we can recycle the buffer									// for the body									//									tph = ILibClonePacket(wcdo->header);									ILibDestructPacket(wcdo->header);									wcdo->header = tph;								}							}//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}							else							{								//								// This packet is chunk encoded, so we need to run it								// through our Chunk Processor								//								ILibWebClient_ProcessChunk(socketModule,wcdo,buffer+i+4,&zero,(endPointer - (*p_beginPointer) - (i+4)));								*p_beginPointer = i+4+zero;								tph = ILibClonePacket(wcdo->header);								ILibDestructPacket(wcdo->header);								wcdo->header = tph;							}//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}						}					}					else					{						//						// ToDo: There was an error parsing the headers. What should we do about it?						// Right now, we don't care						//					}					break;				}				++i;			}		}	}	else	{		//		// We already processed the headers, so we are only expecting the body now		//		if(wcdo->Chunked==0)		{			//			// This isn't chunk encoded			//			if(wcdo->WaitForClose==0)			{				//				// This is to determine if we have everything				//				Fini = ((endPointer - (*p_beginPointer))>=wcdo->BytesLeft)?-1:0;			}			else			{				//				// We need to read until the socket closes				//				Fini = 0;			}			if(wr->OnResponse!=NULL)			{				wr->OnResponse(					socketModule,					0,					wcdo->header,					buffer,					p_beginPointer,					wcdo->WaitForClose==0?(((endPointer - (*p_beginPointer))>=wcdo->BytesLeft)?wcdo->BytesLeft:(endPointer - (*p_beginPointer))):(endPointer-(*p_beginPointer)),					Fini,					wr->user1,					wr->user2,					&(wcdo->PAUSE));			}			if(ILibAsyncSocket_IsFree(socketModule)==0)			{				if(wcdo->WaitForClose==0)				{					//					// Decrement our counters					//					wcdo->BytesLeft -= *p_beginPointer;					if(Fini!=0)					{						//						// We finished processing this, so signal it						//						*p_beginPointer = *p_beginPointer + wcdo->BytesLeft;						ILibWebClient_FinishedResponse(socketModule,wcdo);					}				}			}		}//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}		else		{			//			// This is chunk encoded, so run it through our Chunk Processor			//			ILibWebClient_ProcessChunk(socketModule,wcdo,buffer,p_beginPointer,endPointer);		}//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}	}	if(ILibAsyncSocket_IsFree(socketModule)==0)	{		//		// If the user said to pause this connection, do so		//		*PAUSE = wcdo->PAUSE;	}}/// <summary>/// Internal method dispatched by the LifeTimeMonitor, to retry refused connections/// </summary>/// <para>/// This module does an exponential backoff, when retrying connections. The number/// of retries is determined by the value of HTTP_CONNECT_RETRY_COUNT/// </para>/// <param name="object">The associated WebClientDataObject</param>static void ILibWebClient_RetrySink(void *object){	char key[22];	int keyLength;	struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)object;	wcdo->ExponentialBackoff = wcdo->ExponentialBackoff==0?1:wcdo->ExponentialBackoff * 2;		SEM_TRACK(WebClient_TrackLock("ILibWebClient_RetrySink",1,wcm);)	if(wcdo->ExponentialBackoff==(int)pow((double)2,(double)HTTP_CONNECT_RETRY_COUNT))	{		//		// Retried enough times, give up		//		keyLength = sprintf(key,"%s:%d",inet_ntoa(wcdo->remote.sin_addr),(int)ntohs(wcdo->remote.sin_port));				MEMCHECK(assert(keyLength<=21);) 		ILibDeleteEntry(wcdo->Parent->DataTable,key,keyLength);		ILibDeleteEntry(wcdo->Parent->idleTable,key,keyLength);				SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_RetrySink",2,wcm);)		ILibWebClient_DestroyWebClientDataObject(wcdo);		return;	}	else	{		//		// Lets retry again		//		ILibQueue_EnQueue(wcdo->Parent->backlogQueue,wcdo);	}	SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_RetrySink",3,wcm);)}/// <summary>/// Internal method dispatched by the OnConnect event of the underlying ILibAsyncSocket/// </summary>/// <param name="socketModule">The underlying ILibAsyncSocket</param>/// <param name="Connected">Flag indicating connect status: Nonzero indicates success</param>/// <param name="user">Associated WebClientDataObject</param>static void ILibWebClient_OnConnect(void* socketModule, int Connected, void *user){	struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)user;	struct ILibWebRequest *r;	int i;	wcdo->SOCK = socketModule;	wcdo->InitialRequestAnswered=0;	wcdo->DisconnectSent=0;	if(Connected!=0 && wcdo->DisconnectSent==0)	{		//Success: Send First Request		wcdo->LocalIP = ILibAsyncSocket_GetLocalInterface(socketModule);		wcdo->ExponentialBackoff=1;				SEM_TRACK(WebClient_TrackLock("ILibWebClient_OnConnect",1,wcdo->Parent);)		r = ILibQueue_PeekQueue(wcdo->RequestQueue);		SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_OnConnect",2,wcdo->Parent);)		for(i=0;i<r->NumberOfBuffers;++i)		{			ILibAsyncSocket_Send(socketModule,r->Buffer[i],r->BufferLength[i],-1);		}	}	else	{		//		// The connection failed, so lets set a timed callback, and try again		//		if(wcdo->DisconnectSent==0)		{			wcdo->Closing=2; //This is required, so we don't notify the user yet			ILibAsyncSocket_Disconnect(socketModule);			wcdo->Closing=0;			//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}			wcdo->PipelineFlag = PIPELINE_UNKNOWN;			//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}		}		ILibLifeTime_Add(wcdo->Parent->timer,wcdo,wcdo->ExponentialBackoff,&ILibWebClient_RetrySink,NULL);	}}/// <summary>/// Internal method dispatched by the OnDisconnect event of the underlying ILibAsyncSocket/// </summary>/// <param name="socketModule">The underlying ILibAsyncSocket</param>/// <param name="user">The associated WebClientDataObject</param>static void ILibWebClient_OnDisconnect(void* socketModule, void *user){	struct packetheader *h;	struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)user;	struct ILibWebRequest *wr;	char *buffer;	int BeginPointer,EndPointer;	if(wcdo==NULL) {return;}	if(wcdo->DisconnectSent!=0)	{		//		// We probably closed the socket on purpose, and don't want to tell		// anyone about it yet		//		return;	}	else if(ILibQueue_PeekQueue(wcdo->RequestQueue)!=NULL)	{		//		// There are still pending requests, so we probably already		// send the disconnect event up		//		wcdo->DisconnectSent = 1;	}	//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}	if(wcdo->Closing==0) 	{		if(ILibQueue_PeekQueue(wcdo->RequestQueue)!=NULL)		{			//			// If there are still pending requests, than obviously this server			// doesn't do persistent connections			//			wcdo->PipelineFlag = PIPELINE_NO;		}	}	//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}	if(wcdo->WaitForClose!=0)	{		//		// Since we had to read until the socket closes, we finally have		// all the data we need		//		ILibAsyncSocket_GetBuffer(socketModule,&buffer,&BeginPointer,&EndPointer);				SEM_TRACK(WebClient_TrackLock("ILibWebClient_OnDisconnect",1,wcdo->Parent);)		wr = ILibQueue_DeQueue(wcdo->RequestQueue);		SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_OnDisconnect",2,wcdo->Parent);)		wcdo->InitialRequestAnswered=1;		//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}		wcdo->PipelineFlag = PIPELINE_NO;		//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}		wcdo->FinHeader=0;		h = wcdo->header;		wcdo->header = NULL;		if(wr!=NULL && wr->OnResponse!=NULL)		{							wr->OnResponse(				socketModule,				0,				h,				buffer,				&BeginPointer,				EndPointer,				-1,				wr->user1,				wr->user2,				&(wcdo->PAUSE));						//ILibWebClient_FinishedResponse(socketModule,wcdo);				}		if(wcdo->DisconnectSent==1)		{			wcdo->DisconnectSent=0;		}		ILibWebClient_DestroyWebRequest(wr);		if(h!=NULL)		{			ILibDestructPacket(h);		}	}		if(wcdo->Closing!=0){return;}	SEM_TRACK(WebClient_TrackLock("ILibWebClient_OnDisconnect",3,wcdo->Parent);)	wr = ILibQueue_PeekQueue(wcdo->RequestQueue);	SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_OnDisconnect",4,wcdo->Parent);)	if(wr!=NULL)	{		// Still Requests to be made		if(wcdo->InitialRequestAnswered==0)		{			//Error			wr->OnResponse(				socketModule,				0,				NULL,				NULL,				NULL,				0,				-1,				wr->user1,				wr->user2,				&(wcdo->PAUSE));			ILibWebClient_FinishedResponse(socketModule,wcdo);				SEM_TRACK(WebClient_TrackLock("ILibWebClient_OnDisconnect",5,wcdo->Parent);)			wr = ILibQueue_PeekQueue(wcdo->RequestQueue);			SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_OnDisconnect",6,wcdo->Parent);)			if(wr==NULL){return;}		}		// Make Another Connection and Continue		wcdo->Closing = 0;		ILibQueue_EnQueue(wcdo->Parent->backlogQueue,wcdo);	}}/// <summary>/// Internal method dispatched by the OnSendOK event of the underlying ILibAsyncSocket/// </summary>/// <param name="socketModule">The underlying ILibAsyncSocket</param>/// <param name="user">The associated WebClientDataObject</param>static void ILibWebClient_OnSendOK(void *socketModule, void *user){}/// <summary>/// Chain PreSelect handler/// </summary>/// <param name="WebClientModule">The WebClient token</param>/// <param name="readset"></param>/// <param name="writeset"></param>/// <param name="errorset"></param>/// <param name="blocktime"></param>static void ILibWebClient_PreProcess(void* WebClientModule,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime){	struct ILibWebClientManager *wcm = (struct ILibWebClientManager*)WebClientModule;	struct ILibWebClientDataObject *wcdo;	int i;	int OK=0;	//	// Try and satisfy as many things as we can. If we have resources	// grab a socket and go	//	SEM_TRACK(WebClient_TrackLock("ILibWebClient_PreProcess",1,wcm);)	while(OK==0 && ILibQueue_IsEmpty(wcm->backlogQueue)==0)	{		OK=1;		for(i=0;i<wcm->socksLength;++i)		{			if(ILibAsyncSocket_IsFree(wcm->socks[i])!=0)			{				OK=0;				wcdo = ILibQueue_DeQueue(wcm->backlogQueue);				if(wcdo!=NULL)				{					wcdo->Closing = 0;					ILibAsyncSocket_ConnectTo(						wcm->socks[i], 						INADDR_ANY, 						wcdo->remote.sin_addr.s_addr, 						(int)ntohs(wcdo->remote.sin_port),						NULL,						wcdo);				}			}			if(ILibQueue_IsEmpty(wcm->backlogQueue)!=0) {break;}		}	}	SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_PreProcess",2,wcm);)}/// <summary>/// Internal method dispatched by either ILibWebServer or ILibWebClient, to recheck the headers/// </summary>/// <para>/// In certain cases, when the underlying buffer has been reallocated, the pointers in the /// header structure will be invalid./// </para>/// <param name="token">The sender</param>/// <param name="user">The WCDO object</param>/// <param name="offSet">The offSet to the new buffer location</param>void ILibWebClient_OnBufferReAllocate(void *token, void *user, ptrdiff_t offSet){	struct packetheader_field_node *n;	struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)user;	if(wcdo!=NULL && wcdo->header!=NULL)	{		//		// Sometimes, the header was copied, in which case this realloc doesn't affect us		//		if(wcdo->header->ClonedPacket==0)		{			//			// Sometimes the user instantiated the string, so again			// this may not concern us			//			if(wcdo->header->UserAllocStrings==0)			{				if(wcdo->header->StatusCode==-1)				{					// Request Packet					wcdo->header->Directive  += offSet;					wcdo->header->DirectiveObj += offSet;				}				else				{					// Response Packet					wcdo->header->StatusData += offSet;				}			}			//			// Sometimes the user instantiated the string, so again			// this may not concern us			//			if(wcdo->header->UserAllocVersion==0)			{				wcdo->header->Version += offSet;			}			n = wcdo->header->FirstField;			while(n!=NULL)			{

⌨️ 快捷键说明

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