| @@ -6,9 +6,9 @@ | ||
| 6 | 6 | | | | / _ \ / _` |/ _ \ | |_) | '__/ _ \| |_| | |/ _ \ '__| | |
| 7 | 7 | | | |__| (_) | (_| | __/ | __/| | | (_) | _| | | __/ | | |
| 8 | 8 | | \____\___/ \__,_|\___| |_| |_| \___/|_| |_|_|\___|_| | |
| 9 | 9 | | | |
| 10 | - | (c) Jerome Bruandet ~ https://code-profiler.com/ | | |
| 10 | + | (c) Jerome Bruandet ~ https://nintechnet.com/codeprofiler/ | | |
| 11 | 11 | +=====================================================================+ |
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | 14 | if (! defined('ABSPATH') ) { |
| @@ -72,15 +72,8 @@ | ||
| 72 | 72 | code_profiler_wp_send_json( $response ); |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | 75 | code_profiler_log_debug( |
| 76 | - esc_html__('Cleaning up the temporary folder', 'code-profiler') | |
| 77 | - ); | |
| 78 | - | |
| 79 | - // Clean-up temp files left in the profiles folder | |
| 80 | - code_profiler_cleantmpfiles(); | |
| 81 | - | |
| 82 | - code_profiler_log_debug( | |
| 83 | 76 | esc_html__('Retrieving parameters #1', 'code-profiler') |
| 84 | 77 | ); |
| 85 | 78 | |
| 86 | 79 | // Frontend or backend |
| @@ -191,15 +184,18 @@ | ||
| 191 | 184 | ); |
| 192 | 185 | |
| 193 | 186 | // Create security key |
| 194 | 187 | $profiler_key = bin2hex( random_bytes( 16 ) ); |
| 195 | - $cp_options['hash'] = sha1( $profiler_key ); | |
| 188 | + touch( CODE_PROFILER_UPLOAD_DIR .'/key_'. sha1( $profiler_key ) .'.tmp'); | |
| 196 | 189 | |
| 197 | 190 | code_profiler_log_debug( |
| 198 | 191 | esc_html__('Building HTTP query', 'code-profiler') |
| 199 | 192 | ); |
| 200 | 193 | |
| 201 | - // Build query | |
| 194 | + /** | |
| 195 | + * Build the query. | |
| 196 | + */ | |
| 197 | + $raw_url = $url; | |
| 202 | 198 | $url = add_query_arg( [ |
| 203 | 199 | 'CODE_PROFILER_ON' => $microtime, |
| 204 | 200 | 'profiler_key' => $profiler_key |
| 205 | 201 | ], $url ); |
| @@ -437,19 +433,26 @@ | ||
| 437 | 433 | } else { |
| 438 | 434 | unset( $cp_options['cookies'] ); |
| 439 | 435 | } |
| 440 | 436 | |
| 441 | - // Optional file and folder exclusions | |
| 442 | - $exclusions = []; | |
| 437 | + /** | |
| 438 | + * Optional file and folder exclusions. | |
| 439 | + */ | |
| 440 | + $tmp_exclusions = []; | |
| 443 | 441 | if (! empty( $_POST['exclusions'] ) ) { |
| 444 | 442 | $tmp_array = explode( PHP_EOL, trim( stripslashes( $_POST['exclusions'] ) ) ); |
| 445 | 443 | foreach( $tmp_array as $item ) { |
| 446 | 444 | $item = trim( code_profiler_ASCII_filter( $item ) ); |
| 447 | 445 | if ( $item ) { |
| 448 | - $exclusions[] = $item; | |
| 446 | + $tmp_exclusions[] = $item; | |
| 449 | 447 | } |
| 450 | 448 | } |
| 451 | 449 | } |
| 450 | + /** | |
| 451 | + * Remove duplicates. | |
| 452 | + */ | |
| 453 | + $exclusions = array_unique( $tmp_exclusions ); | |
| 454 | + | |
| 452 | 455 | if ( $exclusions) { |
| 453 | 456 | $cp_options['exclusions'] = json_encode( $exclusions ); |
| 454 | 457 | } else { |
| 455 | 458 | unset( $cp_options['exclusions'] ); |
| @@ -480,25 +483,82 @@ | ||
| 480 | 483 | code_profiler_log_debug( |
| 481 | 484 | esc_html__('Fetching HTTP response', 'code-profiler') |
| 482 | 485 | ); |
| 483 | 486 | |
| 487 | + /** | |
| 488 | + * Always log last HTTP response headers and body, | |
| 489 | + * except sensitive data (cookies & PHP session ID). | |
| 490 | + */ | |
| 491 | + if ( isset( $res['headers'] ) && isset( $res['body'] ) ) { | |
| 492 | + /** | |
| 493 | + * Search for an existing log or create it. | |
| 494 | + */ | |
| 495 | + $last_log = code_profiler_glob( | |
| 496 | + CODE_PROFILER_UPLOAD_DIR, | |
| 497 | + '^last_request\.\d+?\.\d+?\.log$', | |
| 498 | + true | |
| 499 | + ); | |
| 500 | + if ( empty( $last_log[0] ) ) { | |
| 501 | + $last_log[0] = CODE_PROFILER_UPLOAD_DIR .'/last_request.'. microtime( true ) .'.log'; | |
| 502 | + } | |
| 503 | + /** | |
| 504 | + * Parse headers. | |
| 505 | + */ | |
| 506 | + $headers = "HTTP {$res['response']['code']} {$res['response']['message']}\n"; | |
| 507 | + | |
| 508 | + foreach( $res['headers'] as $key => $value ) { | |
| 509 | + /** | |
| 510 | + * Remove cookies. | |
| 511 | + */ | |
| 512 | + if ( $key == 'set-cookie') { | |
| 513 | + $headers .= ucfirst( $key ) .': *** '. __('Removed', 'code-profiler') ." ***\n"; | |
| 514 | + } else { | |
| 515 | + /** | |
| 516 | + * HTTP headers can contain arrays. | |
| 517 | + */ | |
| 518 | + if ( is_array( $value ) ) { | |
| 519 | + foreach( $value as $k => $v ) { | |
| 520 | + $headers .= ucfirst( $key ) .": $v\n"; | |
| 521 | + } | |
| 522 | + } else { | |
| 523 | + $headers .= ucfirst( $key ) .": $value\n"; | |
| 524 | + } | |
| 525 | + } | |
| 526 | + } | |
| 527 | + /** | |
| 528 | + * Save to the log. | |
| 529 | + */ | |
| 530 | + file_put_contents( $last_log[0], | |
| 531 | + "==================================================\n". | |
| 532 | + __('Requested page:', 'code-profiler') ."\n\n". | |
| 533 | + "$raw_url\n". | |
| 534 | + "==================================================\n". | |
| 535 | + __('Response headers:', 'code-profiler') ."\n\n". | |
| 536 | + $headers . | |
| 537 | + "==================================================\n". | |
| 538 | + __('Response body:', 'code-profiler') ."\n\n". | |
| 539 | + print_r( $res['body'], true ). | |
| 540 | + "\n==================================================\n" | |
| 541 | + ); | |
| 542 | + } | |
| 543 | + | |
| 484 | 544 | // HTTP status code |
| 485 | 545 | if (! empty( $cp_options['http_response'] ) ) { |
| 486 | 546 | if ( preg_match( "/{$cp_options['http_response']}/", $res['response']['code'] ) ) { |
| 547 | + | |
| 548 | + $msg = ''; | |
| 549 | + | |
| 487 | 550 | $log = esc_html__( |
| 551 | + /* Translators: HTTP response code and message */ | |
| 488 | 552 | 'The website returned the following HTTP status code: %s %s.', 'code-profiler' |
| 489 | 553 | ); |
| 490 | - if ( $res['response']['code'] >= 500 ) { | |
| 491 | - $msg = $log .' '. esc_html__( | |
| 492 | - 'You may find more details about this error in your PHP error log.', | |
| 493 | - 'code-profiler' | |
| 494 | - ); | |
| 495 | - } else { | |
| 496 | - $msg = $log .' '. esc_html__('By default, the profiler will always abort and throw an error '. | |
| 497 | - 'if the server did not return a 200 HTTP status code. You can change that behaviour in '. | |
| 498 | - 'the Settings section if the page you are profiling needs to return a different '. | |
| 499 | - 'code (3xx, 4xx or 5xx).', 'code-profiler'); | |
| 554 | + | |
| 555 | + if ( $res['response']['code'] < 500 ) { | |
| 556 | + $log .= ' '. esc_html__('By default, the profiler will always abort and throw an error if the server did not return a 200 HTTP status code. You can change that behaviour in the "Settings" section if the page you are profiling needs to return a different code (3xx, 4xx or 5xx).', 'code-profiler'); | |
| 500 | 557 | } |
| 558 | + | |
| 559 | + $msg .= $log .' '. esc_html__('You may find more details about this error in your PHP error log and/or in the "Logs" section.', 'code-profiler'); | |
| 560 | + | |
| 501 | 561 | $response['message'] = sprintf( |
| 502 | 562 | $msg, |
| 503 | 563 | (int) $res['response']['code'], |
| 504 | 564 | $res['response']['message'] |
| @@ -505,8 +565,21 @@ | ||
| 505 | 565 | ); |
| 506 | 566 | code_profiler_log_error( |
| 507 | 567 | sprintf( $log, $res['response']['code'], $res['response']['message'] ) |
| 508 | 568 | ); |
| 569 | + | |
| 570 | + // If it is a 301/302 redirection, we write the new URL to the log | |
| 571 | + if ( in_array( $res['response']['code'], [301, 302] ) && | |
| 572 | + isset( $res['headers']['location'] ) ) { | |
| 573 | + | |
| 574 | + code_profiler_log_error( | |
| 575 | + sprintf( | |
| 576 | + /* Translators: URL */ | |
| 577 | + esc_html__('The URL redirects to: %s', 'code-profiler'), | |
| 578 | + $res['headers']['location'] | |
| 579 | + ) | |
| 580 | + ); | |
| 581 | + } | |
| 509 | 582 | code_profiler_wp_send_json( $response ); |
| 510 | 583 | } |
| 511 | 584 | } |
| 512 | 585 | |
| @@ -615,13 +688,8 @@ | ||
| 615 | 688 | |
| 616 | 689 | // Take a 1s break so that we can spot any potential error |
| 617 | 690 | // in the backend before AJAX refresh the page |
| 618 | 691 | usleep( 1000000 ); |
| 619 | - | |
| 620 | - // Clear hash | |
| 621 | - $cp_options = get_option('code-profiler'); | |
| 622 | - unset( $cp_options['hash'] ); | |
| 623 | - update_option('code-profiler', $cp_options ); | |
| 624 | 692 | |
| 625 | 693 | code_profiler_log_info( |
| 626 | 694 | esc_html__('All done, exiting profiler', 'code-profiler') |
| 627 | 695 | ); |