| | @@ -340,47 +340,72 @@ |
| 340 | 340 | FILE *in = 0, *out = 0, *aux = 0; |
| 341 | 341 | int amt, got, i; |
| 342 | 342 | int wanted = 0; |
| 343 | 343 | char *z; |
| 344 | 344 | char *zIp; |
| 345 | + void *sslConn = 0; |
| 345 | 346 | char zCmdFName[MAX_PATH]; |
| 346 | 347 | char zRequestFName[MAX_PATH]; |
| 347 | 348 | char zReplyFName[MAX_PATH]; |
| 348 | 349 | char zCmd[2000]; /* Command-line to process the request */ |
| 349 | | - char zHdr[4000]; /* The HTTP request header */ |
| 350 | + char zBuf[65536]; /* The HTTP request header */ |
| 351 | + const int szHdr = 4000; /* Reduced header size */ |
| 350 | 352 | |
| 351 | 353 | sqlite3_snprintf(MAX_PATH, zCmdFName, |
| 352 | 354 | "%s_%06d_cmd.txt", zTempPrefix, p->id); |
| 353 | 355 | sqlite3_snprintf(MAX_PATH, zRequestFName, |
| 354 | 356 | "%s_%06d_in.txt", zTempPrefix, p->id); |
| 355 | 357 | sqlite3_snprintf(MAX_PATH, zReplyFName, |
| 356 | 358 | "%s_%06d_out.txt", zTempPrefix, p->id); |
| 357 | 359 | amt = 0; |
| 358 | | - while( amt<sizeof(zHdr) ){ |
| 359 | | - got = recv(p->s, &zHdr[amt], sizeof(zHdr)-1-amt, 0); |
| 360 | | - if( got==SOCKET_ERROR ) goto end_request; |
| 360 | + if( g.httpUseSSL ){ |
| 361 | +#ifdef FOSSIL_ENABLE_SSL |
| 362 | + sslConn = ssl_new_server(p->s); |
| 363 | +#endif |
| 364 | + } |
| 365 | + while( amt<szHdr ){ |
| 366 | + if( sslConn ){ |
| 367 | +#ifdef FOSSIL_ENABLE_SSL |
| 368 | + got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt); |
| 369 | +#endif |
| 370 | + }else{ |
| 371 | + got = recv(p->s, &zBuf[amt], szHdr-amt, 0); |
| 372 | + if( got==SOCKET_ERROR ) goto end_request; |
| 373 | + } |
| 361 | 374 | if( got==0 ){ |
| 362 | 375 | wanted = 0; |
| 363 | 376 | break; |
| 364 | 377 | } |
| 365 | 378 | amt += got; |
| 366 | | - zHdr[amt] = 0; |
| 367 | | - z = strstr(zHdr, "\r\n\r\n"); |
| 379 | + zBuf[amt] = 0; |
| 380 | + z = strstr(zBuf, "\r\n\r\n"); |
| 368 | 381 | if( z ){ |
| 369 | | - wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt; |
| 382 | + wanted = find_content_length(zBuf) + (&z[4]-zBuf) - amt; |
| 370 | 383 | break; |
| 384 | + }else{ |
| 385 | + z = strstr(zBuf, "\n\n"); |
| 386 | + if( z ){ |
| 387 | + wanted = find_content_length(zBuf) + (&z[2]-zBuf) - amt; |
| 388 | + break; |
| 389 | + } |
| 371 | 390 | } |
| 372 | 391 | } |
| 373 | | - if( amt>=sizeof(zHdr) ) goto end_request; |
| 392 | + if( amt>=szHdr ) goto end_request; |
| 374 | 393 | out = fossil_fopen(zRequestFName, "wb"); |
| 375 | 394 | if( out==0 ) goto end_request; |
| 376 | | - fwrite(zHdr, 1, amt, out); |
| 395 | + fwrite(zBuf, 1, amt, out); |
| 377 | 396 | while( wanted>0 ){ |
| 378 | | - got = recv(p->s, zHdr, sizeof(zHdr), 0); |
| 379 | | - if( got==SOCKET_ERROR ) goto end_request; |
| 380 | | - if( got ){ |
| 381 | | - fwrite(zHdr, 1, got, out); |
| 397 | + if( sslConn ){ |
| 398 | +#ifdef FOSSIL_ENABLE_SSL |
| 399 | + got = ssl_read_server(sslConn, zBuf, sizeof(zBuf)); |
| 400 | +#endif |
| 401 | + }else{ |
| 402 | + got = recv(p->s, zBuf, sizeof(zBuf), 0); |
| 403 | + if( got==SOCKET_ERROR ) goto end_request; |
| 404 | + } |
| 405 | + if( got>0 ){ |
| 406 | + fwrite(zBuf, 1, got, out); |
| 382 | 407 | }else{ |
| 383 | 408 | break; |
| 384 | 409 | } |
| 385 | 410 | wanted -= got; |
| 386 | 411 | } |
| | @@ -405,28 +430,40 @@ |
| 405 | 430 | aux = fossil_fopen(zCmdFName, "wb"); |
| 406 | 431 | if( aux==0 ) goto end_request; |
| 407 | 432 | fwrite(zCmd, 1, strlen(zCmd), aux); |
| 408 | 433 | |
| 409 | 434 | sqlite3_snprintf(sizeof(zCmd), zCmd, |
| 410 | | - "\"%s\" http -args \"%s\" --nossl%s", |
| 411 | | - g.nameOfExe, zCmdFName, p->zOptions |
| 435 | + "\"%s\" http -args \"%s\"%s%s", |
| 436 | + g.nameOfExe, zCmdFName, |
| 437 | + g.httpUseSSL ? "" : " --nossl", p->zOptions |
| 412 | 438 | ); |
| 413 | 439 | in = fossil_fopen(zReplyFName, "w+b"); |
| 414 | 440 | fflush(out); |
| 415 | 441 | fflush(aux); |
| 416 | 442 | fossil_system(zCmd); |
| 417 | 443 | if( in ){ |
| 418 | | - while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){ |
| 419 | | - send(p->s, zHdr, got, 0); |
| 444 | + while( (got = fread(zBuf, 1, sizeof(zBuf), in))>0 ){ |
| 445 | + if( sslConn ){ |
| 446 | +#ifdef FOSSIL_ENABLE_SSL |
| 447 | + ssl_write_server(sslConn, zBuf, got); |
| 448 | +#endif |
| 449 | + }else{ |
| 450 | + send(p->s, zBuf, got, 0); |
| 451 | + } |
| 420 | 452 | } |
| 421 | 453 | } |
| 422 | 454 | |
| 423 | 455 | end_request: |
| 424 | 456 | if( out ) fclose(out); |
| 425 | 457 | if( aux ) fclose(aux); |
| 426 | 458 | if( in ) fclose(in); |
| 427 | 459 | /* Initiate shutdown prior to closing the socket */ |
| 460 | + if( sslConn!=0 ){ |
| 461 | +#ifdef FOSSIL_ENABLE_SSL |
| 462 | + ssl_close_server(sslConn); |
| 463 | +#endif |
| 464 | + } |
| 428 | 465 | if( shutdown(p->s,1)==0 ) shutdown(p->s,0); |
| 429 | 466 | closesocket(p->s); |
| 430 | 467 | /* Make multiple attempts to delete the temporary files. Sometimes AV |
| 431 | 468 | ** software keeps the files open for a few seconds, preventing the file |
| 432 | 469 | ** from being deleted on the first try. */ |
| | @@ -619,11 +656,12 @@ |
| 619 | 656 | } |
| 620 | 657 | zTempPrefix = mprintf("%sfossil_server_P%d", |
| 621 | 658 | fossil_unicode_to_utf8(zTmpPath), iPort); |
| 622 | 659 | fossil_print("Temporary files: %s*\n", zTempPrefix); |
| 623 | 660 | fossil_print("Listening for %s requests on TCP port %d\n", |
| 624 | | - (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort); |
| 661 | + (flags&HTTP_SERVER_SCGI)!=0 ? "SCGI" : |
| 662 | + g.httpUseSSL ? "TLS-encrypted HTTPS" : "HTTP", iPort); |
| 625 | 663 | if( zBrowser ){ |
| 626 | 664 | zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort); |
| 627 | 665 | fossil_print("Launch webbrowser: %s\n", zBrowser); |
| 628 | 666 | fossil_system(zBrowser); |
| 629 | 667 | } |
| 630 | 668 | |