diff --git a/httpp/httpp.c b/httpp/httpp.c index aeb9346..cae45c5 100644 --- a/httpp/httpp.c +++ b/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) diff --git a/httpp/httpp.h b/httpp/httpp.h index 7e03f32..6901fa5 100644 --- a/httpp/httpp.h +++ b/httpp/httpp.h @@ -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); diff --git a/net/resolver.c b/net/resolver.c index cc2b6af..3711b21 100644 --- a/net/resolver.c +++ b/net/resolver.c @@ -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); } diff --git a/thread/thread.c b/thread/thread.c index 949c641..e312e3f 100644 --- a/thread/thread.c +++ b/thread/thread.c @@ -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); diff --git a/thread/thread.h b/thread/thread.h index a352265..6ab5c7b 100644 --- a/thread/thread.h +++ b/thread/thread.h @@ -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);