/* * kcgi2.c * CGI スクリプトを処理する例 */ #include "apr_general.h" #include "apr_lib.h" #include "apr_file_io.h" #include "apr_errno.h" #include "apr_tables.h" #include "apr_buckets.h" #include "apr_strings.h" #include "apr_thread_proc.h" #include "mycgi.h" #include "mybb.h" #include "mystab.h" #define DEFAULT_DOC_ROOT "d:/work/apr/work" #define PERL_EXE_PATH "c:/perl/bin/perl.exe" #define CGI_SCRIPT_LOGICAL_PATH "/cgi-bin/hoge.pl" #define DEFAULT_PATH_ENV "c:/perl/bin" /* サーバ情報 */ typedef struct _server_ctx { char * server_name; char * server_software; int port; char *doc_root; } svr_ctx; int apr_my_main ( int ac , char **av , apr_file_t * astdin , apr_file_t * astdout , apr_file_t * astderr , apr_pool_t * pool ) { apr_status_t rv; char error_buf[256]; apr_pool_t *pool2 = NULL; cgi_ctx *cctx = NULL; svr_ctx *sctx = NULL; apr_table_t *headers = NULL; char *method = "POST"; /* char *method = "GET"; */ char *query = "key=%7E%21@%23%24%25%5E%26*%28%29_%2B"; /* char *query = NULL; char *query = "abc=123&xyz=789"; */ /* char *postdata = NULL; */ char *postdata = "key1=val1&key2=val2&key3=val3"; /* サーバ情報 */ sctx = (svr_ctx*)apr_palloc(pool, sizeof(svr_ctx)); sctx->server_name = "127.0.0.1"; sctx->port = 80; sctx->server_software = "kcgi/1.0"; sctx->doc_root = DEFAULT_DOC_ROOT; /* HTTP リクエスト情報 */ headers = apr_table_make(pool, 10); apr_table_set(headers, "Host", sctx->server_name); apr_table_set(headers, "User-Agent", "Some_brawser/1.0"); apr_table_set(headers, "Accept", "*/*"); apr_table_set(headers, "Accept-Charset", "shift_jis, utf-8"); apr_table_set(headers, "Accept-Language", "jp, en"); apr_table_set(headers, "Accept-Encoding", "gzip,compress,deflate"); if (!strcmp(method, "POST") && postdata) { apr_table_set(headers, "Content-Length", apr_itoa(pool, strlen(postdata))); apr_table_set(headers, "Content-Type", "application/x-www-form-urlencoded"); } /* 子プロセス用メモリプール生成 */ rv=apr_pool_create(&pool2, NULL); if (APR_SUCCESS != rv) { goto _FINALLY_; } /* CGIコンテクスト生成 */ /* http://127.0.0.1/cgi-bin/hoge.pl?abc=123&xyz=789 */ { apr_bucket_alloc_t *ba = apr_bucket_alloc_create(pool2); cctx = (cgi_ctx*)apr_palloc(pool2, sizeof(cgi_ctx)); cctx->pool = pool2; cctx->prog_name = PERL_EXE_PATH; cctx->script_name = apr_pstrcat(cctx->pool, sctx->doc_root, CGI_SCRIPT_LOGICAL_PATH, NULL); cctx->clen = 0; if (!strcmp(method, "POST") && postdata) { cctx->clen = strlen(postdata); cctx->bbin = apr_brigade_create(cctx->pool, ba); apr_brigade_write(cctx->bbin, NULL, NULL, postdata, cctx->clen); } else { cctx->bbin = NULL; } cctx->bbout = apr_brigade_create(cctx->pool, ba); cctx->env_tab = apr_table_make(cctx->pool, 17); apr_table_set(cctx->env_tab, "PATH", DEFAULT_PATH_ENV); apr_table_set(cctx->env_tab, "SERVER_SOFTWARE", sctx->server_software); apr_table_set(cctx->env_tab, "SERVER_NAME", sctx->server_name); apr_table_set(cctx->env_tab, "GATEWAY_INTERFACE", "CGI/1.1"); apr_table_set(cctx->env_tab, "SERVER_PROTOCOL", "HTTP/1.1"); apr_table_set(cctx->env_tab, "SERVER_PORT", apr_itoa(cctx->pool, sctx->port)); apr_table_set(cctx->env_tab, "REQUEST_METHOD", method); /* apr_table_set(cctx->env_tab, "PATH_INFO", "/"); apr_table_set(cctx->env_tab, "PATH_TRANSLATED", ""); */ apr_table_set(cctx->env_tab, "SCRIPT_NAME", "/cgi-bin/hoge.pl"); if(query) { apr_table_set(cctx->env_tab, "QUERY_STRING", query); } apr_table_set(cctx->env_tab, "REMOTE_HOST", "127.0.0.1"); apr_table_set(cctx->env_tab, "REMOTE_ADDR", "127.0.0.1"); /* apr_table_set(cctx->env_tab, "AUTH_TYPE", "basic"); apr_table_set(cctx->env_tab, "REMOTE_USER", "nemo"); */ /* apr_table_set(cctx->env_tab, "REMOTE_IDENT", ""); */ if (cctx->clen > 0) { apr_table_set(cctx->env_tab, "CONTENT_TYPE", "application/x-www-form-urlencoded"); apr_table_set(cctx->env_tab, "CONTENT_LENGTH", apr_itoa(pool, cctx->clen)); } /* HTTP リクエストのヘッダをセット * ヘッダ名の変換: * ・"HTTP_" の付加 * ・ハイフン '-' はアンダースコア '_' に変換 * ・大文字に変換 */ { int i=0; const apr_table_entry_t *telts; const apr_array_header_t *tarr = apr_table_elts(headers); telts = (const apr_table_entry_t*)tarr->elts; for (i = 0; i < tarr->nelts; i++) { char *s = NULL; char *key = apr_pstrcat(cctx->pool, "HTTP_", telts[i].key, NULL); for (s=key; *s; s++) { if (*s == '-') { *s = '_'; } else { *s = apr_toupper(*s); } } apr_table_set(cctx->env_tab, key, telts[i].val); } } } /* CGI プロセスの処理 */ { if (!invoke_cgi(cctx)) { goto _FINALLY_; } } if(read_entity_header_CRLF(cctx->bbout)) { apr_off_t len=0; apr_brigade_length(cctx->bbout, 1, &len); apr_file_printf(astdout, "Content-Length=[%d]\n", (int)len); write_from_bb_to_fp(cctx->bbout, astdout); } _FINALLY_: /* 子プロセス用メモリプールの解放 */ if (pool2) { apr_pool_destroy(pool2); pool2 = NULL; } if (rv != APR_SUCCESS) { apr_file_printf(astderr, "ERROR: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf))); apr_file_printf(astderr, "failed!\n"); return 1; /* 異常終了 */ } apr_file_printf(astdout, "\ndone.\n"); return 0; /* 正常終了 */ } /* end of main */