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

📄 httpd_lib.c

📁 网页的客户端开发
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * $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 + -