From eb1d7e48f4afe4220574f45e737a4943f00c6499 Mon Sep 17 00:00:00 2001 From: Evan Kaufman Date: Thu, 24 Dec 2020 13:16:06 -0800 Subject: [PATCH 1/4] Implemented export to nginx of error (4xx) redirects --- fileio/nginx.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/fileio/nginx.php b/fileio/nginx.php index b14ff3375..9188d1312 100644 --- a/fileio/nginx.php +++ b/fileio/nginx.php @@ -56,6 +56,10 @@ private function get_nginx_item( Red_Item $item ) { } private function add_url( Red_Item $item, array $match_data ) { + if ( $item->get_action_type() === 'error' ) { + return $this->get_error( $item->get_url(), $item->get_action_code(), $match_data['source'] ); + } + return $this->get_redirect( $item->get_url(), $item->get_action_data(), $this->get_redirect_code( $item ), $match_data['source'] ); } @@ -109,4 +113,29 @@ private function get_redirect( $line, $target, $code, $source ) { return 'rewrite ' . $line . '$ ' . $target . ' ' . $code . ';'; } + + private function get_error( $line, $code, $source ) { + // Remove any existing start/end from a regex + $line = ltrim( $line, '^' ); + $line = rtrim( $line, '$' ); + $line = preg_replace( "/[\r\n\t].*?$/s", '', $line ); + $line = preg_replace( '/[^\PC\s]/u', '', $line ); + + // For regex... + if ( isset( $source['flag_regex'] ) && $source['flag_regex'] ) { + // Vary modifier for case in/sensitivity + if ( isset( $source['flag_case'] ) && $source['flag_case'] ) { + $modifier = '~*'; + } else { + $modifier = '~'; + } + // And re-anchor url + $line = '^' . $line . '$'; + // For exact match... + } else { + $modifier = '='; + } + + return 'location ' . $modifier . ' ' . $line . ' { return ' . $code . '; }'; + } } From e860602767aecfe32da3ae2e39387e7353d789c0 Mon Sep 17 00:00:00 2001 From: Evan Kaufman Date: Thu, 24 Dec 2020 14:47:20 -0800 Subject: [PATCH 2/4] Implemented case insensitivity for non-regex error url --- fileio/nginx.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fileio/nginx.php b/fileio/nginx.php index 9188d1312..8da8dbcf5 100644 --- a/fileio/nginx.php +++ b/fileio/nginx.php @@ -131,9 +131,16 @@ private function get_error( $line, $code, $source ) { } // And re-anchor url $line = '^' . $line . '$'; - // For exact match... + // For non-regex... } else { - $modifier = '='; + // Escape and use as regex for case insensitivity + if ( isset( $source['flag_case'] ) && $source['flag_case'] ) { + $modifier = '~*'; + $line = '^' . preg_quote($line) . '$'; + // Otherwise use exact match + } else { + $modifier = '='; + } } return 'location ' . $modifier . ' ' . $line . ' { return ' . $code . '; }'; From f5787d3f7af6c935cd40b6bf5cc1305f3ed7a4e0 Mon Sep 17 00:00:00 2001 From: Evan Kaufman Date: Thu, 24 Dec 2020 16:45:07 -0800 Subject: [PATCH 3/4] Added tests for nginx error export --- tests/fileio/test-nginx.php | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/fileio/test-nginx.php b/tests/fileio/test-nginx.php index 0eb994f0b..83cbeb55b 100644 --- a/tests/fileio/test-nginx.php +++ b/tests/fileio/test-nginx.php @@ -60,4 +60,54 @@ public function testCaseInsensitive() { $this->assertEquals( 'rewrite (?i)^/test$ /target permanent;', trim( $lines[5] ) ); } + + public function testError() { + $nginx = new Red_Nginx_File(); + $redirects = array( new Red_Item( ( object )array( 'match_type' => 'url', 'id' => 1, 'action_type' => 'error', 'url' => '/test', 'action_code' => 410, 'status' => 'enabled' ) ) ); + + $file = $nginx->get_data( $redirects, array() ); + $lines = explode( "\n", $file ); + + $this->assertEquals( count( $lines ), 10 ); + $this->assertEquals( '# Created by Redirection', trim( $lines[0] ) ); + $this->assertEquals( 'server {', trim( $lines[4] ) ); + $this->assertEquals( 'location = /test { return 410; }', trim( $lines[5] ) ); + $this->assertEquals( '}', trim( $lines[ count( $lines ) - 4 ] ) ); + $this->assertEquals( '# End of Redirection', trim( $lines[ count( $lines ) - 2 ] ) ); + } + + public function testErrorRegex() { + $nginx = new Red_Nginx_File(); + $redirects = array( new Red_Item( ( object )array( 'match_type' => 'url', 'id' => 1, 'regex' => true, 'action_type' => 'error', 'url' => '^/test.*', 'action_code' => 418, 'status' => 'enabled' ) ) ); + + $file = $nginx->get_data( $redirects, array() ); + $lines = explode( "\n", $file ); + + $this->assertEquals( count( $lines ), 10 ); + $this->assertEquals( 'location ~ ^/test.*$ { return 418; }', trim( $lines[5] ) ); + } + + public function testErrorCaseInsensitive() { + $match_data = json_encode( [ 'source' => [ 'flag_case' => true ] ] ); + $nginx = new Red_Nginx_File(); + $redirects = array( new Red_Item( ( object )array( 'match_type' => 'url', 'id' => 1, 'action_type' => 'error', 'url' => '/test.php', 'action_code' => 451, 'match_data' => $match_data, 'status' => 'enabled' ) ) ); + + $file = $nginx->get_data( $redirects, array() ); + $lines = explode( "\n", $file ); + + $this->assertEquals( count( $lines ), 10 ); + $this->assertEquals( 'location ~* ^/test\.php$ { return 451; }', trim( $lines[5] ) ); + } + + public function testErrorRegexCaseInsensitive() { + $match_data = json_encode( [ 'source' => [ 'flag_case' => true ] ] ); + $nginx = new Red_Nginx_File(); + $redirects = array( new Red_Item( ( object )array( 'match_type' => 'url', 'id' => 1, 'regex' => true, 'action_type' => 'error', 'url' => '^/test.*', 'action_code' => 403, 'match_data' => $match_data, 'status' => 'enabled' ) ) ); + + $file = $nginx->get_data( $redirects, array() ); + $lines = explode( "\n", $file ); + + $this->assertEquals( count( $lines ), 10 ); + $this->assertEquals( 'location ~* ^/test.*$ { return 403; }', trim( $lines[5] ) ); + } } From e559a2be675150478ef4e10c8d30972a6ae9b7e6 Mon Sep 17 00:00:00 2001 From: Evan Kaufman Date: Thu, 24 Dec 2020 23:59:25 -0800 Subject: [PATCH 4/4] Fix test failing for flag_regex --- tests/fileio/test-nginx.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fileio/test-nginx.php b/tests/fileio/test-nginx.php index 83cbeb55b..42bf5e8ac 100644 --- a/tests/fileio/test-nginx.php +++ b/tests/fileio/test-nginx.php @@ -100,7 +100,7 @@ public function testErrorCaseInsensitive() { } public function testErrorRegexCaseInsensitive() { - $match_data = json_encode( [ 'source' => [ 'flag_case' => true ] ] ); + $match_data = json_encode( [ 'source' => [ 'flag_case' => true, 'flag_regex' => true ] ] ); $nginx = new Red_Nginx_File(); $redirects = array( new Red_Item( ( object )array( 'match_type' => 'url', 'id' => 1, 'regex' => true, 'action_type' => 'error', 'url' => '^/test.*', 'action_code' => 403, 'match_data' => $match_data, 'status' => 'enabled' ) ) );