📄 httpd_lib.c
字号:
httpd_realloc_str(&hc->accepte, &hc->maxaccepte, strlen(cp));
strcpy(hc->accepte, cp);
}
#ifdef _USE_TIME
else if (strncasecmp(buf, "If-Modified-Since:", 18) == 0)
{
cp = &buf[18];
hc->if_modified_since = tdate_parse(cp);
// if (hc->if_modified_since == (time_t) -1)
//syslog(LOG_DEBUG, "unparsable time: %.80s", cp);
}
#endif
else if (strncasecmp(buf, "Cookie:", 7) == 0)
{
cp = &buf[7];
cp += strspn(cp, " \t");
hc->cookie = cp;
}
else if (strncasecmp(buf, "Range:", 6) == 0)
{
/* Only support %d- and %d-%d, not %d-%d,%d-%d or -%d. */
if (strchr(buf, ',') == (char*) 0)
{
char* cp_dash;
cp = strpbrk(buf, "=");
if (cp != (char*) 0)
{
cp_dash = strchr(cp + 1, '-');
if (cp_dash != (char*) 0 && cp_dash != cp + 1)
{
*cp_dash = '\0';
hc->got_range = 1;
hc->init_byte_loc = atol(cp + 1);
if (isdigit((int) cp_dash[1]))
hc->end_byte_loc = atol(cp_dash + 1);
}
}
}
}
else if (strncasecmp(buf, "Range-If:", 9) == 0 ||
strncasecmp(buf, "If-Range:", 9) == 0)
{
cp = &buf[9];
hc->range_if = tdate_parse(cp);
// if (hc->range_if == (time_t) -1)
//syslog(LOG_DEBUG, "unparsable time: %.80s", cp);
}
else if (strncasecmp(buf, "Content-Type:", 13) == 0)
{
cp = &buf[13];
cp += strspn(cp, " \t");
hc->contenttype = cp;
}
else if (strncasecmp(buf, "Content-Length:", 15) == 0)
{
cp = &buf[15];
hc->contentlength = atol(cp);
}
else if (strncasecmp(buf, "Authorization:", 14) == 0)
{
cp = &buf[14];
cp += strspn(cp, " \t");
hc->authorization = cp;
}
else if (strncasecmp(buf, "Connection:", 11) == 0)
{
cp = &buf[11];
cp += strspn(cp, " \t");
if (strcasecmp(cp, "keep-alive") == 0)
hc->keep_alive = 1;
}
}
}
if (hc->one_one)
{
/* Check that HTTP/1.1 requests specify a host, as required. */
if (hc->reqhost[0] == '\0' && hc->hdrhost[0] == '\0')
{
httpd_send_err(hc, 400, httpd_err400title, httpd_err400form, "");
return -1;
}
/* If the client wants to do keep-alives, it might also be doing
** pipelining. There's no way for us to tell. Since we don't
** implement keep-alives yet, if we close such a connection there
** might be unread pipelined requests waiting. So, we have to
** do a lingering close.
*/
if (hc->keep_alive)
hc->should_linger = 1;
}
/* Ok, the request has been parsed. Now we resolve stuff that
** may require the entire request.
*/
/* Copy original filename to expanded filename. */
httpd_realloc_str (&hc->expnfilename, &hc->maxexpnfilename, strlen(hc->origfilename));
strcpy(hc->expnfilename, hc->origfilename);
#if 0
if (hc->expnfilename[0] == '~')
{
}
#endif
/* If the expanded filename is an absolute path, check that it's still
** within the current directory or the alternate directory.
*/
return 0;
}
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_start_request
*-----------------------------------------------------------------------
* DESCRIPTION: Start to handle HTTP client request
* INPUT : HTTPD_CONN_T* hc
* OUTPUT : int
*----------------------------------------------------------------------*/
int httpd_start_request(HTTPD_CONN_T* hc)
{
int r;
r = httpd_really_start_request(hc);
return r;
}
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_really_start_request
*-----------------------------------------------------------------------
* DESCRIPTION: Start to handle HTTP client request
* INPUT : HTTPD_CONN_T* hc
* OUTPUT : int
*----------------------------------------------------------------------*/
static int httpd_really_start_request(HTTPD_CONN_T* hc)
{
// dprintf("hc->expnfilename=%s\n", hc->expnfilename);
if (hc->method != METHOD_GET && hc->method != METHOD_HEAD &&
hc->method != METHOD_POST)
{
// dprintf("hc->method=%d\n", hc->method);
httpd_send_err(hc, 500, err500title, err500form, hc->encodedurl);
return -1;
}
#if 0 // old
/* Stat the file. */
if (http_stat(hc->expnfilename, &hc->sb, (hc->method == METHOD_POST) ? 1 : 0) < 0)
{
httpd_send_err(hc, 500, err500title, err500form, hc->encodedurl);
return -1;
}
#endif
{
// (+) Car, 5-28-2002
// changed for cgi GET
int i;
if ((hc->method == METHOD_GET && strcmp(hc->expnfilename, "config.bin")==0) )
i=0;
else if (hc->method == METHOD_POST || (hc->method == METHOD_GET && *hc->query != 0))
i = http_stat (hc->expnfilename, &hc->sb, 1);
else
i = http_stat (hc->expnfilename, &hc->sb, 0);
if (i < 0)
{
httpd_send_err(hc, 500, err500title, err500form, hc->encodedurl);
return -1;
}
// (-) Carl, 5-28-2002
}
// (+) Carl, 4-18-2002
if (auth_check (hc, hc->expnfilename) == -1)
return -1;
// (-) Carl, 4-18-2002
// (+) Carl, 5-28-2002
// deal with POST/GET CGI method now
if (hc->method == METHOD_POST || (hc->method == METHOD_GET && *hc->query != 0))
return PostHandler (hc);
// (-) Carl, 5-28-2002
/* Fill in end_byte_loc if necessary. */
if (hc->got_range && (hc->end_byte_loc == -1 || hc->end_byte_loc >= hc->sb.st_size))
hc->end_byte_loc = hc->sb.st_size - 1;
figure_mime(hc);
if (hc->method == METHOD_HEAD)
{
hc->bytes = 0;
httpd_send_mime (hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size, hc->sb.st_mtime);
}
else
if (hc->if_modified_since != (time_t) -1 && hc->if_modified_since == hc->sb.st_mtime)
{
hc->method = METHOD_HEAD;
hc->bytes = 0;
httpd_send_mime(hc, 304, err304title, hc->encodings, "", hc->type, hc->sb.st_size,
hc->sb.st_mtime);
}
else if (strcmp(hc->expnfilename, "config.bin")==0)
{
UI8_T *cfg_file=(UI8_T *)image_create_cfg_file();
hc->bytes=IMG_WORK_CFG_FILE_SIZE+IMG_HDR_BLK_SIZE;
if ((hc->file_address=(char *)httpd_malloc(hc->bytes))==0)
{
httpd_send_err (hc, 500, err500title, err500form, hc->encodedurl);
return -1;
}
memcpy(hc->file_address,cfg_file,hc->bytes);
httpd_send_mime (hc, 200, ok200title, hc->encodings, "", hc->type, hc->bytes,
0);
}
else
{
hc->file_address = httpd_mmc_map (hc->expnfilename, &(hc->sb));
if (hc->file_address == NULL)
{
httpd_send_err (hc, 500, err500title, err500form, hc->encodedurl);
return -1;
}
hc->bytes = hc->sb.st_size;
httpd_send_mime (hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size,
hc->sb.st_mtime);
}
return 0;
}
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_method_str
*-----------------------------------------------------------------------
* DESCRIPTION: Get HTTP client request method
* INPUT : HTTPD_CONN_T* hc
* OUTPUT : int
*----------------------------------------------------------------------*/
static char* httpd_method_str(int method)
{
switch (method)
{
case METHOD_GET:
return "GET";
case METHOD_HEAD:
return "HEAD";
case METHOD_POST:
return "POST";
default:
return (char*) 0;
}
}
/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_bufgets
*-----------------------------------------------------------------------
* DESCRIPTION:
* INPUT : HTTPD_CONN_T* hc
* OUTPUT : int
*----------------------------------------------------------------------*/
static char* httpd_bufgets(HTTPD_CONN_T* hc)
{
int i;
char c;
for (i = hc->checked_idx; hc->checked_idx < hc->read_idx; ++hc->checked_idx)
{
c = hc->read_buf[hc->checked_idx];
if (c == '\n' || c == '\r')
{
hc->read_buf[hc->checked_idx] = '\0';
++hc->checked_idx;
if (c == '\r' && hc->checked_idx < hc->read_idx &&
hc->read_buf[hc->checked_idx] == '\n')
{
hc->read_buf[hc->checked_idx] = '\0';
++hc->checked_idx;
}
return &(hc->read_buf[i]);
}
}
return (char*) 0;
}
/* Append a string to the buffer waiting to be sent as response. */
void httpd_add_response(HTTPD_CONN_T* hc, char* str)
{
int len;
len = strlen(str);
httpd_realloc_str(&hc->response, &hc->maxresponse, hc->responselen + len);
memcpy(&(hc->response[hc->responselen]), str, len);
hc->responselen += len;
}
/* Send the buffered response. */
void httpd_write_response(HTTPD_CONN_T* hc)
{
int flags;
/* And send it, if necessary. */
if (hc->responselen > 0)
{
write(hc->conn_fd, hc->response, hc->responselen);
hc->responselen = 0;
}
}
static void httpd_send_mime(HTTPD_CONN_T* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod)
{
#ifdef _USE_TIME
time_t now;
const char* rfc1123fmt = "%a, %d %b %Y %H:%M:%S GMT";
char nowbuf[100];
char modbuf[100];
#endif
char buf[1000];
int partial_content;
hc->status = status;
hc->bytes = length;
if (hc->mime_flag)
{
if (status == 200 && hc->got_range && (hc->end_byte_loc >= hc->init_byte_loc) &&
((hc->end_byte_loc != length - 1) || (hc->init_byte_loc != 0)) &&
(hc->range_if == (time_t) -1 || hc->range_if == hc->sb.st_mtime))
{
partial_content = 1;
hc->status = status = 206;
title = ok206title;
}
else
partial_content = 0;
#ifdef _USE_TIME
now = time((time_t*) 0);
if (mod == (time_t) 0)
mod = now;
strftime(nowbuf, sizeof(nowbuf), rfc1123fmt, gmtime(&now));
strftime(modbuf, sizeof(modbuf), rfc1123fmt, gmtime(&mod));
snprintf(buf, sizeof(buf),
"%.20s %d %s\r\nServer: %s\r\nContent-type: %s\r\nDate: %s\r\nLast-modified: %s\r\nAccept-Ranges: bytes\r\nConnection: close\r\n",
hc->protocol, status, title, SERVER_SOFTWARE, type, nowbuf,
modbuf);
#else
snprintf(buf, sizeof(buf),
//"%.20s %d %s\r\nServer: %s\r\nConnection: close\r\nContent-type: %s\r\n",
"%.20s %d %s\r\nServer: %s\r\nContent-type: %s\r\n",
hc->protocol, status, title, SERVER_SOFTWARE, type);
if (memcmp(hc->expnfilename, "images/", 7)==0)
strcat(buf, "Last-modified: Mon 2 Sep 2002 10:10:10\r\nExpires: Fri 6 Sep 2012 10:10:10\r\n");
//dprintf("-->%s\r\n",hc->expnfilename);
#endif
httpd_add_response(hc, buf);
#if 0 // gary 9/5/2002
if (encodings[0] != '\0')
{
snprintf(buf, sizeof(buf),
"Content-encoding: %s\r\n", encodings);
httpd_add_response(hc, buf);
}
#endif
if (partial_content)
{
snprintf(buf, sizeof(buf),
"Content-range: bytes %ld-%ld/%d\r\nContent-length: %ld\r\n",
(long) hc->init_byte_loc, (long) hc->end_byte_loc, length,
(long) (hc->end_byte_loc - hc->init_byte_loc + 1));
httpd_add_response(hc, buf);
}
else
if (length >= 0)
{
snprintf(buf, sizeof(buf),
"Content-length: %d\r\n", length);
httpd_add_response(hc, buf);
}
if (extraheads[0] != '\0')
httpd_add_response(hc, extraheads);
httpd_add_response(hc, "\r\n");
}
}
void httpd_send_response (HTTPD_CONN_T* hc, int status, char* title, char* extrahead, char* form, char* arg)
{
char buf[1000];
httpd_send_mime (hc, status, title, "", extrahead, "text/html", -1, 0);
snprintf(buf, sizeof(buf),
"<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\n<BODY BGCOLOR=\"#cc9999\"><H2>%d %s</H2>\n",
status, title, status, title);
httpd_add_response(hc, buf);
snprintf(buf, sizeof(buf),form, arg);
httpd_add_response(hc, buf);
snprintf(buf, sizeof(buf),"<HR>\n%</HTML>\n",SERVER_SOFTWARE);
httpd_add_response(hc, buf);
}
void httpd_send_err(HTTPD_CONN_T* hc, int status, char* title, char* form, char* arg)
{
httpd_send_response (hc, status, title, "", form, arg);
}
static LPVOID httpd_mmc_map (LPSTR filename, HTTP_STAT_T* sbP)
{
HTTP_STAT_T sb;
HTTP_FILE *fd;
INT len=0;
LPSTR addr;
/* Stat the file if necessary. */
if (sbP != (HTTP_STAT_T *) 0)
sb = *sbP;
else
{
// find URI page file and get the associated state
if (http_stat (filename, &sb, 0) != 0)
{
// syslog(LOG_ERR, "stat - %m");
return (void*) 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -