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