Commit 8941de32 authored by Philipp Schafft's avatar Philipp Schafft 🦁

Fix: Added some more HTTP/1.1 headers

This adds to all responses:
 * "Accept-Encoding: identity"
 * "Connection: close"
 * "Allow: GET, SOURCE" or "Allow: GET" (on admin pages)

This is to generate some infrastructure for Icecast to tell futur
source clients what is supported.

"Upgrade: TLS/1.0" should be added later when upgrade support is present.

See: #2152
parent 025cc0a5
...@@ -306,7 +306,7 @@ void admin_send_response(xmlDocPtr doc, ...@@ -306,7 +306,7 @@ void admin_send_response(xmlDocPtr doc,
ret = util_http_build_header(client->refbuf->data, buf_len, 0, ret = util_http_build_header(client->refbuf->data, buf_len, 0,
0, 200, NULL, 0, 200, NULL,
"text/xml", "utf-8", "text/xml", "utf-8",
NULL, NULL); NULL, NULL, client);
if (ret < 0) { if (ret < 0) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client_send_error(client, 500, 0, "Header generation failed."); client_send_error(client, 500, 0, "Header generation failed.");
...@@ -323,7 +323,7 @@ void admin_send_response(xmlDocPtr doc, ...@@ -323,7 +323,7 @@ void admin_send_response(xmlDocPtr doc,
ret = util_http_build_header(client->refbuf->data, buf_len, 0, ret = util_http_build_header(client->refbuf->data, buf_len, 0,
0, 200, NULL, 0, 200, NULL,
"text/xml", "utf-8", "text/xml", "utf-8",
NULL, NULL); NULL, NULL, client);
if (ret == -1) { if (ret == -1) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client_send_error(client, 500, 0, "Header generation failed."); client_send_error(client, 500, 0, "Header generation failed.");
...@@ -577,7 +577,7 @@ static void html_success(client_t *client, char *message) ...@@ -577,7 +577,7 @@ static void html_success(client_t *client, char *message)
ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
0, 0, 200, NULL, 0, 0, 200, NULL,
"text/html", "utf-8", "text/html", "utf-8",
"", NULL); "", NULL, client);
if (ret == -1 || ret >= PER_CLIENT_REFBUF_SIZE) { if (ret == -1 || ret >= PER_CLIENT_REFBUF_SIZE) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
...@@ -755,7 +755,7 @@ static void command_buildm3u(client_t *client, const char *mount) ...@@ -755,7 +755,7 @@ static void command_buildm3u(client_t *client, const char *mount)
ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
0, 0, 200, NULL, 0, 0, 200, NULL,
"audio/x-mpegurl", NULL, "audio/x-mpegurl", NULL,
NULL, NULL); NULL, NULL, client);
if (ret == -1 || ret >= (PER_CLIENT_REFBUF_SIZE - 512)) { if (ret == -1 || ret >= (PER_CLIENT_REFBUF_SIZE - 512)) {
/* we want at least 512 Byte left for data */ /* we want at least 512 Byte left for data */
...@@ -1157,7 +1157,7 @@ static void command_list_mounts(client_t *client, int response) ...@@ -1157,7 +1157,7 @@ static void command_list_mounts(client_t *client, int response)
PER_CLIENT_REFBUF_SIZE, 0, PER_CLIENT_REFBUF_SIZE, 0,
0, 200, NULL, 0, 200, NULL,
"text/plain", "utf-8", "text/plain", "utf-8",
"", NULL); "", NULL, client);
if (ret == -1 || ret >= PER_CLIENT_REFBUF_SIZE) { if (ret == -1 || ret >= PER_CLIENT_REFBUF_SIZE) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
......
...@@ -172,7 +172,7 @@ void client_send_error(client_t *client, int status, int plain, const char *mess ...@@ -172,7 +172,7 @@ void client_send_error(client_t *client, int status, int plain, const char *mess
ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, 0, ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, 0,
0, status, NULL, 0, status, NULL,
plain ? "text/plain" : "text/html", "utf-8", plain ? "text/plain" : "text/html", "utf-8",
plain ? message : "", NULL); plain ? message : "", NULL, client);
if (ret == -1 || ret >= PER_CLIENT_REFBUF_SIZE) { if (ret == -1 || ret >= PER_CLIENT_REFBUF_SIZE) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
......
...@@ -294,7 +294,7 @@ static int format_prepare_headers (source_t *source, client_t *client) ...@@ -294,7 +294,7 @@ static int format_prepare_headers (source_t *source, client_t *client)
ptr = client->refbuf->data; ptr = client->refbuf->data;
client->respcode = 200; client->respcode = 200;
bytes = util_http_build_header(ptr, remaining, 0, 0, 200, NULL, source->format->contenttype, NULL, NULL, source); bytes = util_http_build_header(ptr, remaining, 0, 0, 200, NULL, source->format->contenttype, NULL, NULL, source, client);
if (bytes == -1) { if (bytes == -1) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client_send_error(client, 500, 0, "Header generation failed."); client_send_error(client, 500, 0, "Header generation failed.");
...@@ -305,7 +305,7 @@ static int format_prepare_headers (source_t *source, client_t *client) ...@@ -305,7 +305,7 @@ static int format_prepare_headers (source_t *source, client_t *client)
ICECAST_LOG_DEBUG("Client buffer reallocation succeeded."); ICECAST_LOG_DEBUG("Client buffer reallocation succeeded.");
client->refbuf->data = ptr = new_ptr; client->refbuf->data = ptr = new_ptr;
client->refbuf->len = remaining = bytes + 1024; client->refbuf->len = remaining = bytes + 1024;
bytes = util_http_build_header(ptr, remaining, 0, 0, 200, NULL, source->format->contenttype, NULL, NULL, source); bytes = util_http_build_header(ptr, remaining, 0, 0, 200, NULL, source->format->contenttype, NULL, NULL, source, client);
if (bytes == -1 ) { if (bytes == -1 ) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client_send_error(client, 500, 0, "Header generation failed."); client_send_error(client, 500, 0, "Header generation failed.");
......
...@@ -462,7 +462,7 @@ int fserve_client_create (client_t *httpclient, const char *path) ...@@ -462,7 +462,7 @@ int fserve_client_create (client_t *httpclient, const char *path)
httpclient->respcode = 200; httpclient->respcode = 200;
ret = util_http_build_header (httpclient->refbuf->data, BUFSIZE, 0, ret = util_http_build_header (httpclient->refbuf->data, BUFSIZE, 0,
0, 200, NULL, 0, 200, NULL,
"audio/x-mpegurl", NULL, "", NULL); "audio/x-mpegurl", NULL, "", NULL, httpclient);
if (ret == -1 || ret >= (BUFSIZE - 512)) { /* we want at least 512 bytes left for the content of the playlist */ if (ret == -1 || ret >= (BUFSIZE - 512)) { /* we want at least 512 bytes left for the content of the playlist */
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client_send_error(httpclient, 500, 0, "Header generation failed."); client_send_error(httpclient, 500, 0, "Header generation failed.");
...@@ -577,7 +577,7 @@ int fserve_client_create (client_t *httpclient, const char *path) ...@@ -577,7 +577,7 @@ int fserve_client_create (client_t *httpclient, const char *path)
bytes = util_http_build_header (httpclient->refbuf->data, BUFSIZE, 0, bytes = util_http_build_header (httpclient->refbuf->data, BUFSIZE, 0,
0, 206, NULL, 0, 206, NULL,
type, NULL, type, NULL,
NULL, NULL); NULL, NULL, httpclient);
if (bytes == -1 || bytes >= (BUFSIZE - 512)) { /* we want at least 512 bytes left */ if (bytes == -1 || bytes >= (BUFSIZE - 512)) { /* we want at least 512 bytes left */
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client_send_error(httpclient, 500, 0, "Header generation failed."); client_send_error(httpclient, 500, 0, "Header generation failed.");
...@@ -608,7 +608,7 @@ int fserve_client_create (client_t *httpclient, const char *path) ...@@ -608,7 +608,7 @@ int fserve_client_create (client_t *httpclient, const char *path)
bytes = util_http_build_header (httpclient->refbuf->data, BUFSIZE, 0, bytes = util_http_build_header (httpclient->refbuf->data, BUFSIZE, 0,
0, 200, NULL, 0, 200, NULL,
type, NULL, type, NULL,
NULL, NULL); NULL, NULL, httpclient);
if (bytes == -1 || bytes >= (BUFSIZE - 512)) { /* we want at least 512 bytes left */ if (bytes == -1 || bytes >= (BUFSIZE - 512)) { /* we want at least 512 bytes left */
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client_send_error(httpclient, 500, 0, "Header generation failed."); client_send_error(httpclient, 500, 0, "Header generation failed.");
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "connection.h" #include "connection.h"
#include "client.h" #include "client.h"
#include "source.h" #include "source.h"
#include "admin.h"
#define CATMODULE "util" #define CATMODULE "util"
...@@ -620,7 +621,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset, ...@@ -620,7 +621,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
int status, const char * statusmsg, int status, const char * statusmsg,
const char * contenttype, const char * charset, const char * contenttype, const char * charset,
const char * datablock, const char * datablock,
struct source_tag * source) { struct source_tag * source, struct _client_tag * client) {
const char * http_version = "1.0"; const char * http_version = "1.0";
ice_config_t *config; ice_config_t *config;
time_t now; time_t now;
...@@ -695,9 +696,11 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset, ...@@ -695,9 +696,11 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
config = config_get_config(); config = config_get_config();
extra_headers = _build_headers(status, config, source); extra_headers = _build_headers(status, config, source);
ret = snprintf (out, len, "%sServer: %s\r\n%s%s%s%s%s%s%s", ret = snprintf (out, len, "%sServer: %s\r\nAccept-Encoding: identity\r\nConnection: close\r\nAllow: %s\r\n%s%s%s%s%s%s%s",
status_buffer, status_buffer,
config->server_id, config->server_id,
(client->admin_command == ADMIN_COMMAND_ERROR ?
"GET, SOURCE" : "GET"),
currenttime_buffer, currenttime_buffer,
contenttype_buffer, contenttype_buffer,
(status == 401 ? "WWW-Authenticate: Basic realm=\"Icecast2 Server\"\r\n" : ""), (status == 401 ? "WWW-Authenticate: Basic realm=\"Icecast2 Server\"\r\n" : ""),
......
...@@ -82,7 +82,8 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset, ...@@ -82,7 +82,8 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
int status, const char * statusmsg, int status, const char * statusmsg,
const char * contenttype, const char * charset, const char * contenttype, const char * charset,
const char * datablock, const char * datablock,
struct source_tag * source); struct source_tag * source,
struct _client_tag * client);
/* String dictionary type, without support for NULL keys, or multiple /* String dictionary type, without support for NULL keys, or multiple
* instances of the same key */ * instances of the same key */
......
...@@ -241,7 +241,7 @@ void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client) ...@@ -241,7 +241,7 @@ void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client)
if (string == NULL) if (string == NULL)
string = xmlCharStrdup (""); string = xmlCharStrdup ("");
ret = util_http_build_header(refbuf->data, full_len, 0, 0, 200, NULL, mediatype, charset, NULL, NULL); ret = util_http_build_header(refbuf->data, full_len, 0, 0, 200, NULL, mediatype, charset, NULL, NULL, client);
if (ret == -1) { if (ret == -1) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client_send_error(client, 500, 0, "Header generation failed."); client_send_error(client, 500, 0, "Header generation failed.");
...@@ -254,7 +254,7 @@ void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client) ...@@ -254,7 +254,7 @@ void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client)
ICECAST_LOG_DEBUG("Client buffer reallocation succeeded."); ICECAST_LOG_DEBUG("Client buffer reallocation succeeded.");
refbuf->data = new_data; refbuf->data = new_data;
refbuf->len = full_len; refbuf->len = full_len;
ret = util_http_build_header(refbuf->data, full_len, 0, 0, 200, NULL, mediatype, charset, NULL, NULL); ret = util_http_build_header(refbuf->data, full_len, 0, 0, 200, NULL, mediatype, charset, NULL, NULL, client);
if (ret == -1) { if (ret == -1) {
ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); ICECAST_LOG_ERROR("Dropping client as we can not build response headers.");
client_send_error(client, 500, 0, "Header generation failed."); client_send_error(client, 500, 0, "Header generation failed.");
......
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