📄 httpd_lib.c
字号:
}
/* 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 + -