BOA对于cookie的支持不是很好,google了一番,终于在chinaunix上找到了答案,主要还是对网页标头的处理不够全面引起的。补充一点,对于编写出来的cgi-bin文件,用arm-linux-gcc 3.4.1通过,提示是没有网页头,Bad Gateway,缺少LFLF,在目标板上无法运行,而使用3.4.2则OK,arm-gcc的版本问题。具体特性没有深入研究。但boa与cgi-bin的编译器最好是同一个。
修改cgi_header.c,代码如下:
if (!strncasecmp(buf, "Status: ", 8)) {
req->header_line--;
memcpy(req->header_line, "HTTP/1.0 ", 9);
} else if (!strncasecmp(buf, "Location: ", 10)) {
#ifdef FASCIST_LOGGING
log_error_time();
fprintf(stderr, "%s:%d - found Location header /"%s/"/n",
__FILE__, __LINE__, buf + 10);
#endif
if (buf[10] == '/') {
log_error_time();
fprintf(stderr,
"server does not support internal redirection: " /
"/"%s/"/n", buf + 10);
send_r_bad_request(req);
} else {
char *c2;
c2 = strchr(buf + 10, '/n');
--c2;
while (*c2 == '/r')
--c2;
++c2;
*c2++ = '/0';
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 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 { // replace end not location and not status #endif