diff -r 191b3c25974a -r 23a242d7b7fa db.c --- a/db.c Sun Oct 23 22:59:59 2011 -0700 +++ b/db.c Mon Oct 31 17:17:07 2011 -0700 @@ -71,6 +71,9 @@ } } + /* initialize prepared statements */ + if ( prepare_statements() != 0 ) return SQLITE_ERROR; + return( SQLITE_OK ); } @@ -144,3 +147,143 @@ return( version ); } + +/* + * Initialize the DB statements, returning 0 on success. + * + */ +unsigned short int +prepare_statements( void ) +{ + unsigned short int rv = 0; + + rv = rv + sqlite3_prepare_v2( v.db, DBSQL_GET_REWRITE_RULE, -1, &v.db_stmt.get_rewrite_rule, NULL ); + if ( rv != 0 ) + debug( 2, LOC, "Error preparing DB statement \"%s\": %s\n", + DBSQL_GET_REWRITE_RULE, sqlite3_errmsg(v.db) ); + + rv = rv + sqlite3_prepare_v2( v.db, DBSQL_MATCH_REQUEST, -1, &v.db_stmt.match_request, NULL ); + if ( rv != 0 ) + debug( 2, LOC, "Error preparing DB statement \"%s\": %s\n", + DBSQL_MATCH_REQUEST, sqlite3_errmsg(v.db) ); + + return( rv ); +} + + +/* + * Initialize and return a pointer to a new rewrite object. + * + */ +rewrite * +init_rewrite( void ) +{ + rewrite *p_rewrite = NULL; + if ( (p_rewrite = malloc( sizeof(rewrite) )) == NULL ) { + debug( 5, LOC, "Unable to allocate memory for rewrite struct: %s\n", strerror(errno) ); + return( NULL ); + } + + p_rewrite->scheme = NULL; + p_rewrite->host = NULL; + p_rewrite->path = NULL; + p_rewrite->port = 0; + p_rewrite->redir = 0; + + return( p_rewrite ); +} + + +#define COPY_REWRITE_ROW( INDEX ) copy_string_token( \ + (char *)sqlite3_column_text( v.db_stmt.get_rewrite_rule, INDEX ),\ + sqlite3_column_bytes( v.db_stmt.get_rewrite_rule, INDEX )) +/* + * Given a request struct pointer, try and find the best matching + * rewrite rule, returning a pointer to a rewrite struct. + * + */ +rewrite * +prepare_rewrite( request *p_request ) +{ + if ( p_request == NULL ) return( NULL ); + + unsigned short int rewrite_id = 0; + rewrite *p_rewrite = init_rewrite(); + + sqlite3_bind_text( v.db_stmt.match_request, 3, p_request->tld, -1, SQLITE_STATIC ); + sqlite3_bind_text( v.db_stmt.match_request, 1, p_request->scheme, -1, SQLITE_STATIC ); + sqlite3_bind_text( v.db_stmt.match_request, 2, p_request->host, -1, SQLITE_STATIC ); + sqlite3_bind_text( v.db_stmt.match_request, 3, p_request->tld, -1, SQLITE_STATIC ); + sqlite3_bind_text( v.db_stmt.match_request, 4, p_request->path, -1, SQLITE_STATIC ); + sqlite3_bind_int( v.db_stmt.match_request, 5, p_request->port ); + /* + sqlite3_bind_text( v.db_stmt.match_request, 6, NULL, -1, SQLITE_STATIC ); + sqlite3_bind_text( v.db_stmt.match_request, 6, p_request->client_ip, -1, SQLITE_STATIC ); + */ + sqlite3_bind_text( v.db_stmt.match_request, 7, p_request->user, -1, SQLITE_STATIC ); + sqlite3_bind_text( v.db_stmt.match_request, 8, p_request->method, -1, SQLITE_STATIC ); + + switch ( sqlite3_step( v.db_stmt.match_request )) { + case SQLITE_ROW: + rewrite_id = sqlite3_column_int( v.db_stmt.match_request, 0 ); + break; + + case SQLITE_DONE: + break; + + default: + return( NULL ); + } + + /* FIXME: CHECK for rewrite_rule being NULL on successful match, emit warning, continue */ + + /* return early if we didn't get a matching request */ + if ( rewrite_id == 0 ) return( NULL ); + + /* pull the rewrite data, populate the struct. only one + * row should ever be returned for this. */ + sqlite3_bind_int( v.db_stmt.get_rewrite_rule, 1, rewrite_id ); + switch ( sqlite3_step( v.db_stmt.get_rewrite_rule )) { + case SQLITE_ROW: + p_rewrite->scheme = COPY_REWRITE_ROW( 1 ); + p_rewrite->host = COPY_REWRITE_ROW( 2 ); + p_rewrite->path = COPY_REWRITE_ROW( 3 ); + p_rewrite->port = sqlite3_column_int( v.db_stmt.get_rewrite_rule, 4 ); + p_rewrite->redir = sqlite3_column_int( v.db_stmt.get_rewrite_rule, 5 ); + break; + + case SQLITE_DONE: + break; + + default: + return( NULL ); + } + + return( p_rewrite ); +} + + +/* + * Release memory used by the rewrite struct and + * reset prepared statements. + * + */ +void +finish_rewrite( rewrite *p_rewrite ) +{ + sqlite3_reset( v.db_stmt.get_rewrite_rule ); + sqlite3_reset( v.db_stmt.match_request ); + sqlite3_clear_bindings( v.db_stmt.get_rewrite_rule ); + sqlite3_clear_bindings( v.db_stmt.match_request ); + + if ( p_rewrite == NULL ) return; + + free( p_rewrite->scheme ); + free( p_rewrite->host ); + free( p_rewrite->path ); + + free( p_rewrite ), p_rewrite = NULL; + + return; +} +