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) |