mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Feature: Support PUT with chunked transfer encoding.
This adds the Transfer-Encoding chunked to PUT support. Please test carefully. Will add PUT to Allow: header after testing. Have fun. Closes: #2088
This commit is contained in:
parent
79cb147c4a
commit
36d10121cf
25
src/client.c
25
src/client.c
@ -158,6 +158,8 @@ void client_destroy(client_t *client)
|
|||||||
connection_close(client->con);
|
connection_close(client->con);
|
||||||
if (client->parser)
|
if (client->parser)
|
||||||
httpp_destroy(client->parser);
|
httpp_destroy(client->parser);
|
||||||
|
if (client->encoding)
|
||||||
|
httpp_encoding_release(client->encoding);
|
||||||
|
|
||||||
global_lock();
|
global_lock();
|
||||||
global.clients--;
|
global.clients--;
|
||||||
@ -177,11 +179,8 @@ void client_destroy(client_t *client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* helper function for reading data from a client */
|
/* helper function for reading data from a client */
|
||||||
int client_read_bytes(client_t *client, void *buf, unsigned len)
|
static ssize_t __client_read_bytes_real(client_t *client, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
int bytes;
|
|
||||||
|
|
||||||
if (client->refbuf && client->refbuf->len) {
|
|
||||||
/* we have data to read from a refbuf first */
|
/* we have data to read from a refbuf first */
|
||||||
if (client->refbuf->len < len)
|
if (client->refbuf->len < len)
|
||||||
len = client->refbuf->len;
|
len = client->refbuf->len;
|
||||||
@ -192,8 +191,24 @@ int client_read_bytes(client_t *client, void *buf, unsigned len)
|
|||||||
}
|
}
|
||||||
client->refbuf->len -= len;
|
client->refbuf->len -= len;
|
||||||
return len;
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int client_read_bytes(client_t *client, void *buf, unsigned len)
|
||||||
|
{
|
||||||
|
ssize_t (*reader)(void*, void*, size_t) = (ssize_t(*)(void*,void*,size_t))__client_read_bytes_real;
|
||||||
|
void *userdata = client;
|
||||||
|
int bytes;
|
||||||
|
|
||||||
|
if (!(client->refbuf && client->refbuf->len)) {
|
||||||
|
reader = (ssize_t(*)(void*,void*,size_t))connection_read_bytes;
|
||||||
|
userdata = client->con;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client->encoding) {
|
||||||
|
bytes = httpp_encoding_read(client->encoding, buf, len, reader, userdata);
|
||||||
|
} else {
|
||||||
|
bytes = reader(userdata, buf, len);
|
||||||
}
|
}
|
||||||
bytes = client->con->read (client->con, buf, len);
|
|
||||||
|
|
||||||
if (bytes == -1 && client->con->error)
|
if (bytes == -1 && client->con->error)
|
||||||
ICECAST_LOG_DEBUG("reading from connection has failed");
|
ICECAST_LOG_DEBUG("reading from connection has failed");
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "acl.h"
|
#include "acl.h"
|
||||||
#include "cfgfile.h"
|
#include "cfgfile.h"
|
||||||
#include "common/httpp/httpp.h"
|
#include "common/httpp/httpp.h"
|
||||||
|
#include "common/httpp/encoding.h"
|
||||||
|
|
||||||
typedef enum _protocol_tag {
|
typedef enum _protocol_tag {
|
||||||
ICECAST_PROTOCOL_HTTP = 0,
|
ICECAST_PROTOCOL_HTTP = 0,
|
||||||
@ -53,6 +54,9 @@ typedef struct _client_tag
|
|||||||
/* the client's http headers */
|
/* the client's http headers */
|
||||||
http_parser_t *parser;
|
http_parser_t *parser;
|
||||||
|
|
||||||
|
/* Transfer Encoding if any */
|
||||||
|
httpp_encoding_t *encoding;
|
||||||
|
|
||||||
/* protocol client uses */
|
/* protocol client uses */
|
||||||
protocol_t protocol;
|
protocol_t protocol;
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit ae2a956d88417f4a9d45a72dc0cd80ee76b6a871
|
Subproject commit f5d9d955a28df8029d4a235feb275b32b2d9b900
|
@ -421,6 +421,11 @@ void connection_uses_ssl(connection_t *con)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t connection_read_bytes(connection_t *con, void *buf, size_t len)
|
||||||
|
{
|
||||||
|
return con->read(con, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
static sock_t wait_for_serversock(int timeout)
|
static sock_t wait_for_serversock(int timeout)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
@ -868,8 +873,18 @@ static inline void source_startup(client_t *client, const char *uri)
|
|||||||
} else {
|
} else {
|
||||||
refbuf_t *ok = refbuf_new(PER_CLIENT_REFBUF_SIZE);
|
refbuf_t *ok = refbuf_new(PER_CLIENT_REFBUF_SIZE);
|
||||||
const char *expectcontinue;
|
const char *expectcontinue;
|
||||||
|
const char *transfer_encoding;
|
||||||
int status_to_send = 200;
|
int status_to_send = 200;
|
||||||
|
|
||||||
|
transfer_encoding = httpp_getvar(source->parser, "transfer-encoding");
|
||||||
|
if (transfer_encoding && strcasecmp(transfer_encoding, HTTPP_ENCODING_IDENTITY) != 0) {
|
||||||
|
client->encoding = httpp_encoding_new(transfer_encoding);
|
||||||
|
if (!client->encoding) {
|
||||||
|
client_send_error(client, 501, 1, "Unimplemented");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* For PUT support we check for 100-continue and send back a 100 to stay in spec */
|
/* For PUT support we check for 100-continue and send back a 100 to stay in spec */
|
||||||
expectcontinue = httpp_getvar (source->parser, "expect");
|
expectcontinue = httpp_getvar (source->parser, "expect");
|
||||||
|
|
||||||
|
@ -63,6 +63,8 @@ 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);
|
void connection_uses_ssl(connection_t *con);
|
||||||
|
|
||||||
|
ssize_t connection_read_bytes(connection_t *con, void *buf, size_t len);
|
||||||
|
|
||||||
extern rwlock_t _source_shutdown_rwlock;
|
extern rwlock_t _source_shutdown_rwlock;
|
||||||
|
|
||||||
#endif /* __CONNECTION_H__ */
|
#endif /* __CONNECTION_H__ */
|
||||||
|
@ -671,6 +671,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
|
|||||||
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;
|
case 426: statusmsg = "Upgrade Required"; http_version = "1.1"; break;
|
||||||
|
case 501: statusmsg = "Unimplemented"; break;
|
||||||
default: statusmsg = "(unknown status code)"; break;
|
default: statusmsg = "(unknown status code)"; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user