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

📄 ilibwebserver.c

📁 intel upnp stack source code
💻 C
📖 第 1 页 / 共 3 页
字号:
	// Add a timed callback, because if we don't receive a request within a specified	// amount of time, we want to close the socket, so we don't waste resources	//	ILibLifeTime_Add(wsm->LifeTime,ws,HTTP_SESSION_IDLE_TIMEOUT,&ILibWebServer_IdleSink,NULL);	//	// Inform the user that a new session was established	//	if(wsm->OnSession!=NULL)	{		wsm->OnSession(ws,wsm->User);	}}/// <summary>/// Internal method dispatched from the underlying AsyncServerSocket engine/// </summary>/// <param name="AsyncServerSocketModule">The ILibAsyncServerSocket token</param>/// <param name="ConnectionToken">The ILibAsyncSocket connection token</param>/// <param name="user">The ILibWebServer_Session object</param>static void ILibWebServer_OnDisconnect(void *AsyncServerSocketModule, void *ConnectionToken, void *user){	struct ILibWebServer_Session *ws = (struct ILibWebServer_Session*)user;	if(ws->Reserved10 != NULL)	{		*(ws->Reserved10) = NULL;	}	//	// Reserved4 = RequestAnsweredFlag	// Reserved5 = RequestMadeFlag	//	if(ws->Reserved4!=0 || ws->Reserved5==0)	{		ILibLifeTime_Remove(((struct ILibWebServer_StateModule*)ws->Parent)->LifeTime,ws);		ws->Reserved4=0;	}	//	// Notify the user that this session disconnected	//	if(ws->OnDisconnect!=NULL)	{		ws->OnDisconnect(ws);	}	ILibWebClient_DestroyWebClientDataObject(ws->Reserved3);	free(user);}/// <summary>/// Internal method dispatched from the underlying ILibAsyncServerSocket engine/// </summary>/// <param name="AsyncServerSocketModule">The ILibAsyncServerSocket token</param>/// <param name="ConnectionToken">The ILibAsyncSocket connection token</param>/// <param name="buffer">The receive buffer</param>/// <param name="p_beginPointer">buffer offset</param>/// <param name="endPointer">buffer length</param>/// <param name="OnInterrupt">Function Pointer to handle Interrupts</param>/// <param name="user">ILibWebServer_Session object</param>/// <param name="PAUSE">Flag to pause data reads on the underlying AsyncSocket engine</param>static void ILibWebServer_OnReceive(void *AsyncServerSocketModule, void *ConnectionToken,char* buffer,int *p_beginPointer, int endPointer,void (**OnInterrupt)(void *AsyncServerSocketMoudle, void *ConnectionToken, void *user), void **user, int *PAUSE){	//	// Pipe the data down to our internal WebClient engine, which will do	// all the HTTP processing	//	struct ILibWebServer_Session *ws = (struct ILibWebServer_Session*)(*user);	ILibWebClient_OnData(ConnectionToken,buffer,p_beginPointer,endPointer,NULL,&(ws->Reserved3),PAUSE);}/// <summary>/// Internal method dispatched from the underlying ILibAsyncServerSocket engine, signaling an interrupt/// </summary>/// <param name="AsyncServerSocketModule">The ILibAsyncServerSocket token</param>/// <param name="ConnectionToken">The ILibAsyncSocket connection token</param>/// <param name="user">The ILibWebServer_Session object</param>static void ILibWebServer_OnInterrupt(void *AsyncServerSocketModule, void *ConnectionToken, void *user){	struct ILibWebServer_Session *session = (struct ILibWebServer_Session*)user;		// This is ok, because this is MicroStackThread	ILibWebClient_DestroyWebClientDataObject(session->Reserved3);}/// <summary>/// Internal method called when a request has been answered. Dispatched from Send routines/// </summary>/// <param name="session">The ILibWebServer_Session object</param>/// <returns>Flag indicating if the session was closed</returns>static int ILibWebServer_RequestAnswered(struct ILibWebServer_Session *session){	struct packetheader *hdr = ILibWebClient_GetHeaderFromDataObject(session->Reserved3);	struct packetheader_field_node *f;	int PersistentConnection = 0;	//	// Reserved7 = Virtual Directory State Object	//	We delete this, because the request is finished, so we don't need to direct	//	data to this handler anymore. It needs to be recalculated next time	//	session->Reserved7 = NULL;	//	// Reqserved8 = RequestAnswered method called	//	If this is set, this method was already called, so we can just exit	//	if(session->Reserved8!=0)	{		return(0);	}	else	{		//		// Set the flags, so if this re-enters, we don't process this again		//		session->Reserved8 = 1;		f = hdr->FirstField;	}	//	// Reserved6 = CloseOverrideFlag	//	which means the session must be closed when request is complete	//	if(session->Reserved6==0)	{		//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}		if(hdr->VersionLength==3 && memcmp(hdr->Version,"1.0",3)==0)		{		//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}			// HTTP 1.0 , Check for Keep-Alive token			while(f!=NULL)			{				if(f->FieldLength==10 && strncasecmp(f->Field,"CONNECTION",10)==0)				{					if(f->FieldDataLength==10 && strncasecmp(f->FieldData,"KEEP-ALIVE",10)==0)					{						PersistentConnection = 1;						break;					}				}				f = f->NextField;			}		//{{{ REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT--> }}}		}		else		{			// HTTP 1.1+ , Check for CLOSE token			PersistentConnection = 1;			while(f!=NULL)			{				if(f->FieldLength==10 && strncasecmp(f->Field,"CONNECTION",10)==0)				{					if(f->FieldDataLength==5 && strncasecmp(f->FieldData,"CLOSE",5)==0)					{						PersistentConnection = 0;						break;					}				}				f = f->NextField;			}		}		//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}	}	if(PersistentConnection==0)	{		//		// Ensure calling on MicroStackThread. This will just result dispatching the callback on		// the microstack thread		//		ILibLifeTime_Add(((struct ILibWebServer_StateModule*)session->Parent)->LifeTime,session->Reserved2,0,&ILibAsyncSocket_Disconnect,NULL);	}	else	{		//		// This is a persistent connection. Set a timed callback, to idle this session if necessary		//		ILibLifeTime_Add(((struct ILibWebServer_StateModule*)session->Parent)->LifeTime,session,HTTP_SESSION_IDLE_TIMEOUT,&ILibWebServer_IdleSink,NULL);		ILibWebClient_FinishedResponse_Server(session->Reserved3);		//		// Since we're done with this request, resume the underlying socket, so we can continue		//		ILibWebClient_Resume(session->Reserved3);	}	return(PersistentConnection==0?ILibWebServer_SEND_RESULTED_IN_DISCONNECT:0);}/// <summary>/// Internal method dispatched from the underlying ILibAsyncServerSocket engine/// </summary>/// <param name="AsyncServerSocketModule">The ILibAsyncServerSocket token</param>/// <param name="ConnectionToken">The ILibAsyncSocket connection token</param>/// <param name="user">The ILibWebServer_Session object</param>static void ILibWebServer_OnSendOK(void *AsyncServerSocketModule,void *ConnectionToken, void *user){	struct ILibWebServer_Session *session = (struct ILibWebServer_Session*)user;	int flag = 0;	//	// Reserved4 = RequestAnsweredFlag	//	if(session->Reserved4!=0)	{		//		// This is normally called when the response was sent. But since it couldn't get through		// the first time, this method gets dispatched when it did, so now we have to call it.		//		flag = ILibWebServer_RequestAnswered(session);	}	if(session->OnSendOK!=NULL && flag != ILibWebServer_SEND_RESULTED_IN_DISCONNECT)	{		//		// Pass this event on, if everything is ok		//		session->OnSendOK(session);	}}/// <summary>/// Constructor for ILibWebServer/// </summary>/// <param name="Chain">The Chain to add this module to</param>/// <param name="MaxConnections">The maximum number of simultaneous connections</param>/// <param name="PortNumber">The Port number to listen to (0 = Random)</param>/// <param name="OnSession">Function Pointer to dispatch on when new Sessions are established</param>/// <param name="User">User state object to pass to OnSession</param>void *ILibWebServer_Create(void *Chain, int MaxConnections, int PortNumber,ILibWebServer_Session_OnSession OnSession, void *User){	struct ILibWebServer_StateModule *RetVal = (struct ILibWebServer_StateModule*)malloc(sizeof(struct ILibWebServer_StateModule));		memset(RetVal,0,sizeof(struct ILibWebServer_StateModule));	RetVal->Destroy = &ILibWebServer_Destroy;	RetVal->Chain = Chain;	RetVal->OnSession = OnSession;	//	// Create the underling ILibAsyncServerSocket	//	RetVal->ServerSocket = ILibCreateAsyncServerSocketModule(		Chain,		MaxConnections,		PortNumber,		INITIAL_BUFFER_SIZE,		&ILibWebServer_OnConnect,			// OnConnect		&ILibWebServer_OnDisconnect,		// OnDisconnect		&ILibWebServer_OnReceive,			// OnReceive		&ILibWebServer_OnInterrupt,			// OnInterrupt		&ILibWebServer_OnSendOK				// OnSendOK		);	//	// Set ourselves in the User tag of the underlying ILibAsyncServerSocket	//	ILibAsyncServerSocket_SetTag(RetVal->ServerSocket,RetVal);	RetVal->LifeTime = ILibCreateLifeTime(Chain);	RetVal->User = User;	ILibAddToChain(Chain,RetVal);	return(RetVal);}/// <summary>/// Returns the port number that this module is listening to/// </summary>/// <param name="WebServerToken">The ILibWebServer to query</param>/// <returns>The listening port number</returns>unsigned short ILibWebServer_GetPortNumber(void *WebServerToken){	struct ILibWebServer_StateModule *WSM = (struct ILibWebServer_StateModule*) WebServerToken;	return(ILibAsyncServerSocket_GetPortNumber(WSM->ServerSocket));}/// <summary>/// Send a response on a Session/// </summary>/// <param name="session">The ILibWebServer_Session to send the response on</param>/// <param name="packet">The packet to respond with</param>/// <returns>Flag indicating send status</returns>int ILibWebServer_Send(struct ILibWebServer_Session *session, struct packetheader *packet){	char *buffer;	int bufferSize;	int RetVal = 0;	if(session==NULL) 	{		ILibDestructPacket(packet);		return(ILibWebServer_INVALID_SESSION);	}	session->Reserved4=1;	bufferSize = ILibGetRawPacket(packet,&buffer);	RetVal = ILibAsyncServerSocket_Send(session->Reserved1,session->Reserved2,buffer,bufferSize,0);	if(RetVal==0)	{		// Completed Send		RetVal = ILibWebServer_RequestAnswered(session);	}	ILibDestructPacket(packet);	return(RetVal);}/// <summary>/// Send a response on a Session, directly specifying the buffers to send/// </summary>/// <param name="session">The ILibWebServer_Session to send the response on</param>/// <param name="buffer">The buffer to send</param>/// <param name="bufferSize">The length of the buffer</param>/// <param name="userFree">The ownership flag of the buffer</param>/// <param name="done">Flag indicating if this is everything</param>/// <returns>Send Status</returns>int ILibWebServer_Send_Raw(struct ILibWebServer_Session *session, char *buffer, int bufferSize, int userFree, int done){	int RetVal=0;	if(session==NULL)	{		if(userFree==ILibAsyncSocket_MemoryOwnership_CHAIN) {free(buffer);}		return(ILibWebServer_INVALID_SESSION);	}	session->Reserved4 = done;	RetVal = ILibAsyncServerSocket_Send(session->Reserved1,session->Reserved2,buffer,bufferSize,userFree);	if(RetVal==0 && done!=0)	{		// Completed Send		RetVal = ILibWebServer_RequestAnswered(session);	}	return(RetVal);}/// <summary>/// Streams the HTTP header response on a session, directly specifying the buffer/// </summary>/// <para>/// DO NOT specify Content-Length or Transfer-Encoding./// </para>/// <param name="session">The ILibWebServer_Session to send the response on</param>/// <param name="StatusCode">The HTTP status code, eg: 200</param>/// <param name="StatusData">The HTTP status data, eg: OK</param>/// <param name="ResponseHeaders">The ownership flag of the buffer</param>/// <param name="ResponseHeaders_FREE">Flag indicating if this is everything</param>/// <returns>Send Status</returns>int ILibWebServer_StreamHeader_Raw(struct ILibWebServer_Session *session, int StatusCode,char *StatusData,char *ResponseHeaders, int ResponseHeaders_FREE){	struct packetheader *hdr;		char *buffer;	int bufferLength;	int RetVal;	struct parser_result *pr,*pr2;	struct parser_result_field *prf;	int len;	char *temp;	int tempLength;	if(session==NULL) 	{		if(ResponseHeaders_FREE==ILibAsyncSocket_MemoryOwnership_CHAIN) {free(ResponseHeaders);}		return(ILibWebServer_INVALID_SESSION);	}	hdr = ILibWebClient_GetHeaderFromDataObject(session->Reserved3);	//	// Allocate the response header buffer	// ToDo: May want to make the response version dynamic or at least #define	//	buffer = (char*)malloc(20+strlen(StatusData));	bufferLength = sprintf(buffer,"HTTP/%s %d %s",HTTPVERSION,StatusCode,StatusData);	//	// Send the first portion of the headers across	//	RetVal = ILibWebServer_Send_Raw(session,buffer,bufferLength,0,0);	if(RetVal != ILibAsyncSocket_SEND_ON_CLOSED_SOCKET_ERROR && RetVal != ILibWebServer_SEND_RESULTED_IN_DISCONNECT)	{		//		// The Send went through

⌨️ 快捷键说明

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