@ -285,23 +285,21 @@ void ast_http_uri_unlink(struct ast_http_uri *urih)
static char * handle_uri ( struct sockaddr_in * sin , char * uri , int * status , char * * title , int * contentlength , struct ast_variable * * cookies )
static char * handle_uri ( struct sockaddr_in * sin , char * uri , int * status , char * * title , int * contentlength , struct ast_variable * * cookies )
{
{
char * c ;
char * c ;
char * params ;
char * params = uri ;
struct ast_http_uri * urih = NULL ;
struct ast_http_uri * urih = NULL ;
int prefix_ len ;
int l;
struct ast_variable * vars = NULL , * v , * prev = NULL ;
struct ast_variable * vars = NULL , * v , * prev = NULL ;
strsep ( & params , " ? " ) ;
/* Extract arguments from the request and store them in variables. */
/* Extract arguments from the request and store them in variables. */
params = strchr ( uri , ' ? ' ) ;
if ( params ) {
if ( params ) {
char * var , * val ;
char * var , * val ;
* params + + = ' \0 ' ;
while ( ( val = strsep ( & params , " & " ) ) ) {
while ( ( var = strsep ( & params , " & " ) ) ) {
var = strsep ( & val , " = " ) ;
val = strchr ( var , ' = ' ) ;
if ( val )
if ( val ) {
* val + + = ' \0 ' ;
ast_uri_decode ( val ) ;
ast_uri_decode ( val ) ;
} else
else
val = " " ;
val = " " ;
ast_uri_decode ( var ) ;
ast_uri_decode ( var ) ;
if ( ( v = ast_variable_new ( var , val ) ) ) {
if ( ( v = ast_variable_new ( var , val ) ) ) {
@ -316,7 +314,7 @@ static char *handle_uri(struct sockaddr_in *sin, char *uri, int *status, char **
/*
/*
* Append the cookies to the variables ( the only reason to have them
* Append the cookies to the variables ( the only reason to have them
* at the end is to avoid another pass of the cookies list to find
* at the end is to avoid another pass of the cookies list to find
* the tail .
* the tail ) .
*/
*/
if ( prev )
if ( prev )
prev - > next = * cookies ;
prev - > next = * cookies ;
@ -326,38 +324,40 @@ static char *handle_uri(struct sockaddr_in *sin, char *uri, int *status, char **
ast_uri_decode ( uri ) ;
ast_uri_decode ( uri ) ;
/* We want requests to start with the prefix and '/' */
/* We want requests to start with the prefix and '/' */
prefix_ len = strlen ( prefix ) ;
l = strlen ( prefix ) ;
if ( prefix_ len & & ! strncasecmp ( uri , prefix , prefix_ len ) & & uri [ prefix_ len ] = = ' / ' ) {
if ( l & & ! strncasecmp ( uri , prefix , l) & & uri [ l] = = ' / ' ) {
uri + = prefix_ len + 1 ;
uri + = l + 1 ;
/* scan registered uris to see if we match one. */
/* scan registered uris to see if we match one. */
for ( urih = uris ; urih ; urih = urih - > next ) {
for ( urih = uris ; urih ; urih = urih - > next ) {
int len = strlen ( urih - > uri ) ;
l = strlen ( urih - > uri ) ;
if ( ! strncasecmp ( urih - > uri , uri , len ) ) {
c = uri + l ; /* candidate */
if ( ! uri [ len ] | | uri [ len ] = = ' / ' ) {
if ( strncasecmp ( urih - > uri , uri , l ) /* no match */
char * turi = uri + len ; /* possible candidate */
| | ( * c & & * c ! = ' / ' ) ) /* substring */
if ( * turi = = ' / ' )
continue ;
turi + + ;
if ( * c = = ' / ' )
if ( ! * turi | | urih - > has_subtree ) {
c + + ;
uri = turi ;
if ( ! * c | | urih - > has_subtree ) {
uri = c ;
break ;
break ;
}
}
}
}
}
}
}
}
if ( urih ) {
if ( urih ) {
c = urih - > callback ( sin , uri , vars , status , title , contentlength ) ;
c = urih - > callback ( sin , uri , vars , status , title , contentlength ) ;
ast_variables_destroy ( vars ) ;
} else if ( ast_strlen_zero ( uri ) & & ast_strlen_zero ( prefix ) ) {
} else if ( ast_strlen_zero ( uri ) & & ast_strlen_zero ( prefix ) ) {
/* Special case: If no prefix, and no URI, send to /static/index.html */
/* Special case: no prefix, no URI, send to /static/index.html */
c = ast_http_error ( 302 , " Moved Temporarily " , " Location: /static/index.html \r \n " , " This is not the page you are looking for... " ) ;
c = ast_http_error ( 302 , " Moved Temporarily " ,
" Location: /static/index.html \r \n " ,
" This is not the page you are looking for... " ) ;
* status = 302 ;
* status = 302 ;
* title = strdup ( " Moved Temporarily " ) ;
* title = strdup ( " Moved Temporarily " ) ;
} else {
} else {
c = ast_http_error ( 404 , " Not Found " , NULL , " The requested URL was not found on this server. " ) ;
c = ast_http_error ( 404 , " Not Found " , NULL ,
" The requested URL was not found on this server. " ) ;
* status = 404 ;
* status = 404 ;
* title = strdup ( " Not Found " ) ;
* title = strdup ( " Not Found " ) ;
}
}
ast_variables_destroy ( vars ) ;
return c ;
return c ;
}
}
@ -365,15 +365,14 @@ static void *ast_httpd_helper_thread(void *data)
{
{
char buf [ 4096 ] ;
char buf [ 4096 ] ;
char cookie [ 4096 ] ;
char cookie [ 4096 ] ;
char timebuf [ 256 ] ;
struct ast_http_server_instance * ser = data ;
struct ast_http_server_instance * ser = data ;
struct ast_variable * var , * prev = NULL , * vars = NULL ;
struct ast_variable * var , * prev = NULL , * vars = NULL ;
char * uri , * c , * title = NULL ;
char * uri , * c , * title = NULL ;
char * vname , * vval ;
int status = 200 , contentlength = 0 ;
int status = 200 , contentlength = 0 ;
time_t t ;
if ( fgets ( buf , sizeof ( buf ) , ser - > f ) ) {
if ( ! fgets ( buf , sizeof ( buf ) , ser - > f ) )
goto done ;
uri = ast_skip_nonblanks ( buf ) ; /* Skip method */
uri = ast_skip_nonblanks ( buf ) ; /* Skip method */
if ( * uri )
if ( * uri )
* uri + + = ' \0 ' ;
* uri + + = ' \0 ' ;
@ -388,6 +387,9 @@ static void *ast_httpd_helper_thread(void *data)
/* process "Cookie: " lines */
/* process "Cookie: " lines */
while ( fgets ( cookie , sizeof ( cookie ) , ser - > f ) ) {
while ( fgets ( cookie , sizeof ( cookie ) , ser - > f ) ) {
char * vname , * vval ;
int l ;
/* Trim trailing characters */
/* Trim trailing characters */
ast_trim_blanks ( cookie ) ;
ast_trim_blanks ( cookie ) ;
if ( ast_strlen_zero ( cookie ) )
if ( ast_strlen_zero ( cookie ) )
@ -395,8 +397,6 @@ static void *ast_httpd_helper_thread(void *data)
if ( strncasecmp ( cookie , " Cookie: " , 8 ) )
if ( strncasecmp ( cookie , " Cookie: " , 8 ) )
continue ;
continue ;
/* XXX fix indentation */
/* TODO - The cookie parsing code below seems to work
/* TODO - The cookie parsing code below seems to work
in IE6 and FireFox 1.5 . However , it is not entirely
in IE6 and FireFox 1.5 . However , it is not entirely
correct , and therefore may not work in all
correct , and therefore may not work in all
@ -410,28 +410,25 @@ static void *ast_httpd_helper_thread(void *data)
/* If we got a FireFox cookie string, the name's right
/* If we got a FireFox cookie string, the name's right
after " Cookie: " */
after " Cookie: " */
vname = cookie + 8 ;
vname = ast_skip_blanks ( cookie + 8 ) ;
/* If we got an IE cookie string, we need to skip to
/* If we got an IE cookie string, we need to skip to
past the version to get to the name */
past the version to get to the name */
if ( * vname = = ' $ ' ) {
if ( * vname = = ' $ ' ) {
vname = strchr ( vname , ' ; ' ) ;
strsep ( & vname , " ; " ) ;
if ( vname ) {
if ( ! vname ) /* no name ? */
vname + + ;
continue ;
if ( * vname = = ' ' )
vname = ast_skip_blanks ( vname ) ;
vname + + ;
}
}
}
if ( vname ) {
vval = strchr ( vname , ' = ' ) ;
vval = strchr ( vname , ' = ' ) ;
if ( vval ) {
if ( ! vval )
continue ;
/* Ditch the = and the quotes */
/* Ditch the = and the quotes */
* vval + + = ' \0 ' ;
* vval + + = ' \0 ' ;
if ( * vval )
if ( * vval )
vval + + ;
vval + + ;
if ( strlen ( vval ) )
if ( ( l = strlen ( vval ) ) )
vval [ strlen ( vva l) - 1 ] = ' \0 ' ;
vval [ l - 1 ] = ' \0 ' ; /* trim trailing quote */
var = ast_variable_new ( vname , vval ) ;
var = ast_variable_new ( vname , vval ) ;
if ( var ) {
if ( var ) {
if ( prev )
if ( prev )
@ -441,16 +438,14 @@ static void *ast_httpd_helper_thread(void *data)
prev = var ;
prev = var ;
}
}
}
}
}
}
if ( * uri ) {
if ( ! * uri )
if ( ! strcasecmp ( buf , " get " ) )
c = handle_uri ( & ser - > requestor , uri , & status , & title , & contentlength , & vars ) ;
else
c = ast_http_error ( 501 , " Not Implemented " , NULL , " Attempt to use unimplemented / unsupported method " ) ; \
} else
c = ast_http_error ( 400 , " Bad Request " , NULL , " Invalid Request " ) ;
c = ast_http_error ( 400 , " Bad Request " , NULL , " Invalid Request " ) ;
else if ( strcasecmp ( buf , " get " ) )
c = ast_http_error ( 501 , " Not Implemented " , NULL ,
" Attempt to use unimplemented / unsupported method " ) ;
else /* try to serve it */
c = handle_uri ( & ser - > requestor , uri , & status , & title , & contentlength , & vars ) ;
/* If they aren't mopped up already, clean up the cookies */
/* If they aren't mopped up already, clean up the cookies */
if ( vars )
if ( vars )
@ -459,17 +454,20 @@ static void *ast_httpd_helper_thread(void *data)
if ( ! c )
if ( ! c )
c = ast_http_error ( 500 , " Internal Error " , NULL , " Internal Server Error " ) ;
c = ast_http_error ( 500 , " Internal Error " , NULL , " Internal Server Error " ) ;
if ( c ) {
if ( c ) {
time ( & t ) ;
time_t t = time ( NULL ) ;
char timebuf [ 256 ] ;
strftime ( timebuf , sizeof ( timebuf ) , " %a, %d %b %Y %H:%M:%S GMT " , gmtime ( & t ) ) ;
strftime ( timebuf , sizeof ( timebuf ) , " %a, %d %b %Y %H:%M:%S GMT " , gmtime ( & t ) ) ;
ast_cli ( ser - > fd , " HTTP/1.1 %d %s \r \n " , status , title ? title : " OK " ) ;
ast_cli ( ser - > fd , " HTTP/1.1 %d %s \r \n " , status , title ? title : " OK " ) ;
ast_cli ( ser - > fd , " Server: Asterisk \r \n " ) ;
ast_cli ( ser - > fd , " Server: Asterisk \r \n " ) ;
ast_cli ( ser - > fd , " Date: %s \r \n " , timebuf ) ;
ast_cli ( ser - > fd , " Date: %s \r \n " , timebuf ) ;
ast_cli ( ser - > fd , " Connection: close \r \n " ) ;
ast_cli ( ser - > fd , " Connection: close \r \n " ) ;
if ( contentlength ) {
if ( contentlength ) {
char * tmp ;
char * tmp = strstr ( c , " \r \n \r \n " ) ;
tmp = strstr ( c , " \r \n \r \n " ) ;
if ( tmp ) {
if ( tmp ) {
ast_cli ( ser - > fd , " Content-length: %d \r \n " , contentlength ) ;
ast_cli ( ser - > fd , " Content-length: %d \r \n " , contentlength ) ;
/* first write the header, then the body */
write ( ser - > fd , c , ( tmp + 4 - c ) ) ;
write ( ser - > fd , c , ( tmp + 4 - c ) ) ;
write ( ser - > fd , tmp + 4 , contentlength ) ;
write ( ser - > fd , tmp + 4 , contentlength ) ;
}
}
@ -479,7 +477,8 @@ static void *ast_httpd_helper_thread(void *data)
}
}
if ( title )
if ( title )
free ( title ) ;
free ( title ) ;
}
done :
fclose ( ser - > f ) ;
fclose ( ser - > f ) ;
free ( ser ) ;
free ( ser ) ;
return NULL ;
return NULL ;