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:
parent
c806e47a4a
commit
71408e6291
58
src/client.c
58
src/client.c
@ -107,6 +107,8 @@ static inline void client_reuseconnection(client_t *client) {
|
|||||||
|
|
||||||
client_destroy(client);
|
client_destroy(client);
|
||||||
|
|
||||||
|
if (reuse == ICECAST_REUSE_UPGRADETLS)
|
||||||
|
connection_uses_ssl(con);
|
||||||
connection_queue(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");
|
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 */
|
/* 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)
|
static inline void client_send_500(client_t *client, const char *message)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,9 @@ typedef enum _reuse_tag {
|
|||||||
/* do not reuse */
|
/* do not reuse */
|
||||||
ICECAST_REUSE_CLOSE = 0,
|
ICECAST_REUSE_CLOSE = 0,
|
||||||
/* reuse */
|
/* reuse */
|
||||||
ICECAST_REUSE_KEEPALIVE
|
ICECAST_REUSE_KEEPALIVE,
|
||||||
|
/* Upgrade to TLS */
|
||||||
|
ICECAST_REUSE_UPGRADETLS
|
||||||
} reuse_t;
|
} reuse_t;
|
||||||
|
|
||||||
typedef struct _client_tag
|
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_destroy(client_t *client);
|
||||||
void client_send_error(client_t *client, int status, int plain, const char *message);
|
void client_send_error(client_t *client, int status, int plain, const char *message);
|
||||||
void client_send_100(client_t *client);
|
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_send_bytes (client_t *client, const void *buf, unsigned len);
|
||||||
int client_read_bytes (client_t *client, 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);
|
void client_set_queue (client_t *client, refbuf_t *refbuf);
|
||||||
|
@ -1423,6 +1423,7 @@ static void _handle_connection(void)
|
|||||||
}
|
}
|
||||||
if (already_parsed || httpp_parse (parser, client->refbuf->data, node->offset)) {
|
if (already_parsed || httpp_parse (parser, client->refbuf->data, node->offset)) {
|
||||||
char *uri;
|
char *uri;
|
||||||
|
const char *upgrade;
|
||||||
|
|
||||||
/* we may have more than just headers, so prepare for it */
|
/* we may have more than just headers, so prepare for it */
|
||||||
if (node->stream_offset == node->offset) {
|
if (node->stream_offset == node->offset) {
|
||||||
@ -1449,6 +1450,12 @@ static void _handle_connection(void)
|
|||||||
continue;
|
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);
|
uri = util_normalise_uri(rawuri);
|
||||||
|
|
||||||
if (!uri) {
|
if (!uri) {
|
||||||
|
@ -61,6 +61,7 @@ void connection_close(connection_t *con);
|
|||||||
connection_t *connection_create(sock_t sock, sock_t serversock, char *ip);
|
connection_t *connection_create(sock_t sock, sock_t serversock, char *ip);
|
||||||
int connection_complete_source(struct source_tag *source, int response);
|
int connection_complete_source(struct source_tag *source, int response);
|
||||||
void connection_queue(connection_t *con);
|
void connection_queue(connection_t *con);
|
||||||
|
void connection_uses_ssl(connection_t *con);
|
||||||
|
|
||||||
extern rwlock_t _source_shutdown_rwlock;
|
extern rwlock_t _source_shutdown_rwlock;
|
||||||
|
|
||||||
|
@ -652,6 +652,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
|
|||||||
{
|
{
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
|
case 101: statusmsg = "Switching Protocols"; http_version = "1.1"; break;
|
||||||
case 200: statusmsg = "OK"; break;
|
case 200: statusmsg = "OK"; break;
|
||||||
case 206: statusmsg = "Partial Content"; http_version = "1.1"; break;
|
case 206: statusmsg = "Partial Content"; http_version = "1.1"; break;
|
||||||
case 400: statusmsg = "Bad Request"; 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 403: statusmsg = "Forbidden"; break;
|
||||||
case 404: statusmsg = "File Not Found"; break;
|
case 404: statusmsg = "File Not Found"; break;
|
||||||
case 416: statusmsg = "Request Range Not Satisfiable"; 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;
|
default: statusmsg = "(unknown status code)"; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user