Applied a modified patch for bug 344, needs testing with ipv6
git-svn-id: https://svn.musicpd.org/mpd/trunk@4171 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
6a2cf38465
commit
1ca85d5ec7
|
@ -48,7 +48,7 @@
|
|||
#define HTTP_REDIRECT_MAX 10
|
||||
|
||||
static char * proxyHost = NULL;
|
||||
static int proxyPort = 0;
|
||||
static char * proxyPort = NULL;
|
||||
static char * proxyUser = NULL;
|
||||
static char * proxyPassword = NULL;
|
||||
static int bufferSize = HTTP_BUFFER_SIZE_DEFAULT;
|
||||
|
@ -57,7 +57,7 @@ static int prebufferSize = HTTP_PREBUFFER_SIZE_DEFAULT;
|
|||
typedef struct _InputStreemHTTPData {
|
||||
char * host;
|
||||
char * path;
|
||||
int port;
|
||||
char *port;
|
||||
int sock;
|
||||
int connState;
|
||||
char * buffer;
|
||||
|
@ -84,13 +84,7 @@ void inputStream_initHttp() {
|
|||
CONF_HTTP_PROXY_PORT);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
proxyPort = strtol(param->value, &test, 10);
|
||||
if(proxyPort <= 0 || *test != '\0') {
|
||||
ERROR("%s \"%s\" is not a positive integer, line %i\n"
|
||||
CONF_HTTP_PROXY_PORT, param->value,
|
||||
param->line);
|
||||
}
|
||||
proxyPort = param->value;
|
||||
|
||||
param = getConfigParam(CONF_HTTP_PROXY_USER);
|
||||
|
||||
|
@ -255,7 +249,7 @@ static InputStreamHTTPData * newInputStreamHTTPData() {
|
|||
ret->httpAuth = NULL;
|
||||
ret->host = NULL;
|
||||
ret->path = NULL;
|
||||
ret->port = 80;
|
||||
ret->port = NULL;
|
||||
ret->connState = HTTP_CONN_STATE_CLOSED;
|
||||
ret->timesRedirected = 0;
|
||||
ret->icyMetaint = 0;
|
||||
|
@ -269,6 +263,7 @@ static InputStreamHTTPData * newInputStreamHTTPData() {
|
|||
static void freeInputStreamHTTPData(InputStreamHTTPData * data) {
|
||||
if(data->host) free(data->host);
|
||||
if(data->path) free(data->path);
|
||||
if(data->port) free(data->port);
|
||||
if(data->proxyAuth) free(data->proxyAuth);
|
||||
if(data->httpAuth) free(data->httpAuth);
|
||||
|
||||
|
@ -340,17 +335,19 @@ static int parseUrl(InputStreamHTTPData * data, char * url) {
|
|||
data->host = malloc(len);
|
||||
strncpy(data->host,temp,len-1);
|
||||
data->host[len-1] = '\0';
|
||||
|
||||
/* fetch the port */
|
||||
if(colon && (!slash || slash != colon+1)) {
|
||||
char * test;
|
||||
data->port = strtol(colon+1,&test,10);
|
||||
|
||||
if(data->port <= 0 || (*test != '\0' && *test != '/')) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
len = strlen(colon)-1;
|
||||
if(slash) len -= strlen(slash);
|
||||
data->port = malloc(len+1);
|
||||
strncpy(data->port, colon+1, len);
|
||||
data->port[len] = '\0';
|
||||
printf("Port: %s\n", data->port);
|
||||
}
|
||||
else {
|
||||
data->port = strdup("80");
|
||||
}
|
||||
|
||||
/* fetch the path */
|
||||
if(proxyHost) data->path = strdup(url);
|
||||
else data->path = strdup(slash ? slash : "/");
|
||||
|
@ -359,19 +356,28 @@ static int parseUrl(InputStreamHTTPData * data, char * url) {
|
|||
}
|
||||
|
||||
static int initHTTPConnection(InputStream * inStream) {
|
||||
struct hostent * he;
|
||||
struct sockaddr * dest;
|
||||
socklen_t destlen;
|
||||
struct sockaddr_in sin;
|
||||
InputStreamHTTPData * data = (InputStreamHTTPData *)inStream->data;
|
||||
int flags;
|
||||
int ret;
|
||||
char * connHost;
|
||||
int connPort;
|
||||
#ifdef HAVE_IPV6
|
||||
struct sockaddr_in6 sin6;
|
||||
#endif
|
||||
char *connHost;
|
||||
char *connPort;
|
||||
struct addrinfo *ans = NULL;
|
||||
struct addrinfo *ap = NULL;
|
||||
struct addrinfo hints;
|
||||
int error, flags;
|
||||
InputStreamHTTPData * data = (InputStreamHTTPData *)inStream->data;
|
||||
/**
|
||||
* Setup hints
|
||||
*/
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_addrlen = 0;
|
||||
hints.ai_addr = NULL;
|
||||
hints.ai_canonname = NULL;
|
||||
hints.ai_next = NULL;
|
||||
|
||||
|
||||
|
||||
|
||||
if(proxyHost) {
|
||||
connHost = proxyHost;
|
||||
connPort = proxyPort;
|
||||
|
@ -381,61 +387,41 @@ static int initHTTPConnection(InputStream * inStream) {
|
|||
connPort = data->port;
|
||||
}
|
||||
|
||||
if(!(he = gethostbyname(connHost))) {
|
||||
DEBUG(__FILE__ ": failure to lookup host \"%s\"\n",connHost);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&sin,0,sizeof(struct sockaddr_in));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(connPort);
|
||||
#ifdef HAVE_IPV6
|
||||
memset(&sin6,0,sizeof(struct sockaddr_in6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
sin6.sin6_port = sin.sin_port;
|
||||
#endif
|
||||
|
||||
switch(he->h_addrtype) {
|
||||
case AF_INET:
|
||||
memcpy((char *)&sin.sin_addr.s_addr,(char *)he->h_addr,
|
||||
he->h_length);
|
||||
dest = (struct sockaddr *)&sin;
|
||||
destlen = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
if(!ipv6Supported()) {
|
||||
return -1;
|
||||
}
|
||||
memcpy((char *)&sin6.sin6_addr.s6_addr,(char *)he->h_addr,
|
||||
he->h_length);
|
||||
dest = (struct sockaddr *)&sin6;
|
||||
destlen = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((data->sock = socket(dest->sa_family,SOCK_STREAM,0)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
flags = fcntl(data->sock, F_GETFL, 0);
|
||||
fcntl(data->sock, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
ret = connect(data->sock,dest,destlen);
|
||||
if(ret < 0 && errno!=EINPROGRESS) {
|
||||
error = getaddrinfo(connHost, connPort, &hints, &ans);
|
||||
if(error) {
|
||||
DEBUG(__FILE__ ": Error getting address info: %s\n", gai_strerror(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* loop through possible addresses */
|
||||
for(ap = ans; ap != NULL; ap = ap->ai_next) {
|
||||
if((data->sock = socket(ap->ai_family, ap->ai_socktype,
|
||||
ap->ai_protocol)) < 0) {
|
||||
DEBUG(__FILE__ ": unable to connect: %s\n", strerror(errno));
|
||||
freeaddrinfo(ans);
|
||||
return -1;
|
||||
}
|
||||
|
||||
flags = fcntl(data->sock, F_GETFL, 0);
|
||||
fcntl(data->sock, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
if(connect(data->sock, ap->ai_addr, ap->ai_addrlen) >= 0
|
||||
|| errno == EINPROGRESS
|
||||
) {
|
||||
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));
|
||||
close(data->sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->connState = HTTP_CONN_STATE_INIT;
|
||||
|
||||
data->buflen = 0;
|
||||
|
||||
return 0;
|
||||
freeaddrinfo(ans);
|
||||
return -1; /* failed */
|
||||
}
|
||||
|
||||
static int finishHTTPInit(InputStream * inStream) {
|
||||
|
@ -444,7 +430,7 @@ static int finishHTTPInit(InputStream * inStream) {
|
|||
fd_set writeSet;
|
||||
fd_set errorSet;
|
||||
int error;
|
||||
int error_len = sizeof(int);
|
||||
socklen_t error_len = sizeof(int);
|
||||
int ret;
|
||||
char request[2049];
|
||||
|
||||
|
|
Loading…
Reference in New Issue