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

📄 httpd_lib.c

📁 网页的客户端开发
💻 C
📖 第 1 页 / 共 3 页
字号:
	}

	/* Nope.  Open the file. */
	fd = http_open (filename);
	if (fd == (HTTP_FILE *) -1)
	{
		// syslog(LOG_ERR, "open - %m");
		return (void*) 0;
	}

	if ((len = http_read (fd, (LPSTR *) &addr)) == -1)
	{
		// syslog(LOG_ERR, "read - %m");
		(void) http_close(fd);
		// httpd_free((void*) m);
		return (void*) 0;
	}
	
	sbP->st_size = len;

	(void) http_close(fd);

	/* And return the address. */
	return addr;
}

/* Copies and decodes a string.  It's ok for from and to to be the
** same string.
*/
static void strdecode(char* to, char* from)
	{
	for (; *from != '\0'; ++to, ++from)
	{
	if (from[0] == '%' && is_hexit(from[1]) && is_hexit(from[2]))
		{
		*to = hexit(from[1]) * 16 + hexit(from[2]);
		from += 2;
		}
	else
		*to = *from;
	}
	*to = '\0';
	}

static int is_hexit(char c)
{
	if (strchr("0123456789abcdefABCDEF", c) != (char*) 0)
		return 1;
	return 0;
}


static int hexit(char c)
	{
	if (c >= '0' && c <= '9')
	return c - '0';
	if (c >= 'a' && c <= 'f')
	return c - 'a' + 10;
	if (c >= 'A' && c <= 'F')
	return c - 'A' + 10;
	return 0;		/* shouldn't happen, we're guarded by is_hexit() */
	}

/* Figures out MIME encodings and type based on the filename.  Multiple
** encodings are separated by semicolons.
*/
static void figure_mime(HTTPD_CONN_T* hc)
{
	int i, j, k, l;
	int got_enc;
	struct table
	{
		char* ext;
		char* val;
	};
	static struct table enc_tab[] =
	{
#include "mime_encodings.h"
	};
		static struct table typ_tab[] = {
#include "mime_types.h"
	};

	/* Look at the extensions on hc->expnfilename from the back forwards. */
	hc->encodings[0] = '\0';
	i = strlen(hc->expnfilename);
	for (;;)
	{
		j = i;
		for (;;)
		{
			--i;
			if (i <= 0)
			{
				/* No extensions left. */
				hc->type = "text/plain";
				return;
			}
			if (hc->expnfilename[i] == '.')
				break;
		}
		/* Found an extension. */
		got_enc = 0;
		for (k = 0; k < sizeof(enc_tab)/sizeof(*enc_tab); ++k)
		{
			l = strlen(enc_tab[k].ext);
			if (l == j - i - 1 && strncasecmp(&hc->expnfilename[i+1], enc_tab[k].ext, l) == 0)
			{
				httpd_realloc_str (&hc->encodings, &hc->maxencodings, strlen(enc_tab[k].val) + 1);
				if (hc->encodings[0] != '\0')
					strcat(hc->encodings, ";");
				strcat(hc->encodings, enc_tab[k].val);
				got_enc = 1;
			}
		}
		if (! got_enc)
		{
			/* No encoding extension found - time to try type extensions. */
			for (k = 0; k < sizeof(typ_tab)/sizeof(*typ_tab); ++k)
			{
				l = strlen(typ_tab[k].ext);
				if (l == j - i - 1 && strncasecmp (&hc->expnfilename[i+1], typ_tab[k].ext, l) == 0)
				{
					hc->type = typ_tab[k].val;
					return;
				}
			}
			/* No recognized type extension found - return default. */
			hc->type = "text/plain";
			return;
		}
	}
}

// (+) Carl, 5-25-2002

#define MULTIPART_FORM	"multipart/form-data"
#define BOUNDARY		"boundary="
#define	LAST_TAG		"content-type:"

static int CheckMultipartForm (HTTPD_CONN_T *hc, PWEB_ENVIR pEnvir, PHTTP_INFO pInfo)
{
	ULONG	ul, ulTotal;
	LPSTR	psz, pszWork;

	psz = httpd_malloc (strlen (hc->contenttype) + 1);
	if (psz == NULL)
		return -1;
	strcpy (psz, hc->contenttype);
	WebLib_strlwr (psz);
	// is type equal to multipart/form-data?
	if (memcmp (psz, MULTIPART_FORM, strlen (MULTIPART_FORM)) == 0)
	{
		pszWork = psz + strlen (MULTIPART_FORM);
		// find the boundary string
		for (ul = 0; pszWork [ul] != 'b'; ul++);
		if (memcmp (&pszWork [ul], BOUNDARY, strlen (BOUNDARY)) == 0)
		{
			// make the ending mark
			ul += strlen (BOUNDARY) + (ULONG) strlen (MULTIPART_FORM);
			strcpy (psz, "--");
			strcat (psz, hc->contenttype + ul);
			strcat (psz, "--");
			pEnvir->pszMultipartForm = httpd_malloc (hc->contentlength);
			if (pEnvir->pszMultipartForm == NULL)
			{
				httpd_free (psz);
				return -1;
			}
			if (pInfo->ulSizeContent != (ULONG) hc->contentlength)
			{
				int		iReceived, iTotal, iRead;
				// the data is not completely received!
				iRead = hc->contentlength;
				iTotal = (int) pInfo->ulSizeContent;
				if (iTotal)
					memcpy (pEnvir->pszMultipartForm, pInfo->pszContent, iTotal);
				// If we don't not delay a while, it comes with error very often!!
				// sys_sleep (5);
				iRead -= iTotal;
				do
				{
					iReceived = httpd_recv (hc->conn_fd, pEnvir->pszMultipartForm + iTotal, iRead, 0);
					if (iReceived < 0)
					{
						httpd_free (pEnvir->pszMultipartForm);
				        httpd_free (psz);
						pEnvir->pszMultipartForm = NULL;
						return -1;
					}
					iTotal += iReceived;
					iRead -= iReceived;
				} while (iReceived != 0 && iRead);
			}
			else
				memcpy (pEnvir->pszMultipartForm, pInfo->pszContent, pInfo->ulSizeContent);
			// search data begin & verify the end of data
			if (pEnvir->pszMultipartForm != NULL)
			{
				// find data begin
				for (ul = 0; ul < (ULONG) hc->contentlength; ul++)
				{
					for (pszWork = pEnvir->pszMultipartForm + ul; 
						 pEnvir->pszMultipartForm [ul] != '\n'; ul++);
					if (*pszWork == 'c' || *pszWork == 'C')
					{
						pEnvir->pszMultipartForm [ul] = 0;
						WebLib_strlwr (pszWork);
						if (memcmp (pszWork, LAST_TAG, strlen (LAST_TAG)) == 0)
						{
							// in rfc1867 && mime format, it is terminated by CRLF pair
							ul += 3;	// CRLF + previous LF
							break;
						}
					}
				}
				pEnvir->ulOffset = ul;
				ulTotal = hc->contentlength - pEnvir->ulOffset;
				ul = (ULONG)(hc->contentlength - 2 - strlen (psz));
				if (memcmp (&pEnvir->pszMultipartForm [ul], psz, strlen (psz)) == 0)
					// CRLF will be prefix & postfix
					pEnvir->ulSizeMultipartForm = ulTotal - strlen (psz) - 4;
				else
				{
					httpd_free (pEnvir->pszMultipartForm);
					pEnvir->pszMultipartForm = NULL;
				}
			}
		}
	}
	httpd_free (psz);

	return 0;
}

// (-) Carl, 5-25-2002


// Gary Chen, 7/18/2002
static unsigned char tohex(unsigned char c)
{
	if (isdigit (c))
	{
		c = c - '0';
	}
	else
	{
		c = toupper (c) - 'A' + 10;
	}
	return(c);
}

// Gary Chen, 7/18/2002
static void httpd_convert_query_str(LPSTR psz, LPSTR pszFmt)
{
	while (*pszFmt)
	{
		switch (*pszFmt)
		{
			case '+':
				*psz++=' ';
				pszFmt++;
				break;
			case '%':
				if (isxdigit(pszFmt[1]) && isxdigit(pszFmt[2]))
				{
					unsigned char c;
					c=tohex(pszFmt[1])*16+tohex(pszFmt[2]);
					*psz++=c;
					pszFmt+=3;
				}
				else
					*psz++=*pszFmt++;
				break;
			default:
				*psz++=*pszFmt++;
				break;
		}				
	}	
	*psz++=*pszFmt++;
}

// (+) Carl, 4-19-2002
static int PostHandler (HTTPD_CONN_T* hc)
{
	// Prepare info before call
	HTTP_INFO	Info;
	WEB_ENVIR	Envir;
	LPSTR		psz, pszFmt;
	int			iRet;

	memset (&Info, 0, sizeof (HTTP_INFO));
	memset (&Envir, 0, sizeof (WEB_ENVIR));
	psz = Envir.pszEnvir = httpd_malloc (1024 * 10);
	if (Envir.pszEnvir == NULL)
	{
		httpd_send_err (hc, 503, httpd_err503title, httpd_err503form, hc->encodedurl);
		return -1;
	}
	// Prepare info.
	Info.ulIndex = hc->sb.st_size;
	Info.pszHeader = hc->read_buf;
	Info.ulSizeHeader = hc->read_idx - hc->checked_idx;
	// (+) Carl, 5-28-2002
	//	changed for CGI get
	if (hc->method == METHOD_POST)
	{
		Info.pszContent = Info.pszHeader + hc->checked_idx;
		Info.ulSizeContent = hc->read_idx - hc->checked_idx;
	}
	else
	{
		// cgi GET
		Info.pszContent = hc->query;
		Info.ulSizeContent = strlen (hc->query);
	}
	// Make the input data as string
	Info.pszContent [Info.ulSizeContent] = 0;
	// build environment
	// (+) Carl, 5-28-2002
	//	Using hc->expnfilename to replace hc->decodedurl. It is changed to suited for GET cgi
//	sprintf (psz, "%s=%s", ENVIR_Path, hc->decodedurl);
	sprintf (psz, "%s=%s", ENVIR_Path, hc->expnfilename);
	// (-) Carl, 5-28-2002
	psz += strlen (psz) + 1;
	sprintf (psz, "%s=%d.%d.%d.%d", ENVIR_Remote, IP3(hc->client_addr.s_addr),
			 IP2(hc->client_addr.s_addr), IP1(hc->client_addr.s_addr),
			 IP0(hc->client_addr.s_addr));
	psz += strlen (psz) + 1;
	sprintf (psz, "%s=%s", ENVIR_Method, httpd_method_str (hc->method));
	psz += strlen (psz) + 1;
	sprintf (psz, "%s=%s", ENVIR_Protocol, hc->protocol);
	psz += strlen (psz) + 1;
/*
	sprintf (psz, "%s=%s", ENVIR_UserAgent, hc->useragent);
	psz += strlen (psz) + 1;
*/
	// Convert the input content to environment
	pszFmt = strtok (Info.pszContent, "&");
	while (pszFmt != NULL)
	{
		// sprintf (psz, "%s", pszFmt);
		httpd_convert_query_str(psz, pszFmt);
		psz += strlen (psz) + 1;
		pszFmt = strtok (NULL, "&");
	}
	*psz = 0;
// (+) Carl, 5-24-2002
    Envir.pszMultipartForm=0;
	if (CheckMultipartForm (hc, &Envir, &Info) == -1)
	{
		httpd_send_err (hc, 503, httpd_err503title, httpd_err503form, hc->encodedurl);
		httpd_free (Envir.pszEnvir);

		return -1;
	}
	// (+) Carl, 5-29-2002
	if (hc->method == METHOD_GET || Envir.pszMultipartForm != NULL)
	{
		if (http_envir_get_string (Envir.pszEnvir, "page") == NULL)
		{
			sprintf (psz, "page=%s", szPageContent);
			// dprintf(psz);
			psz += strlen (psz) + 1;
		}
	}
	// (-) Carl, 5-29-2002

	iRet = http_submit (&Info, &Envir);
	if (iRet != CGI_OK)
	{
		switch (iRet)
		{
			case CGI_NotModified:
				psz = err304title;
				pszFmt = err302form;
				break;

			case CGI_BadRequest:
				psz = httpd_err400title;
				pszFmt = httpd_err400form;
				break;

			case CGI_Forbidden:
				psz = err403title;
				pszFmt = err403form;
				break;

			case CGI_NotFound:
				psz = err404title;
				pszFmt = err404form;
				break;

			case CGI_NotImplemented:
				psz = err501title;
				pszFmt = err501form;
				break;

			case CGI_Unavailable:
				psz = httpd_err503title;
				pszFmt = httpd_err503form;
				break;

			case CGI_InternalError:
			default:
				psz = err500title;
				pszFmt = err500form;
		}
		httpd_send_err (hc, iRet, psz, pszFmt, hc->encodedurl);
		if (Envir.pszMultipartForm)
			httpd_free (Envir.pszMultipartForm);
		httpd_free (Envir.pszEnvir);

		return -1;
	}
	// Get back path from environment & change the hc->encodedurl
	if (Envir.pszMultipartForm)
		httpd_free (Envir.pszMultipartForm);

	httpd_free (Envir.pszEnvir);
	// return the data to caller
	hc->file_address = Envir.pszOutData;
	hc->bytes = hc->sb.st_size = Envir.ulSizeOut;
	httpd_send_mime (hc, 200, ok200title, hc->encodings, "", "text/html", hc->sb.st_size, 0);

	return 0;
// (-) Carl, 5-24-2002
}
// (-) Carl, 4-19-2002

⌨️ 快捷键说明

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