kcgi.c
最終更新:2009/12/16
001: /* 002: * kcgi2.c 003: * CGI スクリプトを処理する例 004: */ 005: 006: #include "apr_general.h" 007: #include "apr_lib.h" 008: #include "apr_file_io.h" 009: #include "apr_errno.h" 010: #include "apr_tables.h" 011: #include "apr_buckets.h" 012: #include "apr_strings.h" 013: #include "apr_thread_proc.h" 014: 015: #include "mycgi.h" 016: #include "mybb.h" 017: #include "mystab.h" 018: 019: #define DEFAULT_DOC_ROOT "d:/work/apr/work" 020: #define PERL_EXE_PATH "c:/perl/bin/perl.exe" 021: 022: #define CGI_SCRIPT_LOGICAL_PATH "/cgi-bin/hoge.pl" 023: 024: #define DEFAULT_PATH_ENV "c:/perl/bin" 025: 026: /* サーバ情報 */ 027: 028: typedef struct _server_ctx { 029: char * server_name; 030: char * server_software; 031: int port; 032: 033: char *doc_root; 034: 035: } svr_ctx; 036: 037: int apr_my_main ( 038: int ac 039: , char **av 040: , apr_file_t * astdin 041: , apr_file_t * astdout 042: , apr_file_t * astderr 043: , apr_pool_t * pool 044: ) { 045: 046: apr_status_t rv; 047: char error_buf[256]; 048: 049: apr_pool_t *pool2 = NULL; 050: cgi_ctx *cctx = NULL; 051: svr_ctx *sctx = NULL; 052: 053: apr_table_t *headers = NULL; 054: 055: char *method = "POST"; 056: /* 057: char *method = "GET"; 058: */ 059: 060: char *query = "key=%7E%21@%23%24%25%5E%26*%28%29_%2B"; 061: /* 062: char *query = NULL; 063: char *query = "abc=123&xyz=789"; 064: */ 065: 066: /* 067: char *postdata = NULL; 068: */ 069: char *postdata = "key1=val1&key2=val2&key3=val3"; 070: 071: /* サーバ情報 */ 072: sctx = (svr_ctx*)apr_palloc(pool, sizeof(svr_ctx)); 073: sctx->server_name = "127.0.0.1"; 074: sctx->port = 80; 075: sctx->server_software = "kcgi/1.0"; 076: sctx->doc_root = DEFAULT_DOC_ROOT; 077: 078: 079: /* HTTP リクエスト情報 */ 080: 081: headers = apr_table_make(pool, 10); 082: apr_table_set(headers, "Host", sctx->server_name); 083: apr_table_set(headers, "User-Agent", "Some_brawser/1.0"); 084: apr_table_set(headers, "Accept", "*/*"); 085: apr_table_set(headers, "Accept-Charset", "shift_jis, utf-8"); 086: apr_table_set(headers, "Accept-Language", "jp, en"); 087: apr_table_set(headers, "Accept-Encoding", "gzip,compress,deflate"); 088: 089: if (!strcmp(method, "POST") && postdata) { 090: apr_table_set(headers, "Content-Length", apr_itoa(pool, strlen(postdata))); 091: apr_table_set(headers, "Content-Type", "application/x-www-form-urlencoded"); 092: } 093: 094: /* 子プロセス用メモリプール生成 */ 095: 096: rv=apr_pool_create(&pool2, NULL); 097: if (APR_SUCCESS != rv) { 098: goto _FINALLY_; 099: } 100: 101: /* CGIコンテクスト生成 */ 102: 103: /* http://127.0.0.1/cgi-bin/hoge.pl?abc=123&xyz=789 */ 104: 105: { 106: apr_bucket_alloc_t *ba = apr_bucket_alloc_create(pool2); 107: cctx = (cgi_ctx*)apr_palloc(pool2, sizeof(cgi_ctx)); 108: cctx->pool = pool2; 109: cctx->prog_name = PERL_EXE_PATH; 110: cctx->script_name = apr_pstrcat(cctx->pool, sctx->doc_root, CGI_SCRIPT_LOGICAL_PATH, NULL); 111: 112: cctx->clen = 0; 113: 114: if (!strcmp(method, "POST") && postdata) { 115: cctx->clen = strlen(postdata); 116: cctx->bbin = apr_brigade_create(cctx->pool, ba); 117: apr_brigade_write(cctx->bbin, NULL, NULL, postdata, cctx->clen); 118: } else { 119: cctx->bbin = NULL; 120: } 121: cctx->bbout = apr_brigade_create(cctx->pool, ba); 122: 123: cctx->env_tab = apr_table_make(cctx->pool, 17); 124: apr_table_set(cctx->env_tab, "PATH", DEFAULT_PATH_ENV); 125: apr_table_set(cctx->env_tab, "SERVER_SOFTWARE", sctx->server_software); 126: apr_table_set(cctx->env_tab, "SERVER_NAME", sctx->server_name); 127: apr_table_set(cctx->env_tab, "GATEWAY_INTERFACE", "CGI/1.1"); 128: apr_table_set(cctx->env_tab, "SERVER_PROTOCOL", "HTTP/1.1"); 129: apr_table_set(cctx->env_tab, "SERVER_PORT", apr_itoa(cctx->pool, sctx->port)); 130: apr_table_set(cctx->env_tab, "REQUEST_METHOD", method); 131: /* 132: apr_table_set(cctx->env_tab, "PATH_INFO", "/"); 133: apr_table_set(cctx->env_tab, "PATH_TRANSLATED", ""); 134: */ 135: 136: apr_table_set(cctx->env_tab, "SCRIPT_NAME", "/cgi-bin/hoge.pl"); 137: 138: if(query) { 139: apr_table_set(cctx->env_tab, "QUERY_STRING", query); 140: } 141: apr_table_set(cctx->env_tab, "REMOTE_HOST", "127.0.0.1"); 142: apr_table_set(cctx->env_tab, "REMOTE_ADDR", "127.0.0.1"); 143: /* 144: apr_table_set(cctx->env_tab, "AUTH_TYPE", "basic"); 145: apr_table_set(cctx->env_tab, "REMOTE_USER", "nemo"); 146: */ 147: /* 148: apr_table_set(cctx->env_tab, "REMOTE_IDENT", ""); 149: */ 150: if (cctx->clen > 0) { 151: apr_table_set(cctx->env_tab, "CONTENT_TYPE", "application/x-www-form-urlencoded"); 152: apr_table_set(cctx->env_tab, "CONTENT_LENGTH", apr_itoa(pool, cctx->clen)); 153: } 154: 155: 156: /* HTTP リクエストのヘッダをセット 157: * ヘッダ名の変換: 158: * ・"HTTP_" の付加 159: * ・ハイフン '-' はアンダースコア '_' に変換 160: * ・大文字に変換 161: */ 162: { 163: int i=0; 164: const apr_table_entry_t *telts; 165: const apr_array_header_t *tarr = apr_table_elts(headers); 166: telts = (const apr_table_entry_t*)tarr->elts; 167: for (i = 0; i < tarr->nelts; i++) { 168: char *s = NULL; 169: char *key = apr_pstrcat(cctx->pool, "HTTP_", telts[i].key, NULL); 170: for (s=key; *s; s++) { 171: if (*s == '-') { 172: *s = '_'; 173: } else { 174: *s = apr_toupper(*s); 175: } 176: } 177: apr_table_set(cctx->env_tab, key, telts[i].val); 178: } 179: } 180: 181: } 182: 183: /* CGI プロセスの処理 */ 184: 185: { 186: 187: if (!invoke_cgi(cctx)) { 188: goto _FINALLY_; 189: } 190: } 191: 192: if(read_entity_header_CRLF(cctx->bbout)) { 193: apr_off_t len=0; 194: apr_brigade_length(cctx->bbout, 1, &len); 195: apr_file_printf(astdout, "Content-Length=[%d]\n", (int)len); 196: write_from_bb_to_fp(cctx->bbout, astdout); 197: } 198: 199: _FINALLY_: 200: 201: /* 子プロセス用メモリプールの解放 */ 202: 203: if (pool2) { 204: apr_pool_destroy(pool2); 205: pool2 = NULL; 206: } 207: 208: if (rv != APR_SUCCESS) { 209: apr_file_printf(astderr, "ERROR: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf))); 210: apr_file_printf(astderr, "failed!\n"); 211: return 1; /* 異常終了 */ 212: } 213: 214: apr_file_printf(astdout, "\ndone.\n"); 215: 216: return 0; /* 正常終了 */ 217: 218: } /* end of main */
KAKU PROJECT (2009) |