mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Feature: Implemented Gopher support.
Gopher clients are automagically detected based on the selector. All selectors must start with / and map directly to the HTTP paths.
This commit is contained in:
parent
924d0e00ec
commit
2a4d4703a2
10
src/client.c
10
src/client.c
@ -149,7 +149,7 @@ void client_destroy(client_t *client)
|
||||
if (client == NULL)
|
||||
return;
|
||||
|
||||
if (client->reuse != ICECAST_REUSE_CLOSE) {
|
||||
if (client->protocol != ICECAST_PROTOCOL_GOPHER && client->reuse != ICECAST_REUSE_CLOSE) {
|
||||
/* only reuse the client if we reached the body's EOF. */
|
||||
if (client_body_eof(client) == 1) {
|
||||
client_reuseconnection(client);
|
||||
@ -167,6 +167,10 @@ void client_destroy(client_t *client)
|
||||
if (auth_release_client(client))
|
||||
return;
|
||||
|
||||
if (client->protocol == ICECAST_PROTOCOL_GOPHER && client->respcode != 0) {
|
||||
client_send_bytes(client, "\r\n.\r\n", 5);
|
||||
}
|
||||
|
||||
/* write log entry if ip is set (some things don't set it, like outgoing
|
||||
* slave requests
|
||||
*/
|
||||
@ -276,9 +280,11 @@ static inline void _client_send_error(client_t *client, int plain, const icecast
|
||||
}
|
||||
data->len = strlen(data->data);
|
||||
|
||||
snprintf(client->refbuf->data + ret, PER_CLIENT_REFBUF_SIZE - ret,
|
||||
if (client->protocol != ICECAST_PROTOCOL_GOPHER) {
|
||||
snprintf(client->refbuf->data + ret, PER_CLIENT_REFBUF_SIZE - ret,
|
||||
"Content-Length: %llu\r\n\r\n",
|
||||
(long long unsigned int)data->len);
|
||||
}
|
||||
|
||||
client->respcode = error->http_status;
|
||||
client->refbuf->len = strlen (client->refbuf->data);
|
||||
|
@ -571,6 +571,8 @@ static void process_request_queue (void)
|
||||
stream_offset = (ptr+2) - client->refbuf->data;
|
||||
break;
|
||||
}
|
||||
if (client->refbuf->data[0] == '/' && strstr(client->refbuf->data, "\n") != NULL)
|
||||
break;
|
||||
pass_it = 0;
|
||||
} while (0);
|
||||
|
||||
@ -1222,6 +1224,49 @@ static void _handle_shoutcast_compatible(client_queue_t *node)
|
||||
return;
|
||||
}
|
||||
|
||||
static int _handle_gopher_compatible(client_queue_t *node)
|
||||
{
|
||||
size_t n_len;
|
||||
char *n;
|
||||
char *ptr;
|
||||
http_parser_t *parser;
|
||||
client_t *client = node->client;
|
||||
|
||||
ptr = strstr(client->refbuf->data, "\r\n");
|
||||
if (!ptr)
|
||||
ptr = strstr(client->refbuf->data, "\n");
|
||||
if (!ptr)
|
||||
return -1;
|
||||
|
||||
*ptr = 0;
|
||||
|
||||
n_len = strlen(client->refbuf->data) + 80;
|
||||
n = calloc(1, n_len);
|
||||
if (!n) {
|
||||
client_destroy(client);
|
||||
free(node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(n, n_len, "GET %s HTTP/1.0\r\n\r\n", client->refbuf->data);
|
||||
|
||||
parser = httpp_create_parser();
|
||||
httpp_initialize(parser, NULL);
|
||||
if (httpp_parse(parser, n, strlen(n))) {
|
||||
client->refbuf->len = 0;
|
||||
client->parser = parser;
|
||||
client->protocol = ICECAST_PROTOCOL_GOPHER;
|
||||
return 1;
|
||||
} else {
|
||||
httpp_destroy(parser);
|
||||
client_destroy(client);
|
||||
}
|
||||
free(n);
|
||||
free(node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Handle <resource> lookups here.
|
||||
*/
|
||||
|
||||
@ -1616,6 +1661,13 @@ static void _handle_connection(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check for gopher clients */
|
||||
if (client->refbuf->data[0] == '/') {
|
||||
if (_handle_gopher_compatible(node) == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* process normal HTTP headers */
|
||||
if (client->parser) {
|
||||
already_parsed = 1;
|
||||
|
10
src/fserve.c
10
src/fserve.c
@ -620,10 +620,12 @@ int fserve_client_create (client_t *httpclient, const char *path)
|
||||
fclose(file);
|
||||
return -1;
|
||||
}
|
||||
bytes += snprintf (httpclient->refbuf->data + bytes, BUFSIZE - bytes,
|
||||
"Accept-Ranges: bytes\r\n"
|
||||
"Content-Length: %" PRI_OFF_T "\r\n\r\n",
|
||||
content_length);
|
||||
if (httpclient->protocol != ICECAST_PROTOCOL_GOPHER) {
|
||||
bytes += snprintf (httpclient->refbuf->data + bytes, BUFSIZE - bytes,
|
||||
"Accept-Ranges: bytes\r\n"
|
||||
"Content-Length: %" PRI_OFF_T "\r\n\r\n",
|
||||
content_length);
|
||||
}
|
||||
free (type);
|
||||
}
|
||||
httpclient->refbuf->len = bytes;
|
||||
|
@ -697,6 +697,10 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset,
|
||||
out += offset;
|
||||
len -= offset;
|
||||
|
||||
if (client && client->protocol == ICECAST_PROTOCOL_GOPHER) {
|
||||
return snprintf(out, len, "%s", (datablock) ? datablock : "");
|
||||
}
|
||||
|
||||
if (status == -1)
|
||||
{
|
||||
status_buffer[0] = '\0';
|
||||
|
@ -373,7 +373,11 @@ void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client)
|
||||
}
|
||||
|
||||
if (!failed) {
|
||||
snprintf(refbuf->data + ret, full_len - ret, "Content-Length: %d\r\n\r\n%s", len, string);
|
||||
if (client->protocol == ICECAST_PROTOCOL_GOPHER) {
|
||||
snprintf(refbuf->data + ret, full_len - ret, "%s", string);
|
||||
} else {
|
||||
snprintf(refbuf->data + ret, full_len - ret, "Content-Length: %d\r\n\r\n%s", len, string);
|
||||
}
|
||||
|
||||
client->respcode = 200;
|
||||
client_set_queue (client, NULL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user