由於 CGI 預設會先輸出 HTTP Status Code "200 OK",有些狀況卻會需要變更 HTTP Status Code,比如轉址,輸入帳密等。這個時候只要在第一行輸出 "Status: 302 Found\r\n" 即可。

參考網址:http://docstore.mik.ua/orelly/linux/cgi/ch03_03.htm

401 Unauthorized

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> static char *base64dec(const char *str, char buf[512]) { #define WHITESPACE 64 #define EQUALS 65 #define INVALID 66 static const unsigned char d[] = { 66,66,66,66,66,66,66,66,66,64,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,62,66,66,66,63,52,53, 54,55,56,57,58,59,60,61,66,66,66,65,66,66,66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,66,66,66,66,66,66,26,27,28, 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66 }; unsigned length = strlen(str); const unsigned char *s = (const unsigned char *)str; char *p = buf; size_t tmp = 1, len = 0; unsigned char c; while (length-- > 0) { c = d[*s++]; switch (c) { case WHITESPACE: continue; /* skip whitespace */ case INVALID: return NULL;/* invalid input, return error */ case EQUALS: /* pad character, end of data */ length = 0; continue; default: tmp = tmp << 6 | c; /* If the buffer is full, split it into bytes */ if (tmp & 0x1000000) { if ((len += 3) > 512) return NULL; /* buffer overflow */ *p++ = tmp >> 16; *p++ = tmp >> 8; *p++ = tmp; tmp = 1; } } } if (tmp & 0x40000) { if ((len += 2) > 512) return NULL; /* buffer overflow */ *p++ = tmp >> 10; *p++ = tmp >> 2; } else if (tmp & 0x1000) { if (++len > 512) return NULL; /* buffer overflow */ *p++ = tmp >> 4; } return buf; }int main(int argc, char *argv[], char *envp[]) { int cgi_fd; char *query = getenv("QUERY_STRING"); char *auth = getenv("HTTP_AUTHORIZATION"); char buf[512]={0,}; char login[] = "123:123"; // redirect stderr to console freopen("/dev/console", "w", stderr); fprintf(stderr, "enos[%s:%d,%s]start\n", __FILE__, __LINE__, __func__); fprintf(stderr, "enos[%s:%d,%s]%s\n", __FILE__, __LINE__, __func__, query); if (auth != NULL){ base64dec(auth+6, buf); fprintf(stderr, "enos[%s:%d,%s]%s\n", __FILE__, __LINE__, __func__, auth); fprintf(stderr, "enos[%s:%d,%s]%s\n", __FILE__, __LINE__, __func__, buf); } // open cgi fd cgi_fd = dup(STDOUT_FILENO); if (cgi_fd < 0) cgi_fd = STDOUT_FILENO; if (strcmp(buf, login) == 0) { dprintf(cgi_fd, "Status: 302 Found\r\n"); dprintf(cgi_fd, "Location: http://tw.yahoo.com/\r\n\r\n"); } else { dprintf(cgi_fd, "Status: 401 Unauthorized\r\n"); dprintf(cgi_fd, "WWW-Authenticate: Basic realm=\"Web Server Authentication\"\r\n\r\n"); } // stop fprintf(stderr, "enos[%s:%d,%s]stop\n", __FILE__, __LINE__, __func__); fclose(stderr); return 0; }

console 輸出

----第一次進入沒輸入 enos[main.c:127,main]start enos[main.c:128,main](null) enos[main.c:149,main]stop ----第二次進入輸入admin:admin 錯誤 enos[main.c:127,main]start enos[main.c:128,main](null) enos[main.c:131,main]Basic YWRtaW46YWRtaW4= enos[main.c:132,main]admin:admin enos[main.c:149,main]stop ----第三次進入輸入123:123 成功 enos[main.c:127,main]start enos[main.c:128,main](null) enos[main.c:131,main]Basic MTIzOjEyMw== enos[main.c:132,main]123:123 enos[main.c:149,main]stop

台南小新 發表在 痞客邦 PIXNET 留言(0) 人氣()