📄 httpd_lib.c
字号:
/*
* $Id: httpd_lib.c,v 1.0 2003/02/21 00:11:04 csm Exp $
* $Copyright: (c) 2002, 2003 Broadcom Corp.
* All Rights Reserved.$
*/
/***********************************************************************
* iMpacct Technology Corporation. Copyright 2001 - 2100. *
* ALL RIGHTS RESERVED *
*----------------------------------------------------------------------*
* Project : NXF-735A
* Creator : Gary Chen / iMpacct 04/08/2002
* File : httpd_lib.c
* Description: Collect HTTPD routines
*
* History:
*
************************************************************************/
#include <sys/sys_config.h>
#include <parm/parm_config.h>
#include <http/http_cfg.h>
#include <http/http_lib.h>
#include <network.h>
extern char szPageContent [];
static int httpd_really_start_request(HTTPD_CONN_T* hc);
static char* httpd_method_str(int method);
static char* httpd_bufgets(HTTPD_CONN_T* hc);
void httpd_write_response(HTTPD_CONN_T* hc);
void httpd_add_response(HTTPD_CONN_T* hc, char* str);
static void httpd_send_mime(HTTPD_CONN_T* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod);
static LPVOID httpd_mmc_map (LPSTR filename, HTTP_STAT_T* sbP);
static void strdecode(char* to, char* from);
static int is_hexit(char c);
static int hexit(char c);
static void figure_mime(HTTPD_CONN_T* hc);
// (+) Carl, 5-25-2002
void WebLib_strlwr (LPSTR psz);
// (-) Carl, 5-25-2002
static int PostHandler (HTTPD_CONN_T* hc);
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_got_request
*-----------------------------------------------------------------------
* DESCRIPTION: Get HTTP client request
* INPUT : HTTPD_CONN_T* hc
* OUTPUT : int
*----------------------------------------------------------------------*/
int httpd_got_request(HTTPD_CONN_T* hc)
{
char c;
for (; hc->checked_idx < hc->read_idx ; ++hc->checked_idx)
{
c = hc->read_buf[hc->checked_idx];
switch (hc->checked_state)
{
case CHST_FIRSTWORD:
switch (c)
{
case ' ':
case '\t':
hc->checked_state = CHST_FIRSTWS;
break;
case '\n':
case '\r':
hc->checked_state = CHST_BOGUS;
return GR_BAD_REQUEST;
}
break;
case CHST_FIRSTWS:
switch (c)
{
case ' ':
case '\t':
break;
case '\n':
case '\r':
hc->checked_state = CHST_BOGUS;
return GR_BAD_REQUEST;
default:
hc->checked_state = CHST_SECONDWORD;
break;
}
break;
case CHST_SECONDWORD:
switch (c)
{
case ' ':
case '\t':
hc->checked_state = CHST_SECONDWS;
break;
case '\n':
case '\r':
/* The first line has only two words - an HTTP/0.9 request. */
return GR_GOT_REQUEST;
}
break;
case CHST_SECONDWS:
switch (c)
{
case ' ':
case '\t':
break;
case '\n':
case '\r':
hc->checked_state = CHST_BOGUS;
return GR_BAD_REQUEST;
default:
hc->checked_state = CHST_THIRDWORD;
break;
}
break;
case CHST_THIRDWORD:
switch (c)
{
case ' ':
case '\t':
hc->checked_state = CHST_BOGUS;
return GR_BAD_REQUEST;
case '\n':
hc->checked_state = CHST_LF;
break;
case '\r':
hc->checked_state = CHST_CR;
break;
}
break;
case CHST_LINE:
switch (c)
{
case '\n':
hc->checked_state = CHST_LF;
break;
case '\r':
hc->checked_state = CHST_CR;
break;
}
break;
case CHST_LF:
switch (c)
{
case '\n':
/* Two newlines in a row - a blank line - end of request. */
return GR_GOT_REQUEST;
case '\r':
hc->checked_state = CHST_CR;
break;
default:
hc->checked_state = CHST_LINE;
break;
}
break;
case CHST_CR:
switch (c)
{
case '\n':
hc->checked_state = CHST_CRLF;
break;
case '\r':
/* Two returns in a row - end of request. */
return GR_GOT_REQUEST;
default:
hc->checked_state = CHST_LINE;
break;
}
break;
case CHST_CRLF:
switch (c)
{
case '\n':
/* Two newlines in a row - end of request. */
return GR_GOT_REQUEST;
case '\r':
hc->checked_state = CHST_CRLFCR;
break;
default:
hc->checked_state = CHST_LINE;
break;
}
break;
case CHST_CRLFCR:
switch (c)
{
case '\n':
case '\r':
/* Two CRLFs or two CRs in a row - end of request. */
return GR_GOT_REQUEST;
default:
hc->checked_state = CHST_LINE;
break;
}
break;
case CHST_BOGUS:
return GR_BAD_REQUEST;
}
}
return GR_NO_REQUEST;
}
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_parse_reques
*-----------------------------------------------------------------------
* DESCRIPTION: Parse HTTP client request
* INPUT : HTTPD_CONN_T* hc
* OUTPUT : int
*----------------------------------------------------------------------*/
int httpd_parse_request(HTTPD_CONN_T* hc)
{
char* buf;
char* method_str;
char* url;
char* protocol;
char* reqhost;
char* eol;
char* cp;
char* pi;
hc->checked_idx = 0;
hc->mime_flag = 0;
hc->one_one = 0;
method_str = httpd_bufgets(hc);
url = strpbrk(method_str, " \t\n\r");
if (url == (char*) 0)
{
httpd_send_err(hc, 400, httpd_err400title, httpd_err400form, "");
return -1;
}
*url++ = '\0';
url += strspn(url, " \t\n\r");
protocol = strpbrk(url, " \t\n\r");
if (protocol == (char*) 0)
protocol = "HTTP/0.9";
else
{
*protocol++ = '\0';
protocol += strspn(protocol, " \t\n\r");
if (*protocol != '\0')
{
hc->mime_flag = 1;
eol = strpbrk(protocol, " \t\n\r");
if (eol != (char*) 0)
*eol = '\0';
if (strcasecmp(protocol, "HTTP/1.0") != 0)
hc->one_one = 1;
}
}
/* Check for HTTP/1.1 absolute URL. */
if (strncasecmp(url, "http://", 7) == 0)
{
if (! hc->one_one)
{
httpd_send_err(hc, 400, httpd_err400title, httpd_err400form, "");
return -1;
}
reqhost = url + 7;
url = strchr(reqhost, '/');
if (url == (char*) 0)
{
httpd_send_err(hc, 400, httpd_err400title, httpd_err400form, "");
return -1;
}
*url = '\0';
httpd_realloc_str(&hc->reqhost, &hc->maxreqhost, strlen(reqhost));
strcpy(hc->reqhost, reqhost);
*url = '/';
}
else
hc->reqhost[0] = '\0';
if (strcasecmp(method_str, httpd_method_str(METHOD_GET)) == 0)
hc->method = METHOD_GET;
else
if (strcasecmp(method_str, httpd_method_str(METHOD_HEAD)) == 0)
hc->method = METHOD_HEAD;
else
if (strcasecmp(method_str, httpd_method_str(METHOD_POST)) == 0)
hc->method = METHOD_POST;
else
{
httpd_send_err (hc, 501, err501title, err501form, method_str);
return -1;
}
hc->encodedurl = url;
httpd_realloc_str (&hc->decodedurl, &hc->maxdecodedurl, strlen(hc->encodedurl));
strdecode(hc->decodedurl, hc->encodedurl);
hc->protocol = protocol;
if (hc->decodedurl[0] != '/')
{
httpd_send_err(hc, 400, httpd_err400title, httpd_err400form, "");
return -1;
}
httpd_realloc_str (&hc->origfilename, &hc->maxorigfilename, strlen(hc->decodedurl));
strcpy(hc->origfilename, &hc->decodedurl[1]);
/* Special case for top-level URL. */
if (hc->origfilename[0] == '\0')
{
httpd_realloc_str (&hc->origfilename, &hc->maxorigfilename, strlen(HTTPD_HOME_PAGE));
strcpy(hc->origfilename, HTTPD_HOME_PAGE);
}
/* Extract query string from encoded URL. */
hc->query[0] = '\0';
cp = strchr(hc->encodedurl, '?');
if (cp != (char*) 0)
{
++cp;
httpd_realloc_str(&hc->query, &hc->maxquery, strlen(cp));
strcpy(hc->query, cp);
}
/* And remove query from filename. */
cp = strchr(hc->origfilename, '?');
if (cp != (char*) 0)
*cp = '\0';
/* Now for the rest of the request. */
hc->accept[0] = '\0';
hc->accepte[0] = '\0';
hc->remoteuser[0] = '\0';
hc->response[0] = '\0';
hc->responselen = 0;
hc->referer = "";
hc->useragent = "";
hc->cookie = "";
hc->contenttype = "";
hc->hdrhost = "";
hc->authorization = "";
hc->if_modified_since = (time_t) -1;
hc->range_if = (time_t) -1;
hc->contentlength = -1;
hc->got_range = 0;
hc->tildemapped = 0;
hc->init_byte_loc = 0;
hc->end_byte_loc = -1;
hc->keep_alive = 0;
hc->hostname = (char*) 0;
if (hc->mime_flag)
{
/* Read the MIME headers. */
while ((buf = httpd_bufgets(hc)) != (char*) 0)
{
if (buf[0] == '\0')
break;
if (strncasecmp(buf, "Referer:", 8) == 0)
{
cp = &buf[8];
cp += strspn(cp, " \t");
hc->referer = cp;
}
else if (strncasecmp(buf, "User-Agent:", 11) == 0)
{
cp = &buf[11];
cp += strspn(cp, " \t");
hc->useragent = cp;
}
else if (strncasecmp(buf, "Host:", 5) == 0)
{
cp = &buf[5];
cp += strspn(cp, " \t");
hc->hdrhost = cp;
cp = strchr(hc->hdrhost, ':');
if (cp != (char*) 0)
*cp = '\0';
}
else if (strncasecmp(buf, "Accept:", 7) == 0)
{
cp = &buf[7];
cp += strspn(cp, " \t");
if (hc->accept[0] != '\0')
{
if (strlen(hc->accept) > 5000)
{
// syslog (LOG_ERR, "%.80s way too much Accept: data",
//inet_ntoa(hc->client_addr));
continue;
}
httpd_realloc_str (&hc->accept, &hc->maxaccept,
strlen(hc->accept) + 2 + strlen(cp));
strcat (hc->accept, ", ");
}
else
httpd_realloc_str(&hc->accept, &hc->maxaccept, strlen(cp));
strcat (hc->accept, cp);
}
else if (strncasecmp(buf, "Accept-Encoding:", 16) == 0)
{
cp = &buf[16];
cp += strspn(cp, " \t");
if (hc->accepte[0] != '\0')
{
if (strlen(hc->accepte) > 5000)
{
//syslog (LOG_ERR, "%.80s way too much Accept-Encoding: data",
// inet_ntoa(hc->client_addr));
continue;
}
httpd_realloc_str (&hc->accepte, &hc->maxaccepte,
strlen(hc->accepte) + 2 + strlen(cp));
strcat (hc->accepte, ", ");
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -