📄 api.c.svn-base
字号:
/*** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights** reserved.**** Terms under which this software may be used or copied are** provided in the specific license associated with this product.**** Hughes Technologies disclaims all warranties with regard to this** software, including all implied warranties of merchantability and** fitness, in no event shall Hughes Technologies be liable for any** special, indirect or consequential damages or any damages whatsoever** resulting from loss of use, data or profits, whether in an action of** contract, negligence or other tortious action, arising out of or in** connection with the use or performance of this software.****** $Id$***/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#include <time.h>#if defined(_WIN32)#include <winsock2.h>#else#include <unistd.h> #include <sys/file.h>#include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h>#include <sys/socket.h> #include <netdb.h>#endif#include "config.h"#include "httpd.h"#include "httpd_priv.h"#ifdef HAVE_STDARG_H# include <stdarg.h>#else# include <varargs.h>#endifchar *httpdUrlEncode(str) char *str;{ char *new, *cp; new = (char *)_httpd_escape(str); if (new == NULL) { return(NULL); } cp = new; while(*cp) { if (*cp == ' ') *cp = '+'; cp++; } return(new);}char *httpdRequestMethodName(request *r){ static char tmpBuf[255]; switch(r->request.method) { case HTTP_GET: return("GET"); case HTTP_POST: return("POST"); default: snprintf(tmpBuf,255,"Invalid method '%d'", r->request.method); return(tmpBuf); }}httpVar *httpdGetVariableByName(request *r, char *name){ httpVar *curVar; curVar = r->variables; while(curVar) { if (strcmp(curVar->name, name) == 0) return(curVar); curVar = curVar->nextVariable; } return(NULL);}httpVar *httpdGetVariableByPrefix(request *r, char *prefix){ httpVar *curVar; if (prefix == NULL) return(r->variables); curVar = r->variables; while(curVar) { if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) return(curVar); curVar = curVar->nextVariable; } return(NULL);}httpVar *httpdGetVariableByPrefixedName(request *r, char *prefix, char *name){ httpVar *curVar; int prefixLen; if (prefix == NULL) return(r->variables); curVar = r->variables; prefixLen = strlen(prefix); while(curVar) { if (strncmp(curVar->name, prefix, prefixLen) == 0 && strcmp(curVar->name + prefixLen, name) == 0) { return(curVar); } curVar = curVar->nextVariable; } return(NULL);}httpVar *httpdGetNextVariableByPrefix(curVar, prefix) httpVar *curVar; char *prefix;{ if(curVar) curVar = curVar->nextVariable; while(curVar) { if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) return(curVar); curVar = curVar->nextVariable; } return(NULL);}int httpdAddVariable(request *r, char *name, char *value){ httpVar *curVar, *lastVar, *newVar; while(*name == ' ' || *name == '\t') name++; newVar = malloc(sizeof(httpVar)); bzero(newVar, sizeof(httpVar)); newVar->name = strdup(name); newVar->value = strdup(value); lastVar = NULL; curVar = r->variables; while(curVar) { if (strcmp(curVar->name, name) != 0) { lastVar = curVar; curVar = curVar->nextVariable; continue; } while(curVar) { lastVar = curVar; curVar = curVar->nextValue; } lastVar->nextValue = newVar; return(0); } if (lastVar) lastVar->nextVariable = newVar; else r->variables = newVar; return(0);}httpd *httpdCreate(host, port) char *host; int port;{ httpd *new; int sock, opt; struct sockaddr_in addr; /* ** Create the handle and setup it's basic config */ new = malloc(sizeof(httpd)); if (new == NULL) return(NULL); bzero(new, sizeof(httpd)); new->port = port; if (host == HTTP_ANY_ADDR) new->host = HTTP_ANY_ADDR; else new->host = strdup(host); new->content = (httpDir*)malloc(sizeof(httpDir)); bzero(new->content,sizeof(httpDir)); new->content->name = strdup(""); /* ** Setup the socket */#ifdef _WIN32 { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); /* Found a usable winsock dll? */ if( err != 0 ) return NULL; /* ** Confirm that the WinSock DLL supports 2.2. ** Note that if the DLL supports versions greater ** than 2.2 in addition to 2.2, it will still return ** 2.2 in wVersion since that is the version we ** requested. */ if( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* ** Tell the user that we could not find a usable ** WinSock DLL. */ WSACleanup( ); return NULL; } /* The WinSock DLL is acceptable. Proceed. */ }#endif sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { free(new); return(NULL); }# ifdef SO_REUSEADDR opt = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(int));# endif new->serverSock = sock; bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; if (new->host == HTTP_ANY_ADDR) { addr.sin_addr.s_addr = htonl(INADDR_ANY); } else { addr.sin_addr.s_addr = inet_addr(new->host); } addr.sin_port = htons((u_short)new->port); if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) <0) { close(sock); free(new); return(NULL); } listen(sock, 128); new->startTime = time(NULL); return(new);}void httpdDestroy(server) httpd *server;{ if (server == NULL) return; if (server->host) free(server->host); free(server);}request *httpdGetConnection(server, timeout) httpd *server; struct timeval *timeout;{ int result; fd_set fds; struct sockaddr_in addr; size_t addrLen; char *ipaddr; request *r; FD_ZERO(&fds); FD_SET(server->serverSock, &fds); result = 0; while(result == 0) { result = select(server->serverSock + 1, &fds, 0, 0, timeout); if (result < 0) { server->lastError = -1; return(NULL); } if (timeout != 0 && result == 0) { return(NULL); server->lastError = 0; } if (result > 0) { break; } } /* Allocate request struct */ r = (request *)malloc(sizeof(request)); if (r == NULL) { server->lastError = -3; return(NULL); } memset((void *)r, 0, sizeof(request)); /* Get on with it */ bzero(&addr, sizeof(addr)); addrLen = sizeof(addr); r->clientSock = accept(server->serverSock,(struct sockaddr *)&addr, &addrLen); ipaddr = inet_ntoa(addr.sin_addr); if (ipaddr) strncpy(r->clientAddr, ipaddr, HTTP_IP_ADDR_LEN); else *r->clientAddr = 0; r->readBufRemain = 0; r->readBufPtr = NULL; /* ** Check the default ACL */ if (server->defaultAcl) { if (httpdCheckAcl(server, r, server->defaultAcl) == HTTP_ACL_DENY) { httpdEndRequest(r); server->lastError = 2; return(NULL); } } return(r);}int httpdReadRequest(httpd *server, request *r){ static char buf[HTTP_MAX_LEN]; int count, inHeaders; char *cp, *cp2; int _httpd_decode(); /* ** Setup for a standard response */ strcpy(r->response.headers, "Server: Hughes Technologies Embedded Server\n"); strcpy(r->response.contentType, "text/html"); strcpy(r->response.response,"200 Output Follows\n"); r->response.headersSent = 0; /* ** Read the request */ count = 0; inHeaders = 1; while(_httpd_readLine(r, buf, HTTP_MAX_LEN) > 0) { count++; /* ** Special case for the first line. Scan the request ** method and path etc */ if (count == 1) { /* ** First line. Scan the request info */ cp = cp2 = buf; while(isalpha(*cp2)) cp2++; *cp2 = 0; if (strcasecmp(cp,"GET") == 0) r->request.method = HTTP_GET; if (strcasecmp(cp,"POST") == 0) r->request.method = HTTP_POST; if (r->request.method == 0) { _httpd_net_write( r->clientSock, HTTP_METHOD_ERROR, strlen(HTTP_METHOD_ERROR)); _httpd_net_write( r->clientSock, cp, strlen(cp)); _httpd_writeErrorLog(server, r, LEVEL_ERROR, "Invalid method received"); return(-1); } cp = cp2+1; while(*cp == ' ') cp++; cp2 = cp; while(*cp2 != ' ' && *cp2 != 0) cp2++; *cp2 = 0; strncpy(r->request.path,cp,HTTP_MAX_URL); _httpd_sanitiseUrl(r->request.path); continue; } /* ** Process the headers */ if (inHeaders) { if (*buf == 0) { /* ** End of headers. Continue if there's ** data to read */ if (r->request.contentLength == 0) break; inHeaders = 0; break; }#if 0 /** * Philippe commenting this out, it crashed with a * particular pattern sent from the browser * and we don't need it if (strncasecmp(buf,"Cookie: ",7) == 0) { char *var, *val, *end; var = index(buf,':'); while(var) { var++; val = index(var, '='); *val = 0; val++; end = index(val,';'); if(end) *end = 0; httpdAddVariable(r, var, val); var = end; } } */#endif#if 0 if (strncasecmp(buf,"Authorization: ",15) == 0) { cp = index(buf,':') + 2; if (strncmp(cp,"Basic ", 6) != 0) { /* Unknown auth method */ } else { char authBuf[100]; cp = index(cp,' ') + 1; _httpd_decode(cp, authBuf, 100); r->request.authLength = strlen(authBuf); cp = index(authBuf,':'); if (cp) { *cp = 0; strncpy( r->request.authPassword, cp+1, HTTP_MAX_AUTH); } strncpy(r->request.authUser, authBuf, HTTP_MAX_AUTH); } }#endif#if 0 if (strncasecmp(buf,"Referer: ",9) == 0) { cp = index(buf,':') + 2; if(cp) { strncpy(r->request.referer,cp,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -