[xiph-commits] r7287 - icecast/trunk/libshout/src

brendan at dactyl.lonelymoon.com brendan
Fri Jul 23 11:17:30 PDT 2004


Author: brendan
Date: Fri Jul 23 11:17:30 2004
New Revision: 7287

Modified:
icecast/trunk/libshout/src/shout.c
Log:
HTTP headers are buffered before being sent (using queue code which
will be shared with non-blocking I/O).


Modified: icecast/trunk/libshout/src/shout.c
===================================================================
--- icecast/trunk/libshout/src/shout.c	2004-07-23 16:00:04 UTC (rev 7286)
+++ icecast/trunk/libshout/src/shout.c	2004-07-23 18:17:26 UTC (rev 7287)
@@ -1,5 +1,6 @@
/* -*- c-basic-offset: 8; -*- */
/* shout.c: Implementation of public libshout interface shout.h
+ * $Id$
*
*  Copyright (C) 2002-2004 the Icecast team <team at icecast.org>
*
@@ -795,11 +796,47 @@
return SHOUTERR_SUCCESS;
}

-static int queue_str(shout_t *self, const char *str)
+static inline int queue_str(shout_t *self, const char *str)
{
return queue_data(self, str, strlen(str));
}

+/* this should be shared with sock_write. Create libicecommon. */
+static int queue_printf(shout_t *self, const char *fmt, ...)
+{
+	char buffer[1024];
+	char *buf;
+	va_list ap, ap_retry;
+	int len;
+
+	buf = buffer;
+
+	va_start(ap, fmt);
+	va_copy(ap_retry, ap);
+
+	len = vsnprintf(buf, sizeof(buffer), fmt, ap);
+
+	self->error = SHOUTERR_SUCCESS;
+	if (len > 0) {
+		if ((size_t)len < sizeof(buffer))
+			queue_data(self, buf, len);
+		else {
+			buf = malloc(++len);
+			if (buf) {
+				len = vsnprintf(buf, len, fmt, ap_retry);
+				queue_data(self, buf, len);
+				free(buf);
+			} else
+				self->error = SHOUTERR_MALLOC;
+		}
+	}
+
+	va_end(ap_retry);
+	va_end(ap);
+
+	return self->error;
+}
+
static int try_write (shout_t *self, const void *data, size_t len)
{
int ret = sock_write_bytes (self->socket, data, len);
@@ -842,67 +879,57 @@
return self->error = SHOUTERR_SUCCESS;
}

-static int send_http_request(shout_t *self)
+static int create_http_request(shout_t *self)
{
char *auth;
char *ai;
+	int ret = SHOUTERR_MALLOC;

-	if (!sock_write(self->socket, "SOURCE %s HTTP/1.0\r\n", self->mount))
-		return SHOUTERR_SOCKET;
-
-	if (self->password && (auth = http_basic_authorization(self))) {
-		if (!sock_write(self->socket, auth)) {
+	/* this is lazy code that relies on the only error from queue_* being
+	 * SHOUTERR_MALLOC */
+	do {
+		if (queue_printf(self, "SOURCE %s HTTP/1.0\r\n", self->mount))
+			break;
+		if (self->password) {
+			if (! (auth = http_basic_authorization(self)))
+				break;
+			if (queue_str(self, auth)) {
+				free(auth);
+				break;
+			}
free(auth);
-			return SHOUTERR_SOCKET;
}
-		free(auth);
-	}
+		if (self->useragent && queue_printf(self, "User-Agent: %s\r\n", self->useragent))
+			break;
+		if (self->format == SHOUT_FORMAT_OGG && queue_printf(self, "Content-Type: application/ogg\r\n"))
+			break;
+		if (self->format == SHOUT_FORMAT_MP3 && queue_printf(self, "Content-Type: audio/mpeg\r\n"))
+			break;
+		if (queue_printf(self, "ice-name: %s\r\n", self->name ? self->name : "no name"))
+			break;
+		if (queue_printf(self, "ice-public: %d\r\n", self->public))
+			break;

-	if (!sock_write(self->socket, "ice-name: %s\r\n", self->name != NULL ? self->name : "no name"))
-		return SHOUTERR_SOCKET;
-	if (self->url) {
-		if (!sock_write(self->socket, "ice-url: %s\r\n", self->url))
-			return SHOUTERR_SOCKET;
-	}
-	if (self->genre) {
-		if (!sock_write(self->socket, "ice-genre: %s\r\n", self->genre))
-			return SHOUTERR_SOCKET;
-	}
-#if 0
-	ai = shout_get_audio_info(self, SHOUT_AI_BITRATE);
-
-	if (bitrate && !sock_write(self->socket, "ice-bitrate: %s\r\n", bitrate))
-		return SHOUTERR_SOCKET;
-#else
-	if ((ai = _shout_util_dict_urlencode(self->audio_info, ';'))) {
-		if (!sock_write(self->socket, "ice-audio-info: %s\r\n", ai)) {
+		if (self->url && queue_printf(self, "ice-url: %s\r\n", self->url))
+			break;
+		if (self->genre && queue_printf(self, "ice-genre: %s\r\n", self->genre))
+			break;
+		if ((ai = _shout_util_dict_urlencode(self->audio_info, ';'))) {
+			if (queue_printf(self, "ice-audio-info: %s\r\n", ai)) {
+				free(ai);
+				break;
+			}
free(ai);
-			return SHOUTERR_SOCKET;
}
-	}
-#endif
-	if (!sock_write(self->socket, "ice-public: %d\r\n", self->public))
-		return SHOUTERR_SOCKET;
-	if (self->description) {
-		if (!sock_write(self->socket, "ice-description: %s\r\n", self->description))
-			return SHOUTERR_SOCKET;
-	}
-	if (self->useragent) {
-		if (!sock_write(self->socket, "User-Agent: %s\r\n", self->useragent))
-			return SHOUTERR_SOCKET;
-	}
-	if (self->format == SHOUT_FORMAT_OGG) {
-		if (!sock_write(self->socket, "Content-Type: application/ogg\r\n"))
-			return SHOUTERR_SOCKET;
-	} else if (self->format == SHOUT_FORMAT_MP3) {
-		if (!sock_write(self->socket, "Content-Type: audio/mpeg\r\n"))
-			return SHOUTERR_SOCKET;
-	}
+		if (self->description && queue_printf(self, "ice-description: %s\r\n", self->description))
+			break;
+		if (queue_str(self, "\r\n"))
+			break;
+
+		ret = SHOUTERR_SUCCESS;
+	} while (0);

-	if (!sock_write(self->socket, "\r\n"))
-		return SHOUTERR_SOCKET;
-
-	return SHOUTERR_SUCCESS;
+	return ret;
}

static char *http_basic_authorization(shout_t *self)
@@ -944,23 +971,19 @@
self->error = SHOUTERR_SOCKET;

self->socket = sock_connect(self->host, self->port);
-	if (self->socket < 0) {
+	if (self->socket < 0)
return self->error = SHOUTERR_NOCONNECT;
-	}

-#if 0
-	if(send_http_request(self) != 0) {
-#else
/* assume we'll have to authenticate, saves round trips on basic */
-	if(send_http_request(self) != 0) {
-#endif
-		return self->error = SHOUTERR_SOCKET;
-	}
+	if(create_http_request(self) != SHOUTERR_SUCCESS)
+		return self->error;

-	if (_shout_util_read_header(self->socket, header, 4096) == 0) {
+	if (send_queue(self) != SHOUTERR_SUCCESS)
+		return self->error;
+
+	if (_shout_util_read_header(self->socket, header, 4096) == 0)
/* either we didn't get a complete header, or we timed out */
return self->error = SHOUTERR_SOCKET;
-	}

parser = httpp_create_parser();
httpp_initialize(parser, NULL);



More information about the commits mailing list