http: split out logic around getaddrinfo() and connect()

Makes code easier to read and modularize

git-svn-id: https://svn.musicpd.org/mpd/trunk@7388 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Eric Wong 2008-06-30 02:42:49 +00:00
parent ec1eeeeaff
commit aa828c1b25

View File

@ -276,18 +276,13 @@ static int parseUrl(InputStreamHTTPData * data, char *url)
return 0; return 0;
} }
static int initHTTPConnection(InputStream * inStream) /* returns -1 on error, 0 on success (and sets dest) */
static int my_getaddrinfo(struct addrinfo **dest,
const char *host, const char *port)
{ {
char *connHost;
char *connPort;
struct addrinfo *ans = NULL;
struct addrinfo *ap = NULL;
struct addrinfo hints; struct addrinfo hints;
int error; int error;
InputStreamHTTPData *data = (InputStreamHTTPData *) inStream->data;
/**
* Setup hints
*/
hints.ai_flags = 0; hints.ai_flags = 0;
hints.ai_family = PF_UNSPEC; hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
@ -297,50 +292,57 @@ static int initHTTPConnection(InputStream * inStream)
hints.ai_canonname = NULL; hints.ai_canonname = NULL;
hints.ai_next = NULL; hints.ai_next = NULL;
if (proxyHost) { if ((error = getaddrinfo(host, port, &hints, dest))) {
connHost = proxyHost; DEBUG(__FILE__ ": Error getting address info for %s:%s: %s\n",
connPort = proxyPort; host, port, gai_strerror(error));
} else {
connHost = data->host;
connPort = data->port;
}
error = getaddrinfo(connHost, connPort, &hints, &ans);
if (error) {
DEBUG(__FILE__ ": Error getting address info: %s\n",
gai_strerror(error));
return -1; return -1;
} }
return 0;
}
/* returns the fd we connected to, or -1 on error */
static int my_connect_addrs(struct addrinfo *ans)
{
int fd;
struct addrinfo *ap;
/* loop through possible addresses */ /* loop through possible addresses */
for (ap = ans; ap != NULL; ap = ap->ai_next) { for (ap = ans; ap != NULL; ap = ap->ai_next) {
if ((data->sock = socket(ap->ai_family, ap->ai_socktype, fd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
ap->ai_protocol)) < 0) { if (fd < 0) {
DEBUG(__FILE__ ": unable to connect: %s\n", DEBUG(__FILE__ ": unable to get socket: %s\n",
strerror(errno)); strerror(errno));
freeaddrinfo(ans); continue;
return -1;
} }
set_nonblocking(data->sock); set_nonblocking(fd);
if (connect(fd, ap->ai_addr, ap->ai_addrlen) >= 0
if (connect(data->sock, ap->ai_addr, ap->ai_addrlen) >= 0 || errno == EINPROGRESS)
|| errno == EINPROGRESS) { return fd; /* success */
data->connState = HTTP_CONN_STATE_INIT;
data->buflen = 0;
freeaddrinfo(ans);
return 0; /* success */
}
/* failed, get the next one */
DEBUG(__FILE__ ": unable to connect: %s\n", strerror(errno)); DEBUG(__FILE__ ": unable to connect: %s\n", strerror(errno));
close(data->sock); xclose(fd); /* failed, get the next one */
} }
return -1;
}
static int initHTTPConnection(InputStream * inStream)
{
struct addrinfo *ans = NULL;
InputStreamHTTPData *data = (InputStreamHTTPData *) inStream->data;
if ((proxyHost ? my_getaddrinfo(&ans, proxyHost, proxyPort) :
my_getaddrinfo(&ans, data->host, data->port)) < 0)
return -1;
data->sock = my_connect_addrs(ans);
freeaddrinfo(ans); freeaddrinfo(ans);
return -1; /* failed */
if (data->sock < 0)
return -1; /* failed */
data->connState = HTTP_CONN_STATE_INIT;
data->buflen = 0;
return 0;
} }
static int finishHTTPInit(InputStream * inStream) static int finishHTTPInit(InputStream * inStream)