Commit cc34e1ec authored by Philipp Schafft's avatar Philipp Schafft 🦁

Merge branch 'devel-ph3--ticket2298'

Closes: #2298
parents 93f1ba43 4ed2af09
......@@ -28,7 +28,16 @@
#include <shout/shout.h>
#include "shout_private.h"
int shout_create_icy_request(shout_t *self)
static int shout_create_icy_request_poke(shout_t *self)
{
if (shout_queue_printf(self, "!POKE\nicy-name:libshout server poke request\n\n")) {
return SHOUTERR_MALLOC;
} else {
return SHOUTERR_SUCCESS;
}
}
static int shout_create_icy_request_real(shout_t *self)
{
const char *bitrate;
const char *val;
......@@ -69,3 +78,12 @@ int shout_create_icy_request(shout_t *self)
return ret;
}
int shout_create_icy_request(shout_t *self)
{
if (self->server_caps & LIBSHOUT_CAP_GOTCAPS) {
return shout_create_icy_request_real(self);
} else {
return shout_create_icy_request_poke(self);
}
}
......@@ -281,6 +281,7 @@ int shout_parse_roaraudio_response(shout_t *self)
switch ((shout_roar_protocol_state_t)self->protocol_state) {
case STATE_IDENT:
self->protocol_state = STATE_AUTH;
self->server_caps |= LIBSHOUT_CAP_GOTCAPS;
break;
case STATE_AUTH:
......
......@@ -77,6 +77,24 @@ int shout_create_xaudiocast_request(shout_t *self)
return ret;
}
int shout_get_xaudiocast_response(shout_t *self)
{
shout_buf_t *queue = self->rqueue.head;
unsigned int i;
do {
for (i = 0; i < queue->len; i++) {
if (queue->data[i] == '\n') {
/* got response */
return SHOUTERR_SUCCESS;
}
}
} while ((queue = queue->next));
/* need more data */
return SHOUTERR_BUSY;
}
int shout_parse_xaudiocast_response(shout_t *self)
{
char *response;
......@@ -87,9 +105,20 @@ int shout_parse_xaudiocast_response(shout_t *self)
if (!strstr(response, "OK")) {
free(response);
return SHOUTERR_NOLOGIN;
/* check to see if that is a response to a POKE. */
if (!(self->server_caps & LIBSHOUT_CAP_GOTCAPS)) {
self->server_caps |= LIBSHOUT_CAP_GOTCAPS;
self->retry++;
if (self->retry > LIBSHOUT_MAX_RETRY)
self->retry = 0;
return SHOUTERR_SOCKET;
} else {
return SHOUTERR_NOLOGIN;
}
}
free(response);
self->server_caps |= LIBSHOUT_CAP_GOTCAPS;
return SHOUTERR_SUCCESS;
}
......@@ -1154,10 +1154,22 @@ static int get_response(shout_t *self)
if ((rc = shout_queue_data(&self->rqueue, (unsigned char*)buf, rc)))
return rc;
if (self->protocol == SHOUT_PROTOCOL_ROARAUDIO)
return shout_get_roaraudio_response(self);
switch (self->protocol) {
case SHOUT_PROTOCOL_HTTP:
return shout_get_http_response(self);
break;
case SHOUT_PROTOCOL_XAUDIOCAST:
/* fall through */
case SHOUT_PROTOCOL_ICY:
return shout_get_xaudiocast_response(self);
break;
case SHOUT_PROTOCOL_ROARAUDIO:
return shout_get_roaraudio_response(self);
break;
}
return shout_get_http_response(self);
/* we should never reach this code */
return SHOUTERR_INSANE;
}
static int try_connect(shout_t *self)
......@@ -1209,20 +1221,7 @@ retry:
break;
case SHOUT_TLS_AUTO:
case SHOUT_TLS_AUTO_NO_PLAIN:
if (self->server_caps & LIBSHOUT_CAP_GOTCAPS) {
/* We had a probe allready, otherwise just poke the server. */
if ((self->server_caps & LIBSHOUT_CAP_UPGRADETLS) && (self->server_caps & LIBSHOUT_CAP_OPTIONS)) {
self->tls_mode_used = SHOUT_TLS_RFC2817;
} else {
if (self->tls_mode == SHOUT_TLS_AUTO_NO_PLAIN) {
self->tls_mode_used = SHOUTERR_NOTLS;
return SHOUTERR_NOTLS;
}
self->tls_mode_used = SHOUT_TLS_DISABLED;
}
self->state = SHOUT_STATE_TLS_PENDING;
goto retry;
}
/* Do nothing. This case is handled post poke. */
break;
default:
rc = SHOUTERR_INSANE;
......@@ -1305,15 +1304,46 @@ retry:
if (rc != SHOUTERR_SUCCESS)
goto failure;
if ((rc = parse_response(self)) != SHOUTERR_SUCCESS) {
if (rc == SHOUTERR_RETRY)
goto retry;
rc = parse_response(self);
if (rc == SHOUTERR_RETRY)
goto retry;
if (rc != SHOUTERR_SUCCESS && !self->retry) {
goto failure;
}
if (self->retry) {
if (!(self->server_caps & LIBSHOUT_CAP_GOTCAPS)) {
rc = SHOUTERR_INSANE;
goto failure;
}
#ifdef HAVE_OPENSSL
if (self->tls_mode_used < 0) {
switch (self->tls_mode) {
case SHOUT_TLS_AUTO:
case SHOUT_TLS_AUTO_NO_PLAIN:
if ((self->server_caps & LIBSHOUT_CAP_UPGRADETLS) && (self->server_caps & LIBSHOUT_CAP_OPTIONS)) {
self->tls_mode_used = SHOUT_TLS_RFC2817;
} else {
if (self->tls_mode == SHOUT_TLS_AUTO_NO_PLAIN) {
self->tls_mode_used = SHOUTERR_NOTLS;
rc = SHOUTERR_NOTLS;
goto failure;
}
self->tls_mode_used = SHOUT_TLS_DISABLED;
}
break;
}
}
#endif
if (rc != SHOUTERR_SUCCESS && self->retry) {
if (rc == SHOUTERR_SOCKET) {
self->state = SHOUT_STATE_RECONNECT;
} else {
self->state = SHOUT_STATE_TLS_PENDING;
goto retry;
}
goto failure;
goto retry;
}
switch (self->format) {
......@@ -1345,6 +1375,11 @@ retry:
/* special case, no fallthru to this */
case SHOUT_STATE_RECONNECT:
#ifdef HAVE_OPENSSL
if (self->tls)
shout_tls_close(self->tls);
self->tls = NULL;
#endif
sock_close(self->socket);
self->state = SHOUT_STATE_UNCONNECTED;
goto retry;
......
......@@ -197,6 +197,7 @@ int shout_get_http_response(shout_t *self);
int shout_parse_http_response(shout_t *self);
int shout_create_xaudiocast_request(shout_t *self);
int shout_get_xaudiocast_response(shout_t *self);
int shout_parse_xaudiocast_response(shout_t *self);
int shout_create_icy_request(shout_t *self);
......
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