mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Cleanup: unbreak 100-continue a bit.
This tries to unbreak the 100-continue thing a bit. Proper headers are send in case of 100-continue. Also the 200 OK was moved to the end of the stream. The client may even be reused. But I'm not sure we only do 'End of stream' in cases we are not on an undefined state of the client. Do we as of now support anything that give us EOS without a fatal socket state (error or shutdown)? At least this unbreaks 100-continue with active TLS that was broken as hell as we sent the header in clear over the socket. Not checking if it was transmitted completly or something. Using lowlevel socket calls (in contrast to the connection level calls that would have handled the TLS just fine). While this seem sto be a huge improvement to the situation I kindly ask you to do a lot testing on this. Both with SOURCE as well as PUT clients.
This commit is contained in:
parent
d6908eb024
commit
79cb147c4a
@ -251,12 +251,6 @@ void client_send_error(client_t *client, int status, int plain, const char *mess
|
||||
fserve_add_client (client, NULL);
|
||||
}
|
||||
|
||||
void client_send_100(client_t *client)
|
||||
{
|
||||
/* On demand inject a HTTP/1.1 100 Continue to make sure clients are happy */
|
||||
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;
|
||||
|
@ -106,7 +106,6 @@ typedef struct _client_tag
|
||||
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);
|
||||
|
@ -814,20 +814,6 @@ int connection_complete_source(source_t *source, int response)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* For PUT support we check for 100-continue and send back a 100 to stay in spec */
|
||||
expectcontinue = httpp_getvar (source->parser, "expect");
|
||||
if (expectcontinue != NULL) {
|
||||
#ifdef HAVE_STRCASESTR
|
||||
if (strcasestr (expectcontinue, "100-continue") != NULL)
|
||||
#else
|
||||
ICECAST_LOG_WARN("OS doesn't support case insenestive substring checks...");
|
||||
if (strstr (expectcontinue, "100-continue") != NULL)
|
||||
#endif
|
||||
{
|
||||
client_send_100 (source->client);
|
||||
}
|
||||
}
|
||||
|
||||
global.sources++;
|
||||
stats_event_args(NULL, "sources", "%d", global.sources);
|
||||
global_unlock();
|
||||
@ -881,8 +867,26 @@ static inline void source_startup(client_t *client, const char *uri)
|
||||
source_client_callback(client, source);
|
||||
} else {
|
||||
refbuf_t *ok = refbuf_new(PER_CLIENT_REFBUF_SIZE);
|
||||
const char *expectcontinue;
|
||||
int status_to_send = 200;
|
||||
|
||||
/* For PUT support we check for 100-continue and send back a 100 to stay in spec */
|
||||
expectcontinue = httpp_getvar (source->parser, "expect");
|
||||
|
||||
if (expectcontinue != NULL) {
|
||||
#ifdef HAVE_STRCASESTR
|
||||
if (strcasestr (expectcontinue, "100-continue") != NULL)
|
||||
#else
|
||||
ICECAST_LOG_WARN("OS doesn't support case insenestive substring checks...");
|
||||
if (strstr (expectcontinue, "100-continue") != NULL)
|
||||
#endif
|
||||
{
|
||||
status_to_send = 100;
|
||||
}
|
||||
}
|
||||
|
||||
client->respcode = 200;
|
||||
util_http_build_header(ok->data, PER_CLIENT_REFBUF_SIZE, 0, 0, 200, NULL, NULL, NULL, "", NULL, client);
|
||||
util_http_build_header(ok->data, PER_CLIENT_REFBUF_SIZE, 0, 0, status_to_send, NULL, NULL, NULL, "", NULL, client);
|
||||
ok->len = strlen(ok->data);
|
||||
/* we may have unprocessed data read in, so don't overwrite it */
|
||||
ok->associated = client->refbuf;
|
||||
|
25
src/source.c
25
src/source.c
@ -887,6 +887,31 @@ static void source_shutdown (source_t *source)
|
||||
/* delete this sources stats */
|
||||
stats_event(source->mount, NULL, NULL);
|
||||
|
||||
if (source->client && source->parser) {
|
||||
/* For PUT support we check for 100-continue and send back a final 200. */
|
||||
const char *expectcontinue = httpp_getvar(source->parser, "expect");
|
||||
|
||||
if (expectcontinue != NULL) {
|
||||
#ifdef HAVE_STRCASESTR
|
||||
if (strcasestr (expectcontinue, "100-continue") != NULL)
|
||||
#else
|
||||
ICECAST_LOG_WARN("OS doesn't support case insenestive substring checks...");
|
||||
if (strstr (expectcontinue, "100-continue") != NULL)
|
||||
#endif
|
||||
{
|
||||
client_t *client = source->client;
|
||||
source->client = NULL; /* detach client from source. */
|
||||
|
||||
util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, 0, 0, 200, NULL, NULL, NULL, "", NULL, source->client);
|
||||
client->refbuf->len = strlen(client->refbuf->data);
|
||||
refbuf_release(client->refbuf->next);
|
||||
client->refbuf->next = NULL;
|
||||
client->pos = 0;
|
||||
fserve_add_client(client, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we don't remove the source from the tree here, it may be a relay and
|
||||
therefore reserved */
|
||||
source_clear_source(source);
|
||||
|
@ -661,6 +661,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case 100: statusmsg = "Continue"; http_version = "1.1"; break;
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user