1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-12-04 14:46:30 -05:00

Feature: Allow RFC 2817 style Upgrade command.

This allows the usage of RFC 2817 style upgrade commands.
This is not correctly announced yet.
Can hardly be tested as most clients do not support this.
Will be helpful with TLS support in libshout.
See: #2159, #2152
This commit is contained in:
Philipp Schafft 2015-02-02 00:34:45 +00:00
parent c806e47a4a
commit 71408e6291
5 changed files with 73 additions and 1 deletions

View File

@ -107,6 +107,8 @@ static inline void client_reuseconnection(client_t *client) {
client_destroy(client);
if (reuse == ICECAST_REUSE_UPGRADETLS)
connection_uses_ssl(con);
connection_queue(con);
}
@ -239,6 +241,62 @@ void client_send_100(client_t *client)
sock_write (client->con->sock, "HTTP/1.1 100 Continue\r\n\r\n");
}
void client_send_101(client_t *client, reuse_t reuse)
{
ssize_t ret;
if (!client)
return;
if (reuse != ICECAST_REUSE_UPGRADETLS) {
client_send_500(client, "Bad reuse parameter");
return;
}
ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, 0,
0, 101, NULL,
"text/plain", "utf-8",
NULL, NULL, client);
snprintf(client->refbuf->data + ret, PER_CLIENT_REFBUF_SIZE - ret,
"Content-Length: 0\r\nUpgrade: TLS/1.0, HTTP/1.0\r\nConnection: Upgrade\r\n\r\n");
client->respcode = 101;
client->refbuf->len = strlen(client->refbuf->data);
client->reuse = reuse;
fserve_add_client(client, NULL);
}
void client_send_426(client_t *client, reuse_t reuse)
{
ssize_t ret;
if (!client)
return;
if (reuse != ICECAST_REUSE_UPGRADETLS) {
client_send_500(client, "Bad reuse parameter");
return;
}
ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, 0,
0, 426, NULL,
"text/plain", "utf-8",
NULL, NULL, client);
snprintf(client->refbuf->data + ret, PER_CLIENT_REFBUF_SIZE - ret,
"Content-Length: 0\r\nUpgrade: TLS/1.0, HTTP/1.0\r\nConnection: Upgrade\r\n\r\n");
client->respcode = 426;
client->refbuf->len = strlen(client->refbuf->data);
client->reuse = ICECAST_REUSE_KEEPALIVE;
fserve_add_client(client, NULL);
}
/* this function is designed to work even if client is in bad state */
static inline void client_send_500(client_t *client, const char *message)
{

View File

@ -34,7 +34,9 @@ typedef enum _reuse_tag {
/* do not reuse */
ICECAST_REUSE_CLOSE = 0,
/* reuse */
ICECAST_REUSE_KEEPALIVE
ICECAST_REUSE_KEEPALIVE,
/* Upgrade to TLS */
ICECAST_REUSE_UPGRADETLS
} reuse_t;
typedef struct _client_tag
@ -105,6 +107,8 @@ int client_create (client_t **c_ptr, connection_t *con, http_parser_t *parser);
void client_destroy(client_t *client);
void client_send_error(client_t *client, int status, int plain, const char *message);
void client_send_100(client_t *client);
void client_send_101(client_t *client, reuse_t reuse);
void client_send_426(client_t *client, reuse_t reuse);
int client_send_bytes (client_t *client, const void *buf, unsigned len);
int client_read_bytes (client_t *client, void *buf, unsigned len);
void client_set_queue (client_t *client, refbuf_t *refbuf);

View File

@ -1423,6 +1423,7 @@ static void _handle_connection(void)
}
if (already_parsed || httpp_parse (parser, client->refbuf->data, node->offset)) {
char *uri;
const char *upgrade;
/* we may have more than just headers, so prepare for it */
if (node->stream_offset == node->offset) {
@ -1449,6 +1450,12 @@ static void _handle_connection(void)
continue;
}
upgrade = httpp_getvar(parser, "upgrade");
if (upgrade && strstr(upgrade, "TLS/1.0") != NULL) {
client_send_101(client, ICECAST_REUSE_UPGRADETLS);
continue;
}
uri = util_normalise_uri(rawuri);
if (!uri) {

View File

@ -61,6 +61,7 @@ void connection_close(connection_t *con);
connection_t *connection_create(sock_t sock, sock_t serversock, char *ip);
int connection_complete_source(struct source_tag *source, int response);
void connection_queue(connection_t *con);
void connection_uses_ssl(connection_t *con);
extern rwlock_t _source_shutdown_rwlock;

View File

@ -652,6 +652,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
{
switch (status)
{
case 101: statusmsg = "Switching Protocols"; http_version = "1.1"; break;
case 200: statusmsg = "OK"; break;
case 206: statusmsg = "Partial Content"; http_version = "1.1"; break;
case 400: statusmsg = "Bad Request"; break;
@ -659,6 +660,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
case 403: statusmsg = "Forbidden"; break;
case 404: statusmsg = "File Not Found"; break;
case 416: statusmsg = "Request Range Not Satisfiable"; break;
case 426: statusmsg = "Upgrade Required"; http_version = "1.1"; break;
default: statusmsg = "(unknown status code)"; break;
}
}