kmyio_htget.c
最終更新:2009/12/19
001: /*
002: * kmyio_htget.c
003: * HTTP/1.0 でWebサイトに接続してファイルに保存する。
004: */
005:
006: #define USAGE "Usage: kmtio_htget <uri> <out_filename>"
007:
008: #include "apr_general.h"
009: #include "apr_lib.h"
010:
011: #include "apr_errno.h"
012: #include "apr_strings.h"
013: #include "apr_uri.h"
014: #include "apr_tables.h"
015:
016: #include "mystab.h"
017: #include "myio_chunk.h"
018: #include "myio_apr.h"
019: #include "myht_util.h"
020:
021: void * my_alloc(void *alloc_func_ctx, int alloc_size) {
022: apr_pool_t *pool = (apr_pool_t*)alloc_func_ctx;
023: return apr_palloc(pool, alloc_size);
024: }
025:
026: int apr_my_main (
027: int ac
028: , char **av
029: , apr_file_t * astdin
030: , apr_file_t * astdout
031: , apr_file_t * astderr
032: , apr_pool_t * pool
033: ) {
034:
035: int error_flag = 0;
036: apr_status_t rv = APR_SUCCESS;
037:
038: char *uri_str = NULL;
039: char *out_filename = NULL;
040:
041: apr_uri_t uri;
042:
043: char *hostname = NULL;
044: int port = 0;
045:
046: MYIO *io = NULL;
047: MYIO *out = NULL;
048: MYIO *in = NULL;
049:
050: apr_table_t * rsp_headers = NULL;
051:
052: if (ac < 3) {
053: apr_file_printf(astderr, "%s\n", USAGE);
054: error_flag = 1;
055: goto _FINALLY_;
056: }
057:
058: uri_str = av[1];
059: out_filename = av[2];
060:
061: if (! my_uri_parse(pool, uri_str, &uri)) {
062: apr_file_printf(astderr, "ERROR: uri [%s] ", uri_str);
063: error_flag = 1;
064: goto _FINALLY_;
065: }
066:
067: hostname = uri.hostname;
068: port = uri.port;
069:
070: /* サーバへの接続 */
071:
072: io = MYIO_sock_connect(hostname, port, pool);
073: if (!io) {
074: apr_file_printf(astderr, "ERROR: connect [%s:%d] ", hostname, port);
075: error_flag = 1;
076: goto _FINALLY_;
077: }
078:
079: /* 出力ファイルのオープン */
080:
081: out = MYIO_fp_open(out_filename,
082: APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_BINARY|APR_FOPEN_TRUNCATE,
083: APR_OS_DEFAULT, pool);
084: if (!out) {
085: apr_file_printf(astderr, "ERROR: file open [%s] ", out_filename);
086: error_flag = 1;
087: goto _FINALLY_;
088: }
089:
090: /* リクエストの送信 */
091:
092: {
093: int nbytes = 0;
094: char *req = apr_pstrcat(pool, "GET ", uri.path, " HTTP/1.0\r\n", NULL);
095: if (uri.port == 80) {
096: req = apr_pstrcat(pool, req, "Host: ", uri.hostname, "\r\n", NULL);
097: } else {
098: req = apr_pstrcat(pool, req, "Host: ", uri.hostname, ":", uri.port_str,
099: "\r\n", NULL);
100: }
101: req = apr_pstrcat(pool, req, "Accept: */*\r\n", NULL);
102: /*
103: req = apr_pstrcat(pool, req,
104: "Accept-Encoding: gzip, compress, deflate, identity\r\n", NULL);
105: req = apr_pstrcat(pool, req, "Connection: close\r\n", NULL);
106: */
107: req = apr_pstrcat(pool, req, "User-Agent: kmyio_htget/0.1\r\n\r\n", NULL);
108:
109: nbytes = MYIO_write(io, req, strlen(req));
110: if (nbytes <= 0) {
111: error_flag = 1;
112: goto _FINALLY_;
113: }
114: }
115:
116: /* バッファリングフィルタ */
117: {
118: in = MYIO_buf_filter_new(io, 2048, my_alloc, pool);
119: if (!in) {
120: apr_file_printf(astderr, "ERROR: MYIO_buf_filter_new ");
121: error_flag = 1;
122: goto _FINALLY_;
123: }
124: }
125:
126: /* レスポンスラインの受信 */
127:
128: {
129: char rsp_line[1024];
130: char *rsp_version=NULL;
131: char *status_str=NULL;
132: char *reason_phrase=NULL;
133: int ret = 0;
134:
135: if (MYIO_gets(in, rsp_line, sizeof(rsp_line)) < 0) {
136: error_flag = 1;
137: goto _FINALLY_;
138: }
139: ret = read_rsp_line(rsp_line,
140: &rsp_version, &status_str, &reason_phrase, ' ');
141: if (ret < 3) {
142: apr_file_printf(astderr, "ERROR: read_rsp_line ");
143: error_flag = 1;
144: goto _FINALLY_;
145: }
146: apr_file_printf(astdout, "[%s] [%s] [%s]\n",
147: rsp_version, status_str, reason_phrase);
148: }
149:
150: /* レスポンスヘッダの受信 */
151:
152: rsp_headers = apr_table_make(pool, 10);
153: {
154: int ret = MYIO_read_entity_headers_CRLF_do(in, set_entity_header_to_tab,
155: rsp_headers);
156: if (! ret) {
157: apr_file_printf(astderr, "ERROR: bio_read_entity_headers_CRLF_do ");
158: error_flag = 1;
159: goto _FINALLY_;
160: }
161: }
162:
163: /* レスポンスヘッダの表示 */
164:
165: apr_table_do(disp_tab, astdout, rsp_headers, NULL);
166:
167: /* レスポンスの受信〜ファイル出力 */
168:
169: {
170: char buf[1024];
171: while (1) {
172: int nbytes = MYIO_read(in, buf, sizeof(buf));
173: if (nbytes <= 0) {
174: break;
175: }
176: nbytes = MYIO_write(out, buf, nbytes);
177: if (nbytes < 0) {
178: break;
179: }
180: }
181: }
182:
183: _FINALLY_:
184:
185: if (out) {
186: MYIO_fp_close(out);
187: out = NULL;
188: }
189:
190: if (io) {
191: MYIO_sock_close(io);
192: io = NULL;
193: }
194:
195: if (in) {
196: MYIO_buf_free(in, NULL, NULL);
197: in = NULL;
198: }
199:
200: if (rv != APR_SUCCESS) {
201: char error_buf[80];
202: apr_file_printf(astderr, "ERROR: %s\n",
203: apr_strerror(rv, error_buf, sizeof(error_buf)));
204: }
205:
206: if (error_flag) {
207: apr_file_printf(astderr, "failed!\n");
208: return 1; /* 異常終了 */
209: }
210:
211: apr_file_printf(astdout, "\ndone.\n");
212:
213: return 0; /* 正常終了 */
214:
215: } /* end of main */
![]() | KAKU PROJECT (2009) |