Changeset 6855
- Timestamp:
- Oct 6, 2008, 1:36:06 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/rpc-server.c
r6847 r6855 12 12 13 13 #include <assert.h> 14 #include <errno.h> 14 15 #include <string.h> /* memcpy */ 15 16 #include <limits.h> /* INT_MAX */ … … 68 69 struct evbuffer * body = evbuffer_new( ); 69 70 70 evbuffer_add_printf( body, "<h1>% s</h1>", code_text );71 evbuffer_add_printf( body, "<h1>%d: %s</h1>", code, code_text ); 71 72 if( text ) 72 73 evbuffer_add_printf( body, "<h2>%s</h2>", text ); … … 145 146 tr_benc top, *args; 146 147 147 body += 4; 148 body += 4; /* walk past the \r\n\r\n */ 148 149 body_len = part_len - ( body - text ); 149 150 if( body_len >= 2 … … 193 194 } types[] = { 194 195 /* 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" } 201 202 }; 202 203 const char * dot = strrchr( path, '.' ); … … 211 212 #ifdef HAVE_LIBZ 212 213 static int 213 compress_evbuf( struct evbuffer * evbuf ) 214 compress_response( struct evbuffer * out, 215 const void * content, 216 size_t content_len ) 214 217 { 215 218 int err = 0; 216 struct evbuffer * out; 217 static z_stream stream; 219 z_stream stream; 218 220 219 221 stream.zalloc = Z_NULL; 220 222 stream.zfree = Z_NULL; 221 223 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; 227 228 228 229 while( !err ) { … … 243 244 244 245 /* 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 ) ) 246 247 err = -1; 247 248 248 if( !err ) { 249 if( err ) 250 evbuffer_add( out, content, content_len ); 251 else 249 252 tr_ninf( MY_NAME, "deflated response from %zu bytes to %zu", 250 EVBUFFER_LENGTH( evbuf ),253 content_len, 251 254 EVBUFFER_LENGTH( out ) ); 252 evbuffer_drain( evbuf, EVBUFFER_LENGTH( evbuf ) );253 evbuffer_add_buffer( evbuf, out );254 }255 255 256 256 deflateEnd( &stream ); 257 evbuffer_free( out );258 257 return err; 259 258 } … … 261 260 262 261 static void 263 maybe_deflate_response( struct evhttp_request * req, 264 struct evbuffer * response ) 262 add_response( struct evhttp_request * req, 263 struct evbuffer * response, 264 const void * content, 265 size_t content_len ) 265 266 { 266 267 #ifdef HAVE_LIBZ … … 269 270 const int do_deflate = accept_encoding && strstr( accept_encoding, 270 271 "deflate" ); 271 if( do_deflate && !compress_ evbuf( response) )272 if( do_deflate && !compress_response( response, content, content_len ) ) 272 273 evhttp_add_header( req->output_headers, "Content-Encoding", "deflate" ); 274 #else 275 evbuffer_add( response, content, content_len ); 273 276 #endif 274 277 } … … 276 279 static void 277 280 serve_file( struct evhttp_request * req, 278 const char * path)281 const char * filename ) 279 282 { 280 283 if( req->type != EVHTTP_REQ_GET ) … … 285 288 else 286 289 { 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 ) 289 299 { 290 300 send_simple_response( req, HTTP_NOTFOUND, NULL ); … … 292 302 else 293 303 { 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 298 306 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 ); 305 314 } 306 315 } … … 337 346 { 338 347 int len = 0; 339 char * response= NULL;348 char * out = NULL; 340 349 struct evbuffer * buf; 341 350 … … 344 353 const char * q; 345 354 if( ( q = strchr( req->uri, '?' ) ) ) 346 response= tr_rpc_request_exec_uri( server->session,347 348 349 355 out = tr_rpc_request_exec_uri( server->session, 356 q + 1, 357 strlen( q + 1 ), 358 &len ); 350 359 } 351 360 else if( req->type == EVHTTP_REQ_POST ) 352 361 { 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 ); 359 366 } 360 367 361 368 buf = evbuffer_new( ); 362 evbuffer_add( buf, response, len ); 363 maybe_deflate_response( req, buf ); 369 add_response( req, buf, out, len ); 364 370 evhttp_add_header( req->output_headers, "Content-Type", 365 371 "application/json; charset=UTF-8" ); … … 368 374 /* cleanup */ 369 375 evbuffer_free( buf ); 370 tr_free( response);376 tr_free( out ); 371 377 } 372 378 … … 428 434 send_simple_response( req, 401, "Unauthorized IP Address" ); 429 435 } 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 ) ) ) 436 439 { 437 440 evhttp_add_header( req->output_headers, … … 662 665 s->session = session; 663 666 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 ); 665 670 s->username = tr_strdup( username ); 666 671 s->password = tr_strdup( password ); … … 672 677 return s; 673 678 } 674
Note: See TracChangeset
for help on using the changeset viewer.