client_socket.c

最終更新:2009/10/10

client_socket.c

001: /* client_socket.c 
002:  * URI と Socket(Client_Socket)の例
003:  * SOCKET: 
004:  * URI:apr_uri_parse
005: */
006: 
007: #define USAGE "Usage: client_socket <url>\n"
008: 
009: #include "apr_general.h"
010: #include "apr_file_io.h"
011: #include "apr_errno.h"
012: 
013: #include "apr_network_io.h"
014: #include "apr_strings.h"
015: #include "apr_uri.h"
016: 
017: #include "mystab.h"
018: 
019: #define ERROR_BUF_SIZE 1024
020:  
021: int apr_my_main (int ac, char **av, apr_file_t * astdin, apr_file_t * astdout, apr_file_t * astderr, apr_pool_t * pool) {
022: 
023:   apr_status_t rv;
024:   char error_buf[256];
025: 
026:   char *uri_str;
027:   
028:   char *hostname = NULL;
029:   int port = 0;
030:   char *path = NULL;
031:   
032:   apr_socket_t *s=NULL;
033: 
034:   if (ac < 2) {
035:     apr_file_printf(astderr, USAGE);
036:     goto _ERROR_;
037:   }
038: 
039:   uri_str = av[1];
040: 
041:   /* URLのパース */
042: 
043:   /* URI:apr_uri_parse
044:    * INC: apr_uri.h
045:    * LIB: aprutil-1.lib
046:    */
047: 
048:   if (pool && uri_str) { /* OUTPUT: hostname, port, path */
049:     apr_uri_t uri;
050:     if (APR_SUCCESS != (rv = apr_uri_parse(pool, uri_str, &uri))) {
051:       apr_file_printf(astderr, "ERROR: apr_parse_uri: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf)));
052:       goto _ERROR_;
053:     }
054:     if (! uri.scheme || strcmp(uri.scheme, "http")) {
055:       apr_file_printf(astderr, "ERROR: unsupported scheme [%s]\n", uri.scheme);
056:     }
057:     hostname = uri.hostname;
058:     if (uri.port_str) {
059:       port = uri.port;
060:     } else {
061:       port = 80;
062:     }
063:     
064:     path = uri.path;
065:   }
066: 
067:   /* コネクションの確立 */
068: 
069:   /* SOCKET: apr_sockaddr_info_get / apr_socket_create / apr_sockaddr_ip_get / apr_socket_connect
070:    * INC: apr_uri.h
071:    * LIB: aprutil-1.lib
072:    */
073: 
074:   if (pool && hostname && port && path) { /* OUTPUT: s */
075:     apr_sockaddr_t *sa=NULL;
076:     if (APR_SUCCESS != (rv = apr_sockaddr_info_get(&sa, hostname, APR_UNSPEC, port, 0, pool))) {
077:       apr_file_printf(astderr, "ERROR: apr_sockaddr_info_get: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf)));
078:       goto _ERROR_;
079:     }
080:     if (APR_SUCCESS != (rv = apr_socket_create(&s, sa->family, SOCK_STREAM, APR_PROTO_TCP, pool))) {
081:       apr_file_printf(astderr, "ERROR: apr_socket_create: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf)));
082:       goto _ERROR_;
083:     }
084:     
085:     for (; sa!=NULL; sa=sa->next) {
086:       char *buf = apr_palloc(pool, 64);
087:       if (APR_SUCCESS == (rv = apr_sockaddr_ip_get (&buf, sa))) {
088:         
089:         if (APR_SUCCESS == (rv = apr_socket_connect(s, sa))) {
090:           apr_file_printf(astdout, "[%s]\n", buf);break;
091:         }
092:       }
093:     }
094:     
095:     if (!sa) {
096:       apr_file_printf(astderr, "ERROR: connection failed.\n");
097:       goto _ERROR_;
098:     }
099:   }
100: 
101:   /* HTTPリクエストの送信 */
102: 
103:   /* SOCKET: apr_socket_send
104:    * INC: apr_uri.h
105:    * LIB: aprutil-1.lib
106:    */
107: 
108:   if (pool && s && path && port) { /* OUTPUT: - */
109:     apr_size_t len = 0;
110:     const char *req_hdr = apr_pstrcat(pool, "GET ", path, " HTTP/1.1", "\r\n", NULL);
111:     if (port == 80) {
112:       req_hdr = apr_pstrcat(pool, req_hdr, "Host: ", hostname, "\r\n\r\n", NULL);
113:     } else {
114:       req_hdr = apr_pstrcat(pool, req_hdr, "Host: ", hostname, ":", apr_itoa(pool, port), "\r\n\r\n", NULL);
115:     }
116:     len = strlen(req_hdr);
117:     if (APR_SUCCESS != (rv = apr_socket_send(s, req_hdr, &len))) {
118:       apr_file_printf(astderr, "ERROR: apr_socket_send: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf)));
119:       goto _ERROR_;
120:     }
121:   }
122: 
123:   /* HTTPレスポンスの受信 */
124: 
125:   /* SOCKET: apr_socket_recv
126:    * INC: apr_uri.h
127:    * LIB: aprutil-1.lib
128:    */
129: 
130:   if (s) { /* OUTPUT: - */
131:     char buf[1024];
132:     apr_size_t len;
133:     while (1) {
134:       len = sizeof(buf);
135:       rv = apr_socket_recv(s, buf, &len);
136:       if (rv == APR_EOF || len == 0) {
137:         break;
138:       }
139:       apr_file_write(astdout, buf, &len);
140:     }
141:   }
142: 
143:   /* SOCKET: apr_socket_close
144:    * INC: apr_uri.h
145:    * LIB: aprutil-1.lib
146:    */
147: 
148:   if (s) apr_socket_close(s);
149:   
150: 
151:   apr_file_printf(astdout, "\ndone.\n");
152: 
153:   return 0; /* 正常終了 */
154:   
155:   _ERROR_:
156:   
157:   if (s) apr_socket_close(s);
158:   apr_file_printf(astderr, "failed!\n");
159:   return 1; /* 異常終了 */
160: }
161: 
Copyright (C) KAKU PROJECT (2009)KAKU PROJECT (2009)