client_socket.c
最終更新:2009/10/10
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:
![]() | KAKU PROJECT (2009) |