1
0
mirror of https://gitlab.xiph.org/xiph/icecast-common.git synced 2024-06-23 06:25:25 +00:00

Cleaned up version of Ciaran Anscomb's relaying patch.

svn path=/trunk/httpp/; revision=3760
This commit is contained in:
Michael Smith 2002-08-05 14:48:04 +00:00
parent 78c08c5f10
commit 68db62a86f
5 changed files with 152 additions and 58 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);