/* client_socket.c * URI と Socket(Client_Socket)の例 * SOCKET: * URI:apr_uri_parse */ #define USAGE "Usage: client_socket \n" #include "apr_general.h" #include "apr_file_io.h" #include "apr_errno.h" #include "apr_network_io.h" #include "apr_strings.h" #include "apr_uri.h" #include "mystab.h" #define ERROR_BUF_SIZE 1024 int apr_my_main (int ac, char **av, apr_file_t * astdin, apr_file_t * astdout, apr_file_t * astderr, apr_pool_t * pool) { apr_status_t rv; char error_buf[256]; char *uri_str; char *hostname = NULL; int port = 0; char *path = NULL; apr_socket_t *s=NULL; if (ac < 2) { apr_file_printf(astderr, USAGE); goto _ERROR_; } uri_str = av[1]; /* URLのパース */ /* URI:apr_uri_parse * INC: apr_uri.h * LIB: aprutil-1.lib */ if (pool && uri_str) { /* OUTPUT: hostname, port, path */ apr_uri_t uri; if (APR_SUCCESS != (rv = apr_uri_parse(pool, uri_str, &uri))) { apr_file_printf(astderr, "ERROR: apr_parse_uri: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf))); goto _ERROR_; } if (! uri.scheme || strcmp(uri.scheme, "http")) { apr_file_printf(astderr, "ERROR: unsupported scheme [%s]\n", uri.scheme); } hostname = uri.hostname; if (uri.port_str) { port = uri.port; } else { port = 80; } path = uri.path; } /* コネクションの確立 */ /* SOCKET: apr_sockaddr_info_get / apr_socket_create / apr_sockaddr_ip_get / apr_socket_connect * INC: apr_uri.h * LIB: aprutil-1.lib */ if (pool && hostname && port && path) { /* OUTPUT: s */ apr_sockaddr_t *sa=NULL; if (APR_SUCCESS != (rv = apr_sockaddr_info_get(&sa, hostname, APR_UNSPEC, port, 0, pool))) { apr_file_printf(astderr, "ERROR: apr_sockaddr_info_get: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf))); goto _ERROR_; } if (APR_SUCCESS != (rv = apr_socket_create(&s, sa->family, SOCK_STREAM, APR_PROTO_TCP, pool))) { apr_file_printf(astderr, "ERROR: apr_socket_create: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf))); goto _ERROR_; } for (; sa!=NULL; sa=sa->next) { char *buf = apr_palloc(pool, 64); if (APR_SUCCESS == (rv = apr_sockaddr_ip_get (&buf, sa))) { if (APR_SUCCESS == (rv = apr_socket_connect(s, sa))) { apr_file_printf(astdout, "[%s]\n", buf);break; } } } if (!sa) { apr_file_printf(astderr, "ERROR: connection failed.\n"); goto _ERROR_; } } /* HTTPリクエストの送信 */ /* SOCKET: apr_socket_send * INC: apr_uri.h * LIB: aprutil-1.lib */ if (pool && s && path && port) { /* OUTPUT: - */ apr_size_t len = 0; const char *req_hdr = apr_pstrcat(pool, "GET ", path, " HTTP/1.1", "\r\n", NULL); if (port == 80) { req_hdr = apr_pstrcat(pool, req_hdr, "Host: ", hostname, "\r\n\r\n", NULL); } else { req_hdr = apr_pstrcat(pool, req_hdr, "Host: ", hostname, ":", apr_itoa(pool, port), "\r\n\r\n", NULL); } len = strlen(req_hdr); if (APR_SUCCESS != (rv = apr_socket_send(s, req_hdr, &len))) { apr_file_printf(astderr, "ERROR: apr_socket_send: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf))); goto _ERROR_; } } /* HTTPレスポンスの受信 */ /* SOCKET: apr_socket_recv * INC: apr_uri.h * LIB: aprutil-1.lib */ if (s) { /* OUTPUT: - */ char buf[1024]; apr_size_t len; while (1) { len = sizeof(buf); rv = apr_socket_recv(s, buf, &len); if (rv == APR_EOF || len == 0) { break; } apr_file_write(astdout, buf, &len); } } /* SOCKET: apr_socket_close * INC: apr_uri.h * LIB: aprutil-1.lib */ if (s) apr_socket_close(s); apr_file_printf(astdout, "\ndone.\n"); return 0; /* 正常終了 */ _ERROR_: if (s) apr_socket_close(s); apr_file_printf(astderr, "failed!\n"); return 1; /* 異常終了 */ }