newzy
- UID
- 35409
- 帖子
- 106
- 积分
- 243
- 在线时间
- 15 小时
|
3#
newzy 发表于 2006-09-07 17:58
修正方法
CGI 应答头包括多行, 我们必须对其进行逐行分析, 并作出正确的应答.
下面是修改好的源程序, 即将原来的 82-136 (即相当下文#else, #endif内部分) 替换成如下代码:
[Copy to clipboard] [ - ]
CODE:
#if 1
while(1) {
int len;
char * pnext = NULL;
char * ptmp = NULL;
/* not find HTTP header tailer */
if (NULL == (pnext=strchr(buf, '\n'))) /* has no '\n' */
break;
/* the length of this line,
* include '\n'
*/
len = pnext - buf + 1;
if (!strncasecmp(buf, "Location: ", 10)) { /* got a location header */
/* not the first one
* exchange this line to the first line
*/
if (buf != req->header_line)
{
if (NULL == (ptmp=(char *)malloc(len)))
{
log_error_time();
perror("malloc");
send_r_error(req);
return 0;
}
/* move Status: to line header */
memcpy(ptmp, buf, len);
memmove(req->header_line+len, req->header_line, buf-req->header_line);
memcpy(req->header_line, ptmp, len);
free(ptmp);
}
/* force pointer header */
buf = req->header_line;
#ifdef FASCIST_LOGGING
log_error_time();
fprintf(stderr, "%s:%d - found Location header \"%s\"\n",
__FILE__, __LINE__, buf + 10);
#endif
if (buf[10] == '/') { /* virtual path */
log_error_time();
fprintf(stderr,
"server does not support internal redirection: " \
"\"%s\"\n", buf + 10);
send_r_bad_request(req);
/*
* We (I, Jon) have declined to support absolute-path parsing
* because I see it as a major security hole.
* Location: /etc/passwd or Location: /etc/shadow is not funny.
*
* Also, the below code is borked.
* request_uri could contain /cgi-bin/bob/extra_path
*/
/*
strcpy(req->request_uri, buf + 10);
return internal_redirect(req);
*/
} else { /* URL */
char *c2;
c2 = strchr(buf + 10, '\n');
/* c2 cannot ever equal NULL here because we already have found one */
--c2;
while (*c2 == '\r')
--c2;
++c2;
/* c2 now points to a '\r' or the '\n' */
*c2++ = '\0'; /* end header */
/* first next header, or is at req->header_end */
while ((*c2 == '\n' || *c2 == '\r') && c2 < req->header_end)
++c2;
if (c2 == req->header_end)
send_r_moved_temp(req, buf + 10, "");
else
send_r_moved_temp(req, buf + 10, c2);
}
req->status = DONE;
return 1;
} else if (!strncasecmp(buf, "Status: ", 8)) {
/* not the first one
* exchange this line to the first line
*/
if (buf != req->header_line)
{
if (NULL == (ptmp=(char *)malloc(len)))
{
log_error_time();
perror("malloc");
send_r_error(req);
return 0;
}
/* move Status: to line header */
memcpy(ptmp, buf, len);
memmove(req->header_line+len, req->header_line, buf-req->header_line);
memcpy(req->header_line, ptmp, len);
free(ptmp);
}
req->header_line--;
memcpy(req->header_line, "HTTP/1.0 ", 9);
return 1;
}
/* pointer to next line */
buf = pnext + 1;
/* reach the end of HTTP header */
if ('\0' == buf[0] || '\n' == buf[0] || '\r' == buf[0])
break;
}
if (1) { /* always done */
#else
if (!strncasecmp(buf, "Status: ", 8)) {
req->header_line--;
memcpy(req->header_line, "HTTP/1.0 ", 9);
} else if (!strncasecmp(buf, "Location: ", 10)) { /* got a location header */
#ifdef FASCIST_LOGGING
log_error_time();
fprintf(stderr, "%s:%d - found Location header \"%s\"\n",
__FILE__, __LINE__, buf + 10);
#endif
if (buf[10] == '/') { /* virtual path */
log_error_time();
fprintf(stderr,
"server does not support internal redirection: " \
"\"%s\"\n", buf + 10);
send_r_bad_request(req);
/*
* We (I, Jon) have declined to support absolute-path parsing
* because I see it as a major security hole.
* Location: /etc/passwd or Location: /etc/shadow is not funny.
*
* Also, the below code is borked.
* request_uri could contain /cgi-bin/bob/extra_path
*/
/*
strcpy(req->request_uri, buf + 10);
return internal_redirect(req);
*/
} else { /* URL */
char *c2;
c2 = strchr(buf + 10, '\n');
/* c2 cannot ever equal NULL here because we already have found one */
--c2;
while (*c2 == '\r')
--c2;
++c2;
/* c2 now points to a '\r' or the '\n' */
*c2++ = '\0'; /* end header */
/* first next header, or is at req->header_end */
while ((*c2 == '\n' || *c2 == '\r') && c2 < req->header_end)
++c2;
if (c2 == req->header_end)
send_r_moved_temp(req, buf + 10, "");
else
send_r_moved_temp(req, buf + 10, c2);
}
req->status = DONE;
return 1;
} else { /* not location and not status */
#endif
|