mirror of
https://gitlab.xiph.org/xiph/icecast-common.git
synced 2024-11-03 04:17:20 -05:00
Cleaned up version of Ciaran Anscomb's relaying patch.
svn path=/trunk/httpp/; revision=3760
This commit is contained in:
parent
78c08c5f10
commit
68db62a86f
190
httpp/httpp.c
190
httpp/httpp.c
@ -49,33 +49,12 @@ void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults)
|
||||
}
|
||||
}
|
||||
|
||||
int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
|
||||
static int split_headers(char *data, unsigned long len, char **line)
|
||||
{
|
||||
char *data, *tmp;
|
||||
char *line[MAX_HEADERS]; /* limited to 32 lines, should be more than enough */
|
||||
int i, l, retlen;
|
||||
int lines;
|
||||
char *req_type = NULL;
|
||||
char *uri = NULL;
|
||||
char *version = NULL;
|
||||
char *name = NULL;
|
||||
char *value = NULL;
|
||||
int whitespace, where;
|
||||
int slen;
|
||||
|
||||
if (http_data == NULL)
|
||||
return 0;
|
||||
|
||||
/* make a local copy of the data, including 0 terminator */
|
||||
data = (char *)malloc(len+1);
|
||||
if (data == NULL) return 0;
|
||||
memcpy(data, http_data, len);
|
||||
data[len] = 0;
|
||||
|
||||
/* first we count how many lines there are
|
||||
** and set up the line[] array
|
||||
*/
|
||||
lines = 0;
|
||||
int i, lines = 0;
|
||||
line[lines] = data;
|
||||
for (i = 0; i < len && lines < MAX_HEADERS; i++) {
|
||||
if (data[i] == '\r')
|
||||
@ -93,7 +72,134 @@ int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
|
||||
|
||||
i++;
|
||||
while (data[i] == '\n') i++;
|
||||
retlen = i;
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
static void parse_headers(http_parser_t *parser, char **line, int lines)
|
||||
{
|
||||
int i,l;
|
||||
int whitespace, where, slen;
|
||||
char *name = NULL;
|
||||
char *value = NULL;
|
||||
|
||||
/* parse the name: value lines. */
|
||||
for (l = 1; l < lines; l++) {
|
||||
where = 0;
|
||||
whitespace = 0;
|
||||
name = line[l];
|
||||
value = NULL;
|
||||
slen = strlen(line[l]);
|
||||
for (i = 0; i < slen; i++) {
|
||||
if (line[l][i] == ':') {
|
||||
whitespace = 1;
|
||||
line[l][i] = '\0';
|
||||
} else {
|
||||
if (whitespace) {
|
||||
whitespace = 0;
|
||||
while (i < slen && line[l][i] == ' ')
|
||||
i++;
|
||||
|
||||
if (i < slen)
|
||||
value = &line[l][i];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name != NULL && value != NULL) {
|
||||
httpp_setvar(parser, _lowercase(name), value);
|
||||
name = NULL;
|
||||
value = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int httpp_parse_response(http_parser_t *parser, char *http_data, unsigned long len, char *uri)
|
||||
{
|
||||
char *data;
|
||||
char *line[MAX_HEADERS];
|
||||
int lines, slen,i, whitespace=0, where=0,code;
|
||||
char *version=NULL, *resp_code=NULL, *message=NULL;
|
||||
|
||||
if(http_data == NULL)
|
||||
return 0;
|
||||
|
||||
/* make a local copy of the data, including 0 terminator */
|
||||
data = (char *)malloc(len+1);
|
||||
if (data == NULL) return 0;
|
||||
memcpy(data, http_data, len);
|
||||
data[len] = 0;
|
||||
|
||||
lines = split_headers(data, len, line);
|
||||
|
||||
/* In this case, the first line contains:
|
||||
* VERSION RESPONSE_CODE MESSAGE, such as
|
||||
* HTTP/1.0 200 OK
|
||||
*/
|
||||
slen = strlen(line[0]);
|
||||
version = line[0];
|
||||
for(i=0; i < slen; i++) {
|
||||
if(line[0][i] == ' ') {
|
||||
line[0][i] = 0;
|
||||
whitespace = 1;
|
||||
}
|
||||
else if(whitespace) {
|
||||
whitespace = 0;
|
||||
where++;
|
||||
if(where == 1)
|
||||
resp_code = &line[0][i];
|
||||
else {
|
||||
message = &line[0][i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(version == NULL || resp_code == NULL || message == NULL) {
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
code = atoi(resp_code);
|
||||
if(code < 200 || code >= 300) {
|
||||
httpp_setvar(parser, HTTPP_VAR_ERROR_MESSAGE, message);
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
httpp_setvar(parser, HTTPP_VAR_URI, uri);
|
||||
httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "RELAY");
|
||||
|
||||
parse_headers(parser, line, lines);
|
||||
|
||||
free(data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
|
||||
{
|
||||
char *data, *tmp;
|
||||
char *line[MAX_HEADERS]; /* limited to 32 lines, should be more than enough */
|
||||
int i;
|
||||
int lines;
|
||||
char *req_type = NULL;
|
||||
char *uri = NULL;
|
||||
char *version = NULL;
|
||||
int whitespace, where, slen;
|
||||
|
||||
if (http_data == NULL)
|
||||
return 0;
|
||||
|
||||
/* make a local copy of the data, including 0 terminator */
|
||||
data = (char *)malloc(len+1);
|
||||
if (data == NULL) return 0;
|
||||
memcpy(data, http_data, len);
|
||||
data[len] = 0;
|
||||
|
||||
lines = split_headers(data, len, line);
|
||||
|
||||
/* parse the first line special
|
||||
** the format is:
|
||||
@ -189,48 +295,18 @@ int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parser->uri != NULL) {
|
||||
if (parser->uri != NULL) {
|
||||
httpp_setvar(parser, HTTPP_VAR_URI, parser->uri);
|
||||
} else {
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parse the name: value lines. */
|
||||
for (l = 1; l < lines; l++) {
|
||||
where = 0;
|
||||
whitespace = 0;
|
||||
name = line[l];
|
||||
value = NULL;
|
||||
slen = strlen(line[l]);
|
||||
for (i = 0; i < slen; i++) {
|
||||
if (line[l][i] == ':') {
|
||||
whitespace = 1;
|
||||
line[l][i] = '\0';
|
||||
} else {
|
||||
if (whitespace) {
|
||||
whitespace = 0;
|
||||
while (i < slen && line[l][i] == ' ')
|
||||
i++;
|
||||
|
||||
if (i < slen)
|
||||
value = &line[l][i];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name != NULL && value != NULL) {
|
||||
httpp_setvar(parser, _lowercase(name), value);
|
||||
name = NULL;
|
||||
value = NULL;
|
||||
}
|
||||
}
|
||||
parse_headers(parser, line, lines);
|
||||
|
||||
free(data);
|
||||
|
||||
return retlen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void httpp_setvar(http_parser_t *parser, char *name, char *value)
|
||||
|
@ -12,6 +12,7 @@
|
||||
#define HTTPP_VAR_VERSION "__version"
|
||||
#define HTTPP_VAR_URI "__uri"
|
||||
#define HTTPP_VAR_REQ_TYPE "__req_type"
|
||||
#define HTTPP_VAR_ERROR_MESSAGE "__errormessage"
|
||||
|
||||
typedef enum httpp_request_type_tag {
|
||||
httpp_req_none, httpp_req_get, httpp_req_post, httpp_req_head, httpp_req_source, httpp_req_play, httpp_req_stats, httpp_req_unknown
|
||||
@ -30,13 +31,13 @@ typedef struct http_varlist_tag {
|
||||
typedef struct http_parser_tag {
|
||||
httpp_request_type_e req_type;
|
||||
char *uri;
|
||||
|
||||
avl_tree *vars;
|
||||
} http_parser_t;
|
||||
|
||||
http_parser_t *httpp_create_parser(void);
|
||||
void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults);
|
||||
int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len);
|
||||
int httpp_parse_response(http_parser_t *parser, char *http_data, unsigned long len, char *uri);
|
||||
void httpp_setvar(http_parser_t *parser, char *name, char *value);
|
||||
char *httpp_getvar(http_parser_t *parser, char *name);
|
||||
void httpp_destroy(http_parser_t *parser);
|
||||
|
@ -127,6 +127,7 @@ static char *_lookup(const char *what, char *buff, int len)
|
||||
if (host == NULL) {
|
||||
buff = NULL;
|
||||
} else {
|
||||
// still need to be locked here?
|
||||
temp = inet_ntoa(*(struct in_addr *)host->h_addr);
|
||||
strncpy(buff, temp, len);
|
||||
}
|
||||
|
@ -465,6 +465,18 @@ void thread_cond_broadcast_c(cond_t *cond, int line, char *file)
|
||||
pthread_cond_broadcast(&cond->sys_cond);
|
||||
}
|
||||
|
||||
void thread_cond_timedwait_c(cond_t *cond, int millis, int line, char *file)
|
||||
{
|
||||
struct timespec time;
|
||||
|
||||
time.tv_sec = millis/1000;
|
||||
time.tv_nsec = (millis - time.tv_sec*1000)*1000000;
|
||||
|
||||
pthread_mutex_lock(&cond->cond_mutex);
|
||||
pthread_cond_timedwait(&cond->sys_cond, &cond->cond_mutex, &time);
|
||||
pthread_mutex_unlock(&cond->cond_mutex);
|
||||
}
|
||||
|
||||
void thread_cond_wait_c(cond_t *cond, int line, char *file)
|
||||
{
|
||||
pthread_mutex_lock(&cond->cond_mutex);
|
||||
@ -472,6 +484,8 @@ void thread_cond_wait_c(cond_t *cond, int line, char *file)
|
||||
pthread_mutex_unlock(&cond->cond_mutex);
|
||||
}
|
||||
|
||||
static int rwlocknum = 0;
|
||||
|
||||
void thread_rwlock_create_c(rwlock_t *rwlock, int line, char *file)
|
||||
{
|
||||
pthread_rwlock_init(&rwlock->sys_rwlock, NULL);
|
||||
|
@ -86,6 +86,7 @@ typedef struct rwlock_tag {
|
||||
#define thread_cond_signal(x) thread_cond_signal_c(x,__LINE__,__FILE__)
|
||||
#define thread_cond_broadcast(x) thread_cond_broadcast_c(x,__LINE__,__FILE__)
|
||||
#define thread_cond_wait(x) thread_cond_wait_c(x,__LINE__,__FILE__)
|
||||
#define thread_cond_timedwait(x,t) thread_cond_wait_c(x,t,__LINE__,__FILE__)
|
||||
#define thread_rwlock_create(x) thread_rwlock_create_c(x,__LINE__,__FILE__)
|
||||
#define thread_rwlock_rlock(x) thread_rwlock_rlock_c(x,__LINE__,__FILE__)
|
||||
#define thread_rwlock_wlock(x) thread_rwlock_wlock_c(x,__LINE__,__FILE__)
|
||||
@ -113,6 +114,7 @@ void thread_cond_create_c(cond_t *cond, int line, char *file);
|
||||
void thread_cond_signal_c(cond_t *cond, int line, char *file);
|
||||
void thread_cond_broadcast_c(cond_t *cond, int line, char *file);
|
||||
void thread_cond_wait_c(cond_t *cond, int line, char *file);
|
||||
void thread_cond_timedwait_c(cond_t *cond, int millis, int line, char *file);
|
||||
void thread_cond_destroy(cond_t *cond);
|
||||
void thread_rwlock_create_c(rwlock_t *rwlock, int line, char *file);
|
||||
void thread_rwlock_rlock_c(rwlock_t *rwlock, int line, char *file);
|
||||
|
Loading…
Reference in New Issue
Block a user