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
|
/* first we count how many lines there are
|
||||||
** and set up the line[] array
|
** and set up the line[] array
|
||||||
*/
|
*/
|
||||||
lines = 0;
|
int i, lines = 0;
|
||||||
line[lines] = data;
|
line[lines] = data;
|
||||||
for (i = 0; i < len && lines < MAX_HEADERS; i++) {
|
for (i = 0; i < len && lines < MAX_HEADERS; i++) {
|
||||||
if (data[i] == '\r')
|
if (data[i] == '\r')
|
||||||
@ -93,7 +72,134 @@ int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
|
|||||||
|
|
||||||
i++;
|
i++;
|
||||||
while (data[i] == '\n') 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
|
/* parse the first line special
|
||||||
** the format is:
|
** the format is:
|
||||||
@ -189,48 +295,18 @@ int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parser->uri != NULL) {
|
if (parser->uri != NULL) {
|
||||||
httpp_setvar(parser, HTTPP_VAR_URI, parser->uri);
|
httpp_setvar(parser, HTTPP_VAR_URI, parser->uri);
|
||||||
} else {
|
} else {
|
||||||
free(data);
|
free(data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse the name: value lines. */
|
parse_headers(parser, line, 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
return retlen;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpp_setvar(http_parser_t *parser, char *name, char *value)
|
void httpp_setvar(http_parser_t *parser, char *name, char *value)
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#define HTTPP_VAR_VERSION "__version"
|
#define HTTPP_VAR_VERSION "__version"
|
||||||
#define HTTPP_VAR_URI "__uri"
|
#define HTTPP_VAR_URI "__uri"
|
||||||
#define HTTPP_VAR_REQ_TYPE "__req_type"
|
#define HTTPP_VAR_REQ_TYPE "__req_type"
|
||||||
|
#define HTTPP_VAR_ERROR_MESSAGE "__errormessage"
|
||||||
|
|
||||||
typedef enum httpp_request_type_tag {
|
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
|
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 {
|
typedef struct http_parser_tag {
|
||||||
httpp_request_type_e req_type;
|
httpp_request_type_e req_type;
|
||||||
char *uri;
|
char *uri;
|
||||||
|
|
||||||
avl_tree *vars;
|
avl_tree *vars;
|
||||||
} http_parser_t;
|
} http_parser_t;
|
||||||
|
|
||||||
http_parser_t *httpp_create_parser(void);
|
http_parser_t *httpp_create_parser(void);
|
||||||
void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults);
|
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(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);
|
void httpp_setvar(http_parser_t *parser, char *name, char *value);
|
||||||
char *httpp_getvar(http_parser_t *parser, char *name);
|
char *httpp_getvar(http_parser_t *parser, char *name);
|
||||||
void httpp_destroy(http_parser_t *parser);
|
void httpp_destroy(http_parser_t *parser);
|
||||||
|
@ -127,6 +127,7 @@ static char *_lookup(const char *what, char *buff, int len)
|
|||||||
if (host == NULL) {
|
if (host == NULL) {
|
||||||
buff = NULL;
|
buff = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
// still need to be locked here?
|
||||||
temp = inet_ntoa(*(struct in_addr *)host->h_addr);
|
temp = inet_ntoa(*(struct in_addr *)host->h_addr);
|
||||||
strncpy(buff, temp, len);
|
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);
|
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)
|
void thread_cond_wait_c(cond_t *cond, int line, char *file)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&cond->cond_mutex);
|
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);
|
pthread_mutex_unlock(&cond->cond_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rwlocknum = 0;
|
||||||
|
|
||||||
void thread_rwlock_create_c(rwlock_t *rwlock, int line, char *file)
|
void thread_rwlock_create_c(rwlock_t *rwlock, int line, char *file)
|
||||||
{
|
{
|
||||||
pthread_rwlock_init(&rwlock->sys_rwlock, NULL);
|
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_signal(x) thread_cond_signal_c(x,__LINE__,__FILE__)
|
||||||
#define thread_cond_broadcast(x) thread_cond_broadcast_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_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_create(x) thread_rwlock_create_c(x,__LINE__,__FILE__)
|
||||||
#define thread_rwlock_rlock(x) thread_rwlock_rlock_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__)
|
#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_signal_c(cond_t *cond, int line, char *file);
|
||||||
void thread_cond_broadcast_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_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_cond_destroy(cond_t *cond);
|
||||||
void thread_rwlock_create_c(rwlock_t *rwlock, int line, char *file);
|
void thread_rwlock_create_c(rwlock_t *rwlock, int line, char *file);
|
||||||
void thread_rwlock_rlock_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