📄 ilibwebserver.c
字号:
/* * 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: ILibWebServer.c * $Revision: #1.0.1799.42459 * $Author: Intel Corporation, Intel Device Builder * $Date: Wednesday, January 19, 2005 * * * */#define HTTPVERSION "1.1"#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) || defined(_WIN32_WCE) #define strncasecmp(x,y,z) _strnicmp(x,y,z)#else #include <semaphore.h>#endif#include <memory.h>#include <math.h>#include "ILibParsers.h"#include "ILibWebServer.h"#include "ILibAsyncServerSocket.h"#include "ILibAsyncSocket.h"#include "ILibWebClient.h"#define HTTP_SESSION_IDLE_TIMEOUT 3#define INITIAL_BUFFER_SIZE 2048struct ILibWebServer_VirDir_Data{ void *callback; void *user;};struct ILibWebServer_StateModule{ 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 *Chain; void *ServerSocket; void *LifeTime; void *User; void *Tag; void *VirtualDirectoryTable; void (*OnSession)(struct ILibWebServer_Session *SessionToken, void *User);};/// <summary>/// Sets the user tag associated with the server/// </summary>/// <param name="object">The ILibWebServer to associate the user tag with</param>/// <param name="Tag">The user tag to associate</param>void ILibWebServer_SetTag(void *object, void *Tag){ struct ILibWebServer_StateModule *s = (struct ILibWebServer_StateModule*)object; s->Tag = Tag;}/// <summary>/// Gets the user tag associated with the server/// </summary>/// <param name="object">The ILibWebServer to query</param>/// <returns>The associated user tag</returns>void *ILibWebServer_GetTag(void *object){ struct ILibWebServer_StateModule *s = (struct ILibWebServer_StateModule*)object; return(s->Tag);}/// <summary>/// Internal method dispatched by a timer to idle out a session/// </summary>/// <para>/// A session can idle in two ways. /// 1.) A TCP connection is established, but a request isn't received within an allotted time period/// 2.) A request is answered, and another request isn't received with an allotted time period/// </para>/// <param name="object">The ILibWebServer_Session that idled</param>static void ILibWebServer_IdleSink(void *object){ struct ILibWebServer_Session *session = (struct ILibWebServer_Session*)object; if(ILibAsyncSocket_IsFree(session->Reserved2)==0) { // This is OK, because we're on the MicroStackThread ILibAsyncServerSocket_Disconnect(session->Reserved1,session->Reserved2); }}/// <summary>/// Chain Destroy handler/// </summary>/// <param name="object">The ILibWebServer module</param>static void ILibWebServer_Destroy(void *object){ struct ILibWebServer_StateModule *s = (struct ILibWebServer_StateModule*)object; void *en; void *data; char *key; int keyLength; if(s->VirtualDirectoryTable!=NULL) { // // If there are registered Virtual Directories, we need to free the resources // associated with them // en = ILibHashTree_GetEnumerator(s->VirtualDirectoryTable); while(ILibHashTree_MoveNext(en)==0) { ILibHashTree_GetValue(en,&key,&keyLength,&data); free(data); } ILibHashTree_DestroyEnumerator(en); ILibDestroyHashTree(s->VirtualDirectoryTable); }}/// <summary>/// Internal method dispatched from the underlying WebClient engine/// </summary>/// <param name="WebReaderToken">The WebClient token</param>/// <param name="InterruptFlag">Flag indicating session was interrupted</param>/// <param name="header">The HTTP header structure</param>/// <param name="bodyBuffer">buffer pointing to HTTP body</param>/// <param name="beginPointer">buffer pointer offset</param>/// <param name="endPointer">buffer length</param>/// <param name="done">Flag indicating if the entire packet has been read</param>/// <param name="user1"></param>/// <param name="user2">The ILibWebServer uses this to pass the ILibWebServer_Session object</param>/// <param name="PAUSE">Flag to pause data reads on the underlying WebClient engine</param>static void ILibWebServer_OnResponse(void *WebReaderToken, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, int done, void *user1, void *user2, int *PAUSE){ struct ILibWebServer_Session *ws = (struct ILibWebServer_Session*)user2; struct ILibWebServer_StateModule *wsm = (struct ILibWebServer_StateModule*)ws->Parent; char *tmp; int tmpLength; struct parser_result *pr; int PreSlash=0; // // Reserved4 = Request Answered Flag // If this flag is set, the request was answered // Reserved5 = Request Made Flag // If this flag is set, a request has been received // if(ws->Reserved4!=0 || ws->Reserved5==0) { // // This session is no longer idle // ws->Reserved4 = 0; ws->Reserved5 = 1; ws->Reserved8 = 0; ILibLifeTime_Remove(((struct ILibWebServer_StateModule*)ws->Parent)->LifeTime,ws); } // // Check Virtual Directory // if(wsm->VirtualDirectoryTable!=NULL) { // // Reserved7 = Virtual Directory State Object // if(ws->Reserved7==NULL) { // // See if we can find the virtual directory. // If we do, set the State Object, so future responses don't need to // do it again // pr = ILibParseString(header->DirectiveObj,0,header->DirectiveObjLength,"/",1); if(pr->FirstResult->datalength==0) { // Does not start with '/' tmp = pr->FirstResult->NextResult->data; tmpLength = pr->FirstResult->NextResult->datalength; } else { // Starts with '/' tmp = pr->FirstResult->data; tmpLength = pr->FirstResult->datalength; PreSlash=1; } ILibDestructParserResults(pr); // // Does the Virtual Directory Exist? // if(ILibHasEntry(wsm->VirtualDirectoryTable,tmp,tmpLength)!=0) { // // Virtual Directory is defined // header->DirectiveObj = tmp+tmpLength; header->DirectiveObjLength -= (tmpLength+PreSlash); // // Set the StateObject, then call the handler // ws->Reserved7 = ILibGetEntry(wsm->VirtualDirectoryTable,tmp,tmpLength); ((ILibWebServer_VirtualDirectory)((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->callback)(ws,header,bodyBuffer,beginPointer,endPointer,done,((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->user); } else if(ws->OnReceive!=NULL) { // // If the virtual directory doesn't exist, just call the main handler // ws->OnReceive(ws,InterruptFlag,header,bodyBuffer,beginPointer,endPointer,done); } } else { // // The state object was already set, so we know this is the handler to use. So easy! // ((ILibWebServer_VirtualDirectory)((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->callback)(ws,header,bodyBuffer,beginPointer,endPointer,done,((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->user); } } else if(ws->OnReceive!=NULL) { // // Since there is no Virtual Directory lookup table, none were registered, // so we know we have no choice but to call the regular handler // ws->OnReceive(ws,InterruptFlag,header,bodyBuffer,beginPointer,endPointer,done); } // // Reserved8 = RequestAnswered method has been called // if(done!=0 && InterruptFlag==0 && header!=NULL && ws->Reserved8==0) { // // The request hasn't been satisfied yet, so stop reading from the socket until it is // *PAUSE=1; }}/// <summary>/// Internal method dispatched from the underlying ILibAsyncServerSocket module/// </summary>/// <para>/// This is dispatched when the underlying buffer has been reallocated, which may/// neccesitate extra processing/// </para>/// <param name="AsyncServerSocketToken">AsyncServerSocket token</param>/// <param name="ConnectionToken">Connection token (Underlying ILibAsyncSocket)</param>/// <param name="user">The ILibWebServer_Session object</param>/// <param name="offSet">Offset to the new buffer location</param>static void ILibWebServer_OnBufferReAllocated(void *AsyncServerSocketToken, void *ConnectionToken, void *user, ptrdiff_t offSet){ struct ILibWebServer_Session *ws = (struct ILibWebServer_Session*)user; // // We need to pass this down to our internal ILibWebClient for further processing // Reserved2 = ConnectionToken // Reserved3 = WebClientDataObject // ILibWebClient_OnBufferReAllocate(ws->Reserved2,ws->Reserved3,offSet);}/// <summary>/// Internal method dispatched from the underlying ILibAsyncServerSocket module/// </summary>/// <param name="AsyncServerSocketModule">AsyncServerSocket token</param>/// <param name="ConnectionToken">Connection token (Underlying ILibAsyncSocket)</param>/// <param name="user">User object that can be set. (used here for ILibWebServer_Session</param>static void ILibWebServer_OnConnect(void *AsyncServerSocketModule, void *ConnectionToken,void **user){ struct ILibWebServer_StateModule *wsm = (struct ILibWebServer_StateModule*)ILibAsyncServerSocket_GetTag(AsyncServerSocketModule); struct ILibWebServer_Session *ws = (struct ILibWebServer_Session*)malloc(sizeof(struct ILibWebServer_Session)); // // Create a new ILibWebServer_Session to represent this connection // memset(ws,0,sizeof(struct ILibWebServer_Session)); ws->Parent = wsm; ws->Reserved1 = AsyncServerSocketModule; ws->Reserved2 = ConnectionToken; ws->Reserved3 = ILibCreateWebClientEx(&ILibWebServer_OnResponse,ConnectionToken,wsm,ws); ws->User = wsm->User; *user = ws; // // We want to know when this connection reallocates its internal buffer, because we may // need to fix a few things // ILibAsyncServerSocket_SetReAllocateNotificationCallback(AsyncServerSocketModule,ConnectionToken,&ILibWebServer_OnBufferReAllocated); //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -