Commit 1ca85d5e authored by Qball Cow's avatar Qball Cow

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
parent 6a2cf384
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#define HTTP_REDIRECT_MAX 10 #define HTTP_REDIRECT_MAX 10
static char * proxyHost = NULL; static char * proxyHost = NULL;
static int proxyPort = 0; static char * proxyPort = NULL;
static char * proxyUser = NULL; static char * proxyUser = NULL;
static char * proxyPassword = NULL; static char * proxyPassword = NULL;
static int bufferSize = HTTP_BUFFER_SIZE_DEFAULT; static int bufferSize = HTTP_BUFFER_SIZE_DEFAULT;
...@@ -57,7 +57,7 @@ static int prebufferSize = HTTP_PREBUFFER_SIZE_DEFAULT; ...@@ -57,7 +57,7 @@ static int prebufferSize = HTTP_PREBUFFER_SIZE_DEFAULT;
typedef struct _InputStreemHTTPData { typedef struct _InputStreemHTTPData {
char * host; char * host;
char * path; char * path;
int port; char *port;
int sock; int sock;
int connState; int connState;
char * buffer; char * buffer;
...@@ -84,13 +84,7 @@ void inputStream_initHttp() { ...@@ -84,13 +84,7 @@ void inputStream_initHttp() {
CONF_HTTP_PROXY_PORT); CONF_HTTP_PROXY_PORT);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
proxyPort = param->value;
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);
}
param = getConfigParam(CONF_HTTP_PROXY_USER); param = getConfigParam(CONF_HTTP_PROXY_USER);
...@@ -255,7 +249,7 @@ static InputStreamHTTPData * newInputStreamHTTPData() { ...@@ -255,7 +249,7 @@ static InputStreamHTTPData * newInputStreamHTTPData() {
ret->httpAuth = NULL; ret->httpAuth = NULL;
ret->host = NULL; ret->host = NULL;
ret->path = NULL; ret->path = NULL;
ret->port = 80; ret->port = NULL;
ret->connState = HTTP_CONN_STATE_CLOSED; ret->connState = HTTP_CONN_STATE_CLOSED;
ret->timesRedirected = 0; ret->timesRedirected = 0;
ret->icyMetaint = 0; ret->icyMetaint = 0;
...@@ -269,6 +263,7 @@ static InputStreamHTTPData * newInputStreamHTTPData() { ...@@ -269,6 +263,7 @@ static InputStreamHTTPData * newInputStreamHTTPData() {
static void freeInputStreamHTTPData(InputStreamHTTPData * data) { static void freeInputStreamHTTPData(InputStreamHTTPData * data) {
if(data->host) free(data->host); if(data->host) free(data->host);
if(data->path) free(data->path); if(data->path) free(data->path);
if(data->port) free(data->port);
if(data->proxyAuth) free(data->proxyAuth); if(data->proxyAuth) free(data->proxyAuth);
if(data->httpAuth) free(data->httpAuth); if(data->httpAuth) free(data->httpAuth);
...@@ -340,17 +335,19 @@ static int parseUrl(InputStreamHTTPData * data, char * url) { ...@@ -340,17 +335,19 @@ static int parseUrl(InputStreamHTTPData * data, char * url) {
data->host = malloc(len); data->host = malloc(len);
strncpy(data->host,temp,len-1); strncpy(data->host,temp,len-1);
data->host[len-1] = '\0'; data->host[len-1] = '\0';
/* fetch the port */ /* fetch the port */
if(colon && (!slash || slash != colon+1)) { if(colon && (!slash || slash != colon+1)) {
char * test; len = strlen(colon)-1;
data->port = strtol(colon+1,&test,10); if(slash) len -= strlen(slash);
data->port = malloc(len+1);
if(data->port <= 0 || (*test != '\0' && *test != '/')) { strncpy(data->port, colon+1, len);
return -1; data->port[len] = '\0';
} printf("Port: %s\n", data->port);
} }
else {
data->port = strdup("80");
}
/* fetch the path */ /* fetch the path */
if(proxyHost) data->path = strdup(url); if(proxyHost) data->path = strdup(url);
else data->path = strdup(slash ? slash : "/"); else data->path = strdup(slash ? slash : "/");
...@@ -359,19 +356,28 @@ static int parseUrl(InputStreamHTTPData * data, char * url) { ...@@ -359,19 +356,28 @@ static int parseUrl(InputStreamHTTPData * data, char * url) {
} }
static int initHTTPConnection(InputStream * inStream) { static int initHTTPConnection(InputStream * inStream) {
struct hostent * he; char *connHost;
struct sockaddr * dest; char *connPort;
socklen_t destlen; struct addrinfo *ans = NULL;
struct sockaddr_in sin; struct addrinfo *ap = NULL;
InputStreamHTTPData * data = (InputStreamHTTPData *)inStream->data; struct addrinfo hints;
int flags; int error, flags;
int ret; InputStreamHTTPData * data = (InputStreamHTTPData *)inStream->data;
char * connHost; /**
int connPort; * Setup hints
#ifdef HAVE_IPV6 */
struct sockaddr_in6 sin6; hints.ai_flags = 0;
#endif 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) { if(proxyHost) {
connHost = proxyHost; connHost = proxyHost;
connPort = proxyPort; connPort = proxyPort;
...@@ -381,61 +387,41 @@ static int initHTTPConnection(InputStream * inStream) { ...@@ -381,61 +387,41 @@ static int initHTTPConnection(InputStream * inStream) {
connPort = data->port; connPort = data->port;
} }
if(!(he = gethostbyname(connHost))) { error = getaddrinfo(connHost, connPort, &hints, &ans);
DEBUG(__FILE__ ": failure to lookup host \"%s\"\n",connHost); if(error) {
return -1; DEBUG(__FILE__ ": Error getting address info: %s\n", gai_strerror(error));
} return -1;
}
memset(&sin,0,sizeof(struct sockaddr_in));
sin.sin_family = AF_INET; /* loop through possible addresses */
sin.sin_port = htons(connPort); for(ap = ans; ap != NULL; ap = ap->ai_next) {
#ifdef HAVE_IPV6 if((data->sock = socket(ap->ai_family, ap->ai_socktype,
memset(&sin6,0,sizeof(struct sockaddr_in6)); ap->ai_protocol)) < 0) {
sin6.sin6_family = AF_INET6; DEBUG(__FILE__ ": unable to connect: %s\n", strerror(errno));
sin6.sin6_port = sin.sin_port; freeaddrinfo(ans);
#endif return -1;
}
switch(he->h_addrtype) {
case AF_INET: flags = fcntl(data->sock, F_GETFL, 0);
memcpy((char *)&sin.sin_addr.s_addr,(char *)he->h_addr, fcntl(data->sock, F_SETFL, flags | O_NONBLOCK);
he->h_length);
dest = (struct sockaddr *)&sin; if(connect(data->sock, ap->ai_addr, ap->ai_addrlen) >= 0
destlen = sizeof(struct sockaddr_in); || errno == EINPROGRESS
break; ) {
#ifdef HAVE_IPV6 data->connState = HTTP_CONN_STATE_INIT;
case AF_INET6: data->buflen = 0;
if(!ipv6Supported()) { freeaddrinfo(ans);
return -1; return 0; /* success */
} }
memcpy((char *)&sin6.sin6_addr.s6_addr,(char *)he->h_addr,
he->h_length); /* failed, get the next one */
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) {
DEBUG(__FILE__ ": unable to connect: %s\n", strerror(errno)); DEBUG(__FILE__ ": unable to connect: %s\n", strerror(errno));
close(data->sock); close(data->sock);
return -1;
} }
data->connState = HTTP_CONN_STATE_INIT; freeaddrinfo(ans);
return -1; /* failed */
data->buflen = 0;
return 0;
} }
static int finishHTTPInit(InputStream * inStream) { static int finishHTTPInit(InputStream * inStream) {
...@@ -444,7 +430,7 @@ static int finishHTTPInit(InputStream * inStream) { ...@@ -444,7 +430,7 @@ static int finishHTTPInit(InputStream * inStream) {
fd_set writeSet; fd_set writeSet;
fd_set errorSet; fd_set errorSet;
int error; int error;
int error_len = sizeof(int); socklen_t error_len = sizeof(int);
int ret; int ret;
char request[2049]; char request[2049];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment