Changeset 6855


Ignore:
Timestamp:
Oct 6, 2008, 1:36:06 PM (13 years ago)
Author:
charles
Message:

slightly more efficient serving of static files & rpc responses

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/rpc-server.c

    r6847 r6855  
    1212
    1313#include <assert.h>
     14#include <errno.h>
    1415#include <string.h> /* memcpy */
    1516#include <limits.h> /* INT_MAX */
     
    6869    struct evbuffer * body = evbuffer_new( );
    6970
    70     evbuffer_add_printf( body, "<h1>%s</h1>", code_text );
     71    evbuffer_add_printf( body, "<h1>%d: %s</h1>", code, code_text );
    7172    if( text )
    7273        evbuffer_add_printf( body, "<h2>%s</h2>", text );
     
    145146                        tr_benc top, *args;
    146147
    147                         body += 4;
     148                        body += 4; /* walk past the \r\n\r\n */
    148149                        body_len = part_len - ( body - text );
    149150                        if( body_len >= 2
     
    193194    } types[] = {
    194195        /* these are just the ones we need for serving clutch... */
    195         { "css",  "text/css"                       },
    196         { "gif",  "image/gif"                      },
    197         { "html", "text/html"                      },
    198         { "ico",  "image/vnd.microsoft.icon"       },
    199         { "js",   "application/javascript"         },
    200         { "png",  "image/png"                      }
     196        { "css",  "text/css"                  },
     197        { "gif",  "image/gif"                 },
     198        { "html", "text/html"                 },
     199        { "ico",  "image/vnd.microsoft.icon"  },
     200        { "js",   "application/javascript"    },
     201        { "png",  "image/png"                 }
    201202    };
    202203    const char * dot = strrchr( path, '.' );
     
    211212#ifdef HAVE_LIBZ
    212213static int
    213 compress_evbuf( struct evbuffer * evbuf )
     214compress_response( struct evbuffer  * out,
     215                   const void       * content,
     216                   size_t             content_len )
    214217{
    215218    int err = 0;
    216     struct evbuffer  * out;
    217     static z_stream    stream;
     219    z_stream stream;
    218220
    219221    stream.zalloc = Z_NULL;
    220222    stream.zfree = Z_NULL;
    221223    stream.opaque = Z_NULL;
    222     deflateInit( &stream, Z_DEFAULT_COMPRESSION );
    223 
    224     stream.next_in = EVBUFFER_DATA( evbuf );
    225     stream.avail_in = EVBUFFER_LENGTH( evbuf );
    226     out = evbuffer_new( );
     224    deflateInit( &stream, Z_BEST_COMPRESSION );
     225
     226    stream.next_in = (Bytef*) content;
     227    stream.avail_in = content_len;
    227228
    228229    while( !err ) {
     
    243244
    244245    /* if the deflated form is larger, then just use the original */
    245     if( !err && ( EVBUFFER_LENGTH( out ) >= EVBUFFER_LENGTH( evbuf ) ) )
     246    if( !err && ( EVBUFFER_LENGTH( out ) >= content_len ) )
    246247        err = -1;
    247248
    248     if( !err ) {
     249    if( err )
     250        evbuffer_add( out, content, content_len );
     251    else
    249252        tr_ninf( MY_NAME, "deflated response from %zu bytes to %zu",
    250                           EVBUFFER_LENGTH( evbuf ),
     253                          content_len,
    251254                          EVBUFFER_LENGTH( out ) );
    252         evbuffer_drain( evbuf, EVBUFFER_LENGTH( evbuf ) );
    253         evbuffer_add_buffer( evbuf, out );
    254     }
    255255
    256256    deflateEnd( &stream );
    257     evbuffer_free( out );
    258257    return err;
    259258}
     
    261260
    262261static void
    263 maybe_deflate_response( struct evhttp_request * req,
    264                         struct evbuffer *       response )
     262add_response( struct evhttp_request * req,
     263              struct evbuffer *       response,
     264              const void *            content,
     265              size_t                  content_len )
    265266{
    266267#ifdef HAVE_LIBZ
     
    269270    const int    do_deflate = accept_encoding && strstr( accept_encoding,
    270271                                                         "deflate" );
    271     if( do_deflate && !compress_evbuf( response ) )
     272    if( do_deflate && !compress_response( response, content, content_len ) )
    272273        evhttp_add_header( req->output_headers, "Content-Encoding", "deflate" );
     274#else
     275    evbuffer_add( response, content, content_len );
    273276#endif
    274277}
     
    276279static void
    277280serve_file( struct evhttp_request * req,
    278             const char *            path )
     281            const char *            filename )
    279282{
    280283    if( req->type != EVHTTP_REQ_GET )
     
    285288    else
    286289    {
    287         const int fd = open( path, O_RDONLY, 0 );
    288         if( fd == -1 )
     290        size_t content_len;
     291        uint8_t * content;
     292        const int error = errno;
     293
     294        errno = 0;
     295        content_len = 0;
     296        content = tr_loadFile( filename, &content_len );
     297
     298        if( errno )
    289299        {
    290300            send_simple_response( req, HTTP_NOTFOUND, NULL );
     
    292302        else
    293303        {
    294             struct evbuffer * buf = evbuffer_new( );
    295             for( ;; )
    296                 if( evbuffer_read( buf, fd, INT_MAX ) < 1 )
    297                     break;
     304            struct evbuffer * out = evbuffer_new( );
     305
    298306            evhttp_add_header( req->output_headers, "Content-Type",
    299                               mimetype_guess(
    300                                   path ) );
    301             maybe_deflate_response( req, buf );
    302             evhttp_send_reply( req, HTTP_OK, "OK", buf );
    303             evbuffer_free( buf );
    304             close( fd );
     307                               mimetype_guess( filename ) );
     308            add_response( req, out, content, content_len );
     309            evhttp_send_reply( req, HTTP_OK, "OK", out );
     310
     311            errno = error;
     312            evbuffer_free( out );
     313            tr_free( content );
    305314        }
    306315    }
     
    337346{
    338347    int               len = 0;
    339     char *            response = NULL;
     348    char *            out = NULL;
    340349    struct evbuffer * buf;
    341350
     
    344353        const char * q;
    345354        if( ( q = strchr( req->uri, '?' ) ) )
    346             response = tr_rpc_request_exec_uri( server->session,
    347                                                 q + 1,
    348                                                 strlen( q + 1 ),
    349                                                 &len );
     355            out = tr_rpc_request_exec_uri( server->session,
     356                                           q + 1,
     357                                           strlen( q + 1 ),
     358                                           &len );
    350359    }
    351360    else if( req->type == EVHTTP_REQ_POST )
    352361    {
    353         response = tr_rpc_request_exec_json( server->session,
    354                                              EVBUFFER_DATA( req->
    355                                                             input_buffer ),
    356                                              EVBUFFER_LENGTH( req->
    357                                                               input_buffer ),
    358                                              &len );
     362        out = tr_rpc_request_exec_json( server->session,
     363                                        EVBUFFER_DATA( req->input_buffer ),
     364                                        EVBUFFER_LENGTH( req->input_buffer ),
     365                                        &len );
    359366    }
    360367
    361368    buf = evbuffer_new( );
    362     evbuffer_add( buf, response, len );
    363     maybe_deflate_response( req, buf );
     369    add_response( req, buf, out, len );
    364370    evhttp_add_header( req->output_headers, "Content-Type",
    365371                       "application/json; charset=UTF-8" );
     
    368374    /* cleanup */
    369375    evbuffer_free( buf );
    370     tr_free( response );
     376    tr_free( out );
    371377}
    372378
     
    428434            send_simple_response( req, 401, "Unauthorized IP Address" );
    429435        }
    430         else if( server->isPasswordEnabled && ( !pass
    431                                               || !user
    432                                               || strcmp( server->username,
    433                                                          user )
    434                                               || strcmp( server->password,
    435                                                          pass ) ) )
     436        else if( server->isPasswordEnabled
     437                 && ( !pass || !user || strcmp( server->username, user )
     438                                     || strcmp( server->password, pass ) ) )
    436439        {
    437440            evhttp_add_header( req->output_headers,
     
    662665    s->session = session;
    663666    s->port = port;
    664     s->whitelist = tr_strdup( whitelist && *whitelist ? whitelist : TR_DEFAULT_RPC_WHITELIST );
     667    s->whitelist = tr_strdup( whitelist && *whitelist
     668                              ? whitelist
     669                              : TR_DEFAULT_RPC_WHITELIST );
    665670    s->username = tr_strdup( username );
    666671    s->password = tr_strdup( password );
     
    672677    return s;
    673678}
    674 
Note: See TracChangeset for help on using the changeset viewer.