Skip to content

Instantly share code, notes, and snippets.

@x-yuri
Last active January 5, 2018 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save x-yuri/5ad28ac0a22ca19a7c3073ce0de5abf0 to your computer and use it in GitHub Desktop.
Save x-yuri/5ad28ac0a22ca19a7c3073ce0de5abf0 to your computer and use it in GitHub Desktop.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <apr-1/apr_general.h>
#include <apr-1/apr_network_io.h>
#include <apr-1/apr_strings.h>
#define REMOTE_HOST "localhost"
#define REMOTE_PORT 8000
#define SOCK_TIMEOUT (APR_USEC_PER_SEC * 30)
#define BUFSIZE 4096
#define CRLF "\r\n"
static apr_status_t do_connect(apr_socket_t **sock, apr_pool_t *mp)
{
apr_sockaddr_t *sa;
apr_socket_t *s;
apr_status_t rv;
rv = apr_sockaddr_info_get(&sa, REMOTE_HOST, APR_UNSPEC, REMOTE_PORT, 0, mp);
if (rv != APR_SUCCESS) {
return rv;
}
for ( ; sa; sa = sa->next) {
rv = apr_socket_create(&s, sa->family, SOCK_STREAM, APR_PROTO_TCP, mp);
if (rv != APR_SUCCESS) {
return rv;
}
apr_socket_opt_set(s, APR_SO_NONBLOCK, 1);
apr_socket_timeout_set(s, SOCK_TIMEOUT);
rv = apr_socket_connect(s, sa);
if (rv == ECONNREFUSED) {
continue;
} else if (rv == APR_SUCCESS) {
break;
} else {
return rv;
}
}
apr_socket_opt_set(s, APR_SO_NONBLOCK, 0);
apr_socket_timeout_set(s, SOCK_TIMEOUT);
*sock = s;
return APR_SUCCESS;
}
static apr_status_t send_reqeust(apr_socket_t *sock, apr_pool_t *mp)
{
apr_status_t rv;
const char request[] = "GET / HTTP/1.0" CRLF
"Host: " REMOTE_HOST CRLF
CRLF;
apr_size_t len = strlen(request);
rv = apr_socket_send(sock, request, &len);
if (rv != APR_SUCCESS) {
return rv;
}
apr_file_t *stdout;
apr_file_open_stdout(&stdout, mp);
while (1) {
char buf[BUFSIZE];
apr_size_t len = sizeof(buf);
apr_status_t rv = apr_socket_recv(sock, buf, &len);
if (rv == APR_EOF || len == 0) {
break;
} else if (rv != APR_SUCCESS) {
return rv;
}
apr_file_write(stdout, buf, &len);
}
apr_file_close(stdout);
return APR_SUCCESS;
}
int main(int argc, const char *argv[])
{
(void)argc;
(void)argv;
apr_status_t rv;
apr_pool_t *mp;
apr_socket_t *s;
apr_initialize();
apr_pool_create(&mp, NULL);
rv = do_connect(&s, mp);
if (rv != APR_SUCCESS) {
goto error;
}
rv = send_reqeust(s, mp);
if (rv != APR_SUCCESS) {
goto error;
}
apr_socket_close(s);
apr_terminate();
exit(EXIT_SUCCESS);
error:
{
char errbuf[256];
apr_strerror(rv, errbuf, sizeof(errbuf));
printf("error: %d, %s\n", rv, errbuf);
}
apr_terminate();
exit(EXIT_FAILURE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment