[Rt-commit] rt branch, 4.0-trunk, updated. rt-4.0.0rc6-122-g511e2d4

Alex Vandiver alexmv at bestpractical.com
Mon Mar 7 15:18:48 EST 2011


The branch, 4.0-trunk has been updated
       via  511e2d4d278bf2be2bd30b461eb84cdd2287849b (commit)
       via  552191ec55d0387e5dde646397b10c609701ac1d (commit)
       via  2ff6caa73798ed55de2e2dc154bc3c790906dc8e (commit)
       via  8ac8c928cdc1bb940617b1f9f7dda1b694b0fb4d (commit)
       via  8c6ce9794fb3cc7959e901faef13794c00b6eaf7 (commit)
       via  a1f2fef4ffb0ae40efacc4cdb7c1ba8cee31cdad (commit)
       via  07ee408ad96bd427ecb0bbcdade82ce7e3bb43d7 (commit)
       via  c800c1498b983994a64c262229a321f282143f30 (commit)
       via  d90da0291be55147ba7e081d5b650916eba7203d (commit)
       via  9a21d6831ca5319f10596b8b14194d881167bca5 (commit)
       via  8c07aaac4bbb832493506c8d351cd25244ba405e (commit)
       via  6442feddcc84987e8b35e00f78b53996ef7590da (commit)
       via  accd61356beaba2d8783a5d53efd5566b5b88f74 (commit)
       via  b3fc9c44065c675c224a612fdfab808d034e9962 (commit)
       via  b3aff1dee707578d50c3a6e0295805d6be85aff5 (commit)
       via  d18f44f8b478172a1d2c955da15fffe123545dc5 (commit)
       via  67d0e3383ff17dd75fcdaef223eca457afac4e44 (commit)
       via  cfcc4e864f5950d486cc92aae3e62e8aed455c30 (commit)
       via  d8525aec55bf2ae9f5bca618f48843c1de924650 (commit)
       via  fd331c5ee0895c88d2c4defbc29e1240b4eb5a86 (commit)
       via  dbc3be4ee2b877725c516a39dc0eff435c63ac7d (commit)
       via  d308ca8606a69691f6381f3e75519fb6d8c39363 (commit)
       via  12db13fa39ffc0f08f817d42374a52e1345344dd (commit)
       via  d50dc1233e464ca48718a8831fb5988ff3fe9a93 (commit)
       via  a403984c93cab9faef02964fdc84364e88c8e874 (commit)
       via  49c7b26300aab43b869b63ef31783f61be3b5879 (commit)
       via  657a54c497de93805953d2680b799329ad658b1d (commit)
       via  1477965de50dce7dba4c4a004cff0bcbb6aa6d40 (commit)
       via  f1d13b4b77b3d51362d50877f254e1313a558276 (commit)
       via  1df624dffe0c3ad75a882530094da2d05908919a (commit)
       via  e7ee68b10d52111c8658e3edb443e02764b78200 (commit)
       via  2552e8a4b54dba236c5aed38004818132b4ba467 (commit)
       via  34450f9a075110d0168059f4e1545441838af72b (commit)
       via  17f20f4d7702c8995d6e254c6bb4ea5d9d3ad509 (commit)
       via  4523baff8adedc5e1aaac2d524340189716578f7 (commit)
       via  86724f50eda221da619a0db2525ea6a418d175c5 (commit)
       via  6b0288d8cdb9094e8e876bf289e8970eaa0d405a (commit)
       via  a150639b63733c99637319232a8ab81dbc6cfc64 (commit)
       via  7e8c06de31d1c50ff28c794d8854e253956c7801 (commit)
       via  70d0b47622d0d5851c4319364ea89e808e87cd4a (commit)
       via  d8369fb109108b6cd528be10b4e7fc815d21ce1d (commit)
       via  3f3daf96f49a2db98c7d66fd87b62f0a5a6cae0e (commit)
       via  80f99916da474d46741c8a56be4a10cda11c2e5c (commit)
       via  7479cd2f3e421114b0dcaa15c57800a2cc10f818 (commit)
       via  cecdd645659565a2a3e3187793fbc05da1ead2c6 (commit)
       via  c66f03325bb1c47f7734174abeb6458bb2031acf (commit)
       via  01c6628f00a57cc6c0176e5268e92200f4a74841 (commit)
       via  9dc1eca1511d46e4ac71fa089b0dee1777ea0809 (commit)
       via  a6a2c93f569bc742c214cb0824b6111d3b22898b (commit)
       via  b04468be8ffa4178c7476f1b6c5f8d1414e794f6 (commit)
       via  b95abf852c1bd5cac77dc9d94faf16647f888e5f (commit)
       via  71334f7afa6e98157f10e287669b5cd0d9a5bdf9 (commit)
      from  01b89391ecb9ae2c65ffca99cfa25f9299ca59fc (commit)

Summary of changes:
 lib/RT/Config.pm        |  111 ++++++++++++++++++++++-
 lib/RT/Handle.pm        |   15 ++--
 lib/RT/Interface/Web.pm |   40 ++++++++
 lib/RT/Test.pm          |  230 +++++++++++++++++++++++++++--------------------
 lib/RT/Test/Apache.pm   |    2 +
 sbin/rt-server.in       |   33 ++++++--
 t/api/web-config.t      |  163 +++++++++++++++++++++++++++++++++
 t/shredder/utils.pl     |   10 +--
 8 files changed, 482 insertions(+), 122 deletions(-)
 create mode 100644 t/api/web-config.t

- Log -----------------------------------------------------------------
commit 71334f7afa6e98157f10e287669b5cd0d9a5bdf9
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Tue Dec 28 19:01:40 2010 -0500

    Warnings and tests for broken WebPath settings

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index 64798a2..4d5888e 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -536,6 +536,26 @@ our %META = (
                               'You can change the site default in your %Lifecycles config.');
         }
     },
+    WebPath => {
+        PostLoadCheck => sub {
+            my $self  = shift;
+            my $value = shift;
+
+            # "In most cases, you should leave $WebPath set to '' (an empty value)."
+            return unless $value;
+
+            # $WebPath requires a leading / but no trailing /, or it can be blank.
+            return if $value =~ m{^/.+[^/]$};
+
+            if ($value =~ m{/$}) {
+                $RT::Logger->error("The WebPath config option requires no trailing slash");
+            }
+
+            if ($value !~ m{^/}) {
+                $RT::Logger->error("The WebPath config option requires a leading slash");
+            }
+        },
+    },
 );
 my %OPTIONS = ();
 
diff --git a/t/api/web-config.t b/t/api/web-config.t
new file mode 100644
index 0000000..150784d
--- /dev/null
+++ b/t/api/web-config.t
@@ -0,0 +1,36 @@
+use strict;
+use warnings;
+use RT;
+use RT::Test nodb => 1, tests => 9;
+
+sub warnings_from {
+    my $option = shift;
+    my $value  = shift;
+
+    my @warnings;
+    local $SIG{__WARN__} = sub {
+        push @warnings, $_[0];
+    };
+
+    RT->Config->Set($option => $value);
+    RT->Config->PostLoadCheck;
+
+    return @warnings;
+}
+
+is(warnings_from(WebPath => ''), 0);
+is(warnings_from(WebPath => '/foo'), 0);
+
+my @w = warnings_from(WebPath => '/foo/');
+is(@w, 1);
+like($w[0], qr/The WebPath config option requires no trailing slash/);
+
+ at w = warnings_from(WebPath => 'foo');
+is(@w, 1);
+like($w[0], qr/The WebPath config option requires a leading slash/);
+
+ at w = warnings_from(WebPath => 'foo/');
+is(@w, 2);
+like($w[0], qr/The WebPath config option requires no trailing slash/);
+like($w[1], qr/The WebPath config option requires a leading slash/);
+

commit b95abf852c1bd5cac77dc9d94faf16647f888e5f
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Tue Dec 28 19:03:36 2010 -0500

    Catch Set($WebPath, '/') as a special case

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index 4d5888e..265d706 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -544,6 +544,12 @@ our %META = (
             # "In most cases, you should leave $WebPath set to '' (an empty value)."
             return unless $value;
 
+            # try to catch someone who assumes that you shouldn't leave this empty
+            if ($value eq '/') {
+                $RT::Logger->error("For the WebPath config option, use the empty string instead of /");
+                return;
+            }
+
             # $WebPath requires a leading / but no trailing /, or it can be blank.
             return if $value =~ m{^/.+[^/]$};
 
diff --git a/t/api/web-config.t b/t/api/web-config.t
index 150784d..c91d1fa 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use RT;
-use RT::Test nodb => 1, tests => 9;
+use RT::Test nodb => 1, tests => 11;
 
 sub warnings_from {
     my $option = shift;
@@ -34,3 +34,7 @@ is(@w, 2);
 like($w[0], qr/The WebPath config option requires no trailing slash/);
 like($w[1], qr/The WebPath config option requires a leading slash/);
 
+ at w = warnings_from(WebPath => '/');
+is(@w, 1);
+like($w[0], qr{For the WebPath config option, use the empty string instead of /});
+

commit b04468be8ffa4178c7476f1b6c5f8d1414e794f6
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Tue Dec 28 19:18:54 2010 -0500

    Validate WebDomain

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index 265d706..d7ed5c1 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -562,6 +562,27 @@ our %META = (
             }
         },
     },
+    WebDomain => {
+        PostLoadCheck => sub {
+            my $self  = shift;
+            my $value = shift;
+
+            if (!$value) {
+                $RT::Logger->error("You must set the WebDomain config option");
+                return;
+            }
+
+            if ($value =~ m{^(\w+://)}) {
+                $RT::Logger->error("The WebDomain config option must not contain a scheme ($1)");
+                return;
+            }
+
+            if ($value =~ m{(/.*)}) {
+                $RT::Logger->error("The WebDomain config option must not contain a path ($1)");
+                return;
+            }
+        },
+    },
 );
 my %OPTIONS = ();
 
diff --git a/t/api/web-config.t b/t/api/web-config.t
index c91d1fa..316a4a9 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use RT;
-use RT::Test nodb => 1, tests => 11;
+use RT::Test nodb => 1, tests => 24;
 
 sub warnings_from {
     my $option = shift;
@@ -18,6 +18,7 @@ sub warnings_from {
     return @warnings;
 }
 
+# WebPath
 is(warnings_from(WebPath => ''), 0);
 is(warnings_from(WebPath => '/foo'), 0);
 
@@ -38,3 +39,30 @@ like($w[1], qr/The WebPath config option requires a leading slash/);
 is(@w, 1);
 like($w[0], qr{For the WebPath config option, use the empty string instead of /});
 
+# reinstate a valid WebPath for other tests
+is(warnings_from(WebPath => '/rt'), 0);
+
+# WebDomain
+is(warnings_from(WebDomain => 'example.com'), 0);
+is(warnings_from(WebDomain => 'rt.example.com'), 0);
+is(warnings_from(WebDomain => 'localhost'), 0);
+
+ at w = warnings_from(WebDomain => '');
+is(@w, 1);
+like($w[0], qr{You must set the WebDomain config option});
+
+ at w = warnings_from(WebDomain => 'http://rt.example.com');
+is(@w, 1);
+like($w[0], qr{The WebDomain config option must not contain a scheme \(http://\)});
+
+ at w = warnings_from(WebDomain => 'https://rt.example.com');
+is(@w, 1);
+like($w[0], qr{The WebDomain config option must not contain a scheme \(https://\)});
+
+ at w = warnings_from(WebDomain => 'rt.example.com/path');
+is(@w, 1);
+like($w[0], qr{The WebDomain config option must not contain a path \(/path\)});
+
+# reinstate a valid WebDomain for other tests
+is(warnings_from(WebDomain => 'rt.example.com'), 0);
+

commit a6a2c93f569bc742c214cb0824b6111d3b22898b
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Tue Dec 28 19:25:06 2010 -0500

    Validate WebPort
    
        *Probably* not needed but we might as well test it, because it's easy
        and we're testing all the others

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index d7ed5c1..d402129 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -583,6 +583,21 @@ our %META = (
             }
         },
     },
+    WebPort => {
+        PostLoadCheck => sub {
+            my $self  = shift;
+            my $value = shift;
+
+            if (!$value) {
+                $RT::Logger->error("You must set the WebPort config option");
+                return;
+            }
+
+            if ($value !~ m{^\d+$}) {
+                $RT::Logger->error("The WebPort config option must be an integer");
+            }
+        },
+    },
 );
 my %OPTIONS = ();
 
diff --git a/t/api/web-config.t b/t/api/web-config.t
index 316a4a9..390eb94 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use RT;
-use RT::Test nodb => 1, tests => 24;
+use RT::Test nodb => 1, tests => 34;
 
 sub warnings_from {
     my $option = shift;
@@ -66,3 +66,23 @@ like($w[0], qr{The WebDomain config option must not contain a path \(/path\)});
 # reinstate a valid WebDomain for other tests
 is(warnings_from(WebDomain => 'rt.example.com'), 0);
 
+# WebPort
+is(warnings_from(WebDomain => 80), 0);
+is(warnings_from(WebDomain => 443), 0);
+is(warnings_from(WebDomain => 8888), 0);
+
+ at w = warnings_from(WebPort => '');
+is(@w, 1);
+like($w[0], qr{You must set the WebPort config option});
+
+ at w = warnings_from(WebPort => 3.14);
+is(@w, 1);
+like($w[0], qr{The WebPort config option must be an integer});
+
+ at w = warnings_from(WebPort => 'wha?');
+is(@w, 1);
+like($w[0], qr{The WebPort config option must be an integer});
+
+# reinstate a valid WebDomain for other tests
+is(warnings_from(WebPort => 443), 0);
+

commit 9dc1eca1511d46e4ac71fa089b0dee1777ea0809
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Tue Dec 28 20:10:35 2010 -0500

    Validate WebBaseURL
    
        Still need to validate that it is the combination of the other
        options, but getting there

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index d402129..fb483ab 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -598,6 +598,25 @@ our %META = (
             }
         },
     },
+    WebBaseURL => {
+        PostLoadCheck => sub {
+            my $self  = shift;
+            my $value = shift;
+
+            if (!$value) {
+                $RT::Logger->error("You must set the WebBaseURL config option");
+                return;
+            }
+
+            if ($value !~ m{^\w+://}) {
+                $RT::Logger->error("The WebDomain config option must contain a scheme");
+            }
+
+            if ($value =~ m{/$}) {
+                $RT::Logger->error("The WebDomain config option requires no trailing slash");
+            }
+        },
+    },
 );
 my %OPTIONS = ();
 
diff --git a/t/api/web-config.t b/t/api/web-config.t
index 390eb94..e156320 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use RT;
-use RT::Test nodb => 1, tests => 34;
+use RT::Test nodb => 1, tests => 46;
 
 sub warnings_from {
     my $option = shift;
@@ -86,3 +86,27 @@ like($w[0], qr{The WebPort config option must be an integer});
 # reinstate a valid WebDomain for other tests
 is(warnings_from(WebPort => 443), 0);
 
+# WebBaseURL
+is(warnings_from(WebBaseURL => 'http://rt.example.com/rt'), 0);
+is(warnings_from(WebBaseURL => 'xtp://rt.example.com/rt'), 0, 'nonstandard schema is okay');
+is(warnings_from(WebBaseURL => 'http://rt.example.com:8888/rt'), 0, 'nonstandard port is okay');
+
+ at w = warnings_from(WebBaseURL => '');
+is(@w, 1);
+like($w[0], qr{You must set the WebBaseURL config option});
+
+ at w = warnings_from(WebBaseURL => 'rt.example.com');
+is(@w, 1);
+like($w[0], qr{The WebDomain config option must contain a scheme});
+
+ at w = warnings_from(WebBaseURL => 'http://rt.example.com/');
+is(@w, 1);
+like($w[0], qr{The WebDomain config option requires no trailing slash});
+
+ at w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/');
+is(@w, 1);
+like($w[0], qr{The WebDomain config option requires no trailing slash});
+
+# reinstate a valid WebDomain for other tests
+is(warnings_from(WebBaseURL => 'http://rt.example.com/rt'), 0);
+

commit 01c6628f00a57cc6c0176e5268e92200f4a74841
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Tue Dec 28 20:19:25 2010 -0500

    Fix WebBaseURL tests
    
        WebBaseURL must not contain a path, that's for WebURL

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index fb483ab..17b12bc 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -609,11 +609,15 @@ our %META = (
             }
 
             if ($value !~ m{^\w+://}) {
-                $RT::Logger->error("The WebDomain config option must contain a scheme");
+                $RT::Logger->error("The WebBaseURL config option must contain a scheme");
             }
 
             if ($value =~ m{/$}) {
-                $RT::Logger->error("The WebDomain config option requires no trailing slash");
+                $RT::Logger->error("The WebBaseURL config option requires no trailing slash");
+            }
+
+            if ($value =~ m{^\w+://.+?(/[^/].*)}) {
+                $RT::Logger->error("The WebBaseURL config option must not contain a path ($1)");
             }
         },
     },
diff --git a/t/api/web-config.t b/t/api/web-config.t
index e156320..d18d49e 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use RT;
-use RT::Test nodb => 1, tests => 46;
+use RT::Test nodb => 1, tests => 49;
 
 sub warnings_from {
     my $option = shift;
@@ -87,9 +87,9 @@ like($w[0], qr{The WebPort config option must be an integer});
 is(warnings_from(WebPort => 443), 0);
 
 # WebBaseURL
-is(warnings_from(WebBaseURL => 'http://rt.example.com/rt'), 0);
-is(warnings_from(WebBaseURL => 'xtp://rt.example.com/rt'), 0, 'nonstandard schema is okay');
-is(warnings_from(WebBaseURL => 'http://rt.example.com:8888/rt'), 0, 'nonstandard port is okay');
+is(warnings_from(WebBaseURL => 'http://rt.example.com'), 0);
+is(warnings_from(WebBaseURL => 'xtp://rt.example.com'), 0, 'nonstandard schema is okay');
+is(warnings_from(WebBaseURL => 'http://rt.example.com:8888'), 0, 'nonstandard port is okay');
 
 @w = warnings_from(WebBaseURL => '');
 is(@w, 1);
@@ -97,16 +97,21 @@ like($w[0], qr{You must set the WebBaseURL config option});
 
 @w = warnings_from(WebBaseURL => 'rt.example.com');
 is(@w, 1);
-like($w[0], qr{The WebDomain config option must contain a scheme});
+like($w[0], qr{The WebBaseURL config option must contain a scheme});
 
 @w = warnings_from(WebBaseURL => 'http://rt.example.com/');
 is(@w, 1);
-like($w[0], qr{The WebDomain config option requires no trailing slash});
+like($w[0], qr{The WebBaseURL config option requires no trailing slash});
 
- at w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/');
+ at w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/ir');
 is(@w, 1);
-like($w[0], qr{The WebDomain config option requires no trailing slash});
+like($w[0], qr{The WebBaseURL config option must not contain a path \(/rt/ir\)});
 
-# reinstate a valid WebDomain for other tests
-is(warnings_from(WebBaseURL => 'http://rt.example.com/rt'), 0);
+ at w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/ir/');
+is(@w, 2);
+like($w[0], qr{The WebBaseURL config option requires no trailing slash});
+like($w[1], qr{The WebBaseURL config option must not contain a path \(/rt/ir/\)});
+
+# reinstate a valid WebBaseURL for other tests
+is(warnings_from(WebBaseURL => 'http://rt.example.com'), 0);
 

commit c66f03325bb1c47f7734174abeb6458bb2031acf
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Tue Dec 28 20:22:43 2010 -0500

    More extensive nested-directory path testing

diff --git a/t/api/web-config.t b/t/api/web-config.t
index d18d49e..fb986f1 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use RT;
-use RT::Test nodb => 1, tests => 49;
+use RT::Test nodb => 1, tests => 64;
 
 sub warnings_from {
     my $option = shift;
@@ -21,6 +21,7 @@ sub warnings_from {
 # WebPath
 is(warnings_from(WebPath => ''), 0);
 is(warnings_from(WebPath => '/foo'), 0);
+is(warnings_from(WebPath => '/foo/bar'), 0);
 
 my @w = warnings_from(WebPath => '/foo/');
 is(@w, 1);
@@ -35,6 +36,19 @@ is(@w, 2);
 like($w[0], qr/The WebPath config option requires no trailing slash/);
 like($w[1], qr/The WebPath config option requires a leading slash/);
 
+ at w = warnings_from(WebPath => '/foo/bar/');
+is(@w, 1);
+like($w[0], qr/The WebPath config option requires no trailing slash/);
+
+ at w = warnings_from(WebPath => 'foo/bar');
+is(@w, 1);
+like($w[0], qr/The WebPath config option requires a leading slash/);
+
+ at w = warnings_from(WebPath => 'foo/bar/');
+is(@w, 2);
+like($w[0], qr/The WebPath config option requires no trailing slash/);
+like($w[1], qr/The WebPath config option requires a leading slash/);
+
 @w = warnings_from(WebPath => '/');
 is(@w, 1);
 like($w[0], qr{For the WebPath config option, use the empty string instead of /});
@@ -63,6 +77,10 @@ like($w[0], qr{The WebDomain config option must not contain a scheme \(https://\
 is(@w, 1);
 like($w[0], qr{The WebDomain config option must not contain a path \(/path\)});
 
+ at w = warnings_from(WebDomain => 'rt.example.com/path/more');
+is(@w, 1);
+like($w[0], qr{The WebDomain config option must not contain a path \(/path/more\)});
+
 # reinstate a valid WebDomain for other tests
 is(warnings_from(WebDomain => 'rt.example.com'), 0);
 
@@ -103,6 +121,15 @@ like($w[0], qr{The WebBaseURL config option must contain a scheme});
 is(@w, 1);
 like($w[0], qr{The WebBaseURL config option requires no trailing slash});
 
+ at w = warnings_from(WebBaseURL => 'http://rt.example.com/rt');
+is(@w, 1);
+like($w[0], qr{The WebBaseURL config option must not contain a path \(/rt\)});
+
+ at w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/');
+is(@w, 2);
+like($w[0], qr{The WebBaseURL config option requires no trailing slash});
+like($w[1], qr{The WebBaseURL config option must not contain a path \(/rt/\)});
+
 @w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/ir');
 is(@w, 1);
 like($w[0], qr{The WebBaseURL config option must not contain a path \(/rt/ir\)});

commit cecdd645659565a2a3e3187793fbc05da1ead2c6
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Tue Dec 28 20:25:17 2010 -0500

    A few WebBaseURL test tweaks

diff --git a/t/api/web-config.t b/t/api/web-config.t
index fb986f1..aa0356a 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use RT;
-use RT::Test nodb => 1, tests => 64;
+use RT::Test nodb => 1, tests => 65;
 
 sub warnings_from {
     my $option = shift;
@@ -106,8 +106,9 @@ is(warnings_from(WebPort => 443), 0);
 
 # WebBaseURL
 is(warnings_from(WebBaseURL => 'http://rt.example.com'), 0);
-is(warnings_from(WebBaseURL => 'xtp://rt.example.com'), 0, 'nonstandard schema is okay');
+is(warnings_from(WebBaseURL => 'xtp://rt.example.com'), 0, 'nonstandard schema is okay?');
 is(warnings_from(WebBaseURL => 'http://rt.example.com:8888'), 0, 'nonstandard port is okay');
+is(warnings_from(WebBaseURL => 'https://rt.example.com:8888'), 0, 'nonstandard port with https is okay');
 
 @w = warnings_from(WebBaseURL => '');
 is(@w, 1);

commit 7479cd2f3e421114b0dcaa15c57800a2cc10f818
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Tue Dec 28 20:54:40 2010 -0500

    Validate WebURL

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index 17b12bc..dfdf59a 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -621,6 +621,25 @@ our %META = (
             }
         },
     },
+    WebURL => {
+        PostLoadCheck => sub {
+            my $self  = shift;
+            my $value = shift;
+
+            if (!$value) {
+                $RT::Logger->error("You must set the WebURL config option");
+                return;
+            }
+
+            if ($value !~ m{^\w+://}) {
+                $RT::Logger->error("The WebURL config option must contain a scheme");
+            }
+
+            if ($value !~ m{/$}) {
+                $RT::Logger->error("The WebURL config option requires a trailing slash");
+            }
+        },
+    },
 );
 my %OPTIONS = ();
 
diff --git a/t/api/web-config.t b/t/api/web-config.t
index aa0356a..8037ad5 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use RT;
-use RT::Test nodb => 1, tests => 65;
+use RT::Test nodb => 1, tests => 83;
 
 sub warnings_from {
     my $option = shift;
@@ -143,3 +143,35 @@ like($w[1], qr{The WebBaseURL config option must not contain a path \(/rt/ir/\)}
 # reinstate a valid WebBaseURL for other tests
 is(warnings_from(WebBaseURL => 'http://rt.example.com'), 0);
 
+# WebURL
+is(warnings_from(WebURL => 'http://rt.example.com/'), 0);
+is(warnings_from(WebURL => 'http://example.com/rt/'), 0);
+is(warnings_from(WebURL => 'http://example.com/rt/ir/'), 0);
+is(warnings_from(WebURL => 'xtp://rt.example.com/'), 0, 'nonstandard schema is okay?');
+is(warnings_from(WebURL => 'http://rt.example.com:8888/'), 0, 'nonstandard port is okay');
+is(warnings_from(WebURL => 'https://rt.example.com:8888/'), 0, 'nonstandard port with https is okay');
+
+ at w = warnings_from(WebURL => '');
+is(@w, 1);
+like($w[0], qr{You must set the WebURL config option});
+
+ at w = warnings_from(WebURL => 'rt.example.com');
+is(@w, 2);
+like($w[0], qr{The WebURL config option must contain a scheme});
+like($w[1], qr{The WebURL config option requires a trailing slash});
+
+ at w = warnings_from(WebURL => 'http://rt.example.com');
+is(@w, 1);
+like($w[0], qr{The WebURL config option requires a trailing slash});
+
+ at w = warnings_from(WebURL => 'http://rt.example.com/rt');
+is(@w, 1);
+like($w[0], qr{The WebURL config option requires a trailing slash});
+
+ at w = warnings_from(WebURL => 'http://rt.example.com/rt/ir');
+is(@w, 1);
+like($w[0], qr{The WebURL config option requires a trailing slash});
+
+# reinstate a valid WebURL for other tests
+is(warnings_from(WebURL => 'http://rt.example.com/rt/'), 0);
+

commit 80f99916da474d46741c8a56be4a10cda11c2e5c
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Fri Jan 7 13:04:51 2011 -0500

    Lock down scheme to http or https

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index dfdf59a..cc6be20 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -608,15 +608,15 @@ our %META = (
                 return;
             }
 
-            if ($value !~ m{^\w+://}) {
-                $RT::Logger->error("The WebBaseURL config option must contain a scheme");
+            if ($value !~ m{^https?://}i) {
+                $RT::Logger->error("The WebBaseURL config option must contain a scheme (http or https)");
             }
 
             if ($value =~ m{/$}) {
                 $RT::Logger->error("The WebBaseURL config option requires no trailing slash");
             }
 
-            if ($value =~ m{^\w+://.+?(/[^/].*)}) {
+            if ($value =~ m{^https?://.+?(/[^/].*)}i) {
                 $RT::Logger->error("The WebBaseURL config option must not contain a path ($1)");
             }
         },
@@ -631,8 +631,8 @@ our %META = (
                 return;
             }
 
-            if ($value !~ m{^\w+://}) {
-                $RT::Logger->error("The WebURL config option must contain a scheme");
+            if ($value !~ m{^https?://}i) {
+                $RT::Logger->error("The WebURL config option must contain a scheme (http or https)");
             }
 
             if ($value !~ m{/$}) {
diff --git a/t/api/web-config.t b/t/api/web-config.t
index 8037ad5..48981cf 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use RT;
-use RT::Test nodb => 1, tests => 83;
+use RT::Test nodb => 1, tests => 87;
 
 sub warnings_from {
     my $option = shift;
@@ -106,7 +106,7 @@ is(warnings_from(WebPort => 443), 0);
 
 # WebBaseURL
 is(warnings_from(WebBaseURL => 'http://rt.example.com'), 0);
-is(warnings_from(WebBaseURL => 'xtp://rt.example.com'), 0, 'nonstandard schema is okay?');
+is(warnings_from(WebBaseURL => 'HTTP://rt.example.com'), 0, 'uppercase scheme is okay');
 is(warnings_from(WebBaseURL => 'http://rt.example.com:8888'), 0, 'nonstandard port is okay');
 is(warnings_from(WebBaseURL => 'https://rt.example.com:8888'), 0, 'nonstandard port with https is okay');
 
@@ -118,6 +118,10 @@ like($w[0], qr{You must set the WebBaseURL config option});
 is(@w, 1);
 like($w[0], qr{The WebBaseURL config option must contain a scheme});
 
+ at w = warnings_from(WebBaseURL => 'xtp://rt.example.com');
+is(@w, 1);
+like($w[0], qr{The WebBaseURL config option must contain a scheme \(http or https\)});
+
 @w = warnings_from(WebBaseURL => 'http://rt.example.com/');
 is(@w, 1);
 like($w[0], qr{The WebBaseURL config option requires no trailing slash});
@@ -145,9 +149,9 @@ is(warnings_from(WebBaseURL => 'http://rt.example.com'), 0);
 
 # WebURL
 is(warnings_from(WebURL => 'http://rt.example.com/'), 0);
+is(warnings_from(WebURL => 'HTTP://rt.example.com/'), 0, 'uppercase scheme is okay');
 is(warnings_from(WebURL => 'http://example.com/rt/'), 0);
 is(warnings_from(WebURL => 'http://example.com/rt/ir/'), 0);
-is(warnings_from(WebURL => 'xtp://rt.example.com/'), 0, 'nonstandard schema is okay?');
 is(warnings_from(WebURL => 'http://rt.example.com:8888/'), 0, 'nonstandard port is okay');
 is(warnings_from(WebURL => 'https://rt.example.com:8888/'), 0, 'nonstandard port with https is okay');
 
@@ -164,6 +168,10 @@ like($w[1], qr{The WebURL config option requires a trailing slash});
 is(@w, 1);
 like($w[0], qr{The WebURL config option requires a trailing slash});
 
+ at w = warnings_from(WebURL => 'xtp://example.com/rt/');
+is(@w, 1);
+like($w[0], qr{The WebURL config option must contain a scheme \(http or https\)});
+
 @w = warnings_from(WebURL => 'http://rt.example.com/rt');
 is(@w, 1);
 like($w[0], qr{The WebURL config option requires a trailing slash});

commit 3f3daf96f49a2db98c7d66fd87b62f0a5a6cae0e
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Fri Jan 7 13:12:45 2011 -0500

    Simplify the 0 and 1 warning test cases

diff --git a/t/api/web-config.t b/t/api/web-config.t
index 48981cf..4a4f5c3 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -3,6 +3,30 @@ use warnings;
 use RT;
 use RT::Test nodb => 1, tests => 87;
 
+sub no_warnings_ok {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+    my $option = shift;
+    my $value  = shift;
+    my $name   = shift;
+
+    is(warnings_from($option => $value), 0, $name);
+}
+
+sub one_warning_like {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+    my $option = shift;
+    my $value  = shift;
+    my $regex  = shift;
+    my $name   = shift;
+
+    my @w = warnings_from($option => $value);
+    is(@w, 1);
+    like($w[0], $regex, $name);
+}
+
+
 sub warnings_from {
     my $option = shift;
     my $value  = shift;
@@ -19,125 +43,87 @@ sub warnings_from {
 }
 
 # WebPath
-is(warnings_from(WebPath => ''), 0);
-is(warnings_from(WebPath => '/foo'), 0);
-is(warnings_from(WebPath => '/foo/bar'), 0);
+no_warnings_ok(WebPath => '');
+no_warnings_ok(WebPath => '/foo');
+no_warnings_ok(WebPath => '/foo/bar');
 
-my @w = warnings_from(WebPath => '/foo/');
-is(@w, 1);
-like($w[0], qr/The WebPath config option requires no trailing slash/);
+one_warning_like(WebPath => '/foo/', qr/The WebPath config option requires no trailing slash/);
 
- at w = warnings_from(WebPath => 'foo');
-is(@w, 1);
-like($w[0], qr/The WebPath config option requires a leading slash/);
+one_warning_like(WebPath => 'foo', qr/The WebPath config option requires a leading slash/);
 
- at w = warnings_from(WebPath => 'foo/');
+my @w = warnings_from(WebPath => 'foo/');
 is(@w, 2);
 like($w[0], qr/The WebPath config option requires no trailing slash/);
 like($w[1], qr/The WebPath config option requires a leading slash/);
 
- at w = warnings_from(WebPath => '/foo/bar/');
-is(@w, 1);
-like($w[0], qr/The WebPath config option requires no trailing slash/);
+one_warning_like(WebPath => '/foo/bar/', qr/The WebPath config option requires no trailing slash/);
 
- at w = warnings_from(WebPath => 'foo/bar');
-is(@w, 1);
-like($w[0], qr/The WebPath config option requires a leading slash/);
+one_warning_like(WebPath => 'foo/bar', qr/The WebPath config option requires a leading slash/);
 
 @w = warnings_from(WebPath => 'foo/bar/');
 is(@w, 2);
 like($w[0], qr/The WebPath config option requires no trailing slash/);
 like($w[1], qr/The WebPath config option requires a leading slash/);
 
- at w = warnings_from(WebPath => '/');
-is(@w, 1);
-like($w[0], qr{For the WebPath config option, use the empty string instead of /});
+one_warning_like(WebPath => '/', qr{For the WebPath config option, use the empty string instead of /});
 
 # reinstate a valid WebPath for other tests
-is(warnings_from(WebPath => '/rt'), 0);
+no_warnings_ok(WebPath => '/rt');
 
 # WebDomain
-is(warnings_from(WebDomain => 'example.com'), 0);
-is(warnings_from(WebDomain => 'rt.example.com'), 0);
-is(warnings_from(WebDomain => 'localhost'), 0);
+no_warnings_ok(WebDomain => 'example.com');
+no_warnings_ok(WebDomain => 'rt.example.com');
+no_warnings_ok(WebDomain => 'localhost');
 
- at w = warnings_from(WebDomain => '');
-is(@w, 1);
-like($w[0], qr{You must set the WebDomain config option});
+one_warning_like(WebDomain => '', qr{You must set the WebDomain config option});
 
- at w = warnings_from(WebDomain => 'http://rt.example.com');
-is(@w, 1);
-like($w[0], qr{The WebDomain config option must not contain a scheme \(http://\)});
+one_warning_like(WebDomain => 'http://rt.example.com', qr{The WebDomain config option must not contain a scheme \(http://\)});
 
- at w = warnings_from(WebDomain => 'https://rt.example.com');
-is(@w, 1);
-like($w[0], qr{The WebDomain config option must not contain a scheme \(https://\)});
+one_warning_like(WebDomain => 'https://rt.example.com', qr{The WebDomain config option must not contain a scheme \(https://\)});
 
- at w = warnings_from(WebDomain => 'rt.example.com/path');
-is(@w, 1);
-like($w[0], qr{The WebDomain config option must not contain a path \(/path\)});
+one_warning_like(WebDomain => 'rt.example.com/path', qr{The WebDomain config option must not contain a path \(/path\)});
 
- at w = warnings_from(WebDomain => 'rt.example.com/path/more');
-is(@w, 1);
-like($w[0], qr{The WebDomain config option must not contain a path \(/path/more\)});
+one_warning_like(WebDomain => 'rt.example.com/path/more', qr{The WebDomain config option must not contain a path \(/path/more\)});
 
 # reinstate a valid WebDomain for other tests
-is(warnings_from(WebDomain => 'rt.example.com'), 0);
+no_warnings_ok(WebDomain => 'rt.example.com');
 
 # WebPort
-is(warnings_from(WebDomain => 80), 0);
-is(warnings_from(WebDomain => 443), 0);
-is(warnings_from(WebDomain => 8888), 0);
+no_warnings_ok(WebDomain => 80);
+no_warnings_ok(WebDomain => 443);
+no_warnings_ok(WebDomain => 8888);
 
- at w = warnings_from(WebPort => '');
-is(@w, 1);
-like($w[0], qr{You must set the WebPort config option});
+one_warning_like(WebPort => '', qr{You must set the WebPort config option});
 
- at w = warnings_from(WebPort => 3.14);
-is(@w, 1);
-like($w[0], qr{The WebPort config option must be an integer});
+one_warning_like(WebPort => 3.14, qr{The WebPort config option must be an integer});
 
- at w = warnings_from(WebPort => 'wha?');
-is(@w, 1);
-like($w[0], qr{The WebPort config option must be an integer});
+one_warning_like(WebPort => 'wha?', qr{The WebPort config option must be an integer});
 
 # reinstate a valid WebDomain for other tests
-is(warnings_from(WebPort => 443), 0);
+no_warnings_ok(WebPort => 443);
 
 # WebBaseURL
-is(warnings_from(WebBaseURL => 'http://rt.example.com'), 0);
-is(warnings_from(WebBaseURL => 'HTTP://rt.example.com'), 0, 'uppercase scheme is okay');
-is(warnings_from(WebBaseURL => 'http://rt.example.com:8888'), 0, 'nonstandard port is okay');
-is(warnings_from(WebBaseURL => 'https://rt.example.com:8888'), 0, 'nonstandard port with https is okay');
+no_warnings_ok(WebBaseURL => 'http://rt.example.com');
+no_warnings_ok(WebBaseURL => 'HTTP://rt.example.com', 'uppercase scheme is okay');
+no_warnings_ok(WebBaseURL => 'http://rt.example.com:8888', 'nonstandard port is okay');
+no_warnings_ok(WebBaseURL => 'https://rt.example.com:8888', 'nonstandard port with https is okay');
 
- at w = warnings_from(WebBaseURL => '');
-is(@w, 1);
-like($w[0], qr{You must set the WebBaseURL config option});
+one_warning_like(WebBaseURL => '', qr{You must set the WebBaseURL config option});
 
- at w = warnings_from(WebBaseURL => 'rt.example.com');
-is(@w, 1);
-like($w[0], qr{The WebBaseURL config option must contain a scheme});
+one_warning_like(WebBaseURL => 'rt.example.com', qr{The WebBaseURL config option must contain a scheme});
 
- at w = warnings_from(WebBaseURL => 'xtp://rt.example.com');
-is(@w, 1);
-like($w[0], qr{The WebBaseURL config option must contain a scheme \(http or https\)});
+one_warning_like(WebBaseURL => 'xtp://rt.example.com', qr{The WebBaseURL config option must contain a scheme \(http or https\)});
 
- at w = warnings_from(WebBaseURL => 'http://rt.example.com/');
-is(@w, 1);
-like($w[0], qr{The WebBaseURL config option requires no trailing slash});
+one_warning_like(WebBaseURL => 'http://rt.example.com/', qr{The WebBaseURL config option requires no trailing slash});
 
- at w = warnings_from(WebBaseURL => 'http://rt.example.com/rt');
-is(@w, 1);
-like($w[0], qr{The WebBaseURL config option must not contain a path \(/rt\)});
+one_warning_like(WebBaseURL => 'http://rt.example.com/rt', qr{The WebBaseURL config option must not contain a path \(/rt\)});
 
 @w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/');
 is(@w, 2);
 like($w[0], qr{The WebBaseURL config option requires no trailing slash});
 like($w[1], qr{The WebBaseURL config option must not contain a path \(/rt/\)});
 
- at w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/ir');
-is(@w, 1);
-like($w[0], qr{The WebBaseURL config option must not contain a path \(/rt/ir\)});
+one_warning_like(WebBaseURL => 'http://rt.example.com/rt/ir', qr{The WebBaseURL config option must not contain a path \(/rt/ir\)});
 
 @w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/ir/');
 is(@w, 2);
@@ -145,41 +131,31 @@ like($w[0], qr{The WebBaseURL config option requires no trailing slash});
 like($w[1], qr{The WebBaseURL config option must not contain a path \(/rt/ir/\)});
 
 # reinstate a valid WebBaseURL for other tests
-is(warnings_from(WebBaseURL => 'http://rt.example.com'), 0);
+no_warnings_ok(WebBaseURL => 'http://rt.example.com');
 
 # WebURL
-is(warnings_from(WebURL => 'http://rt.example.com/'), 0);
-is(warnings_from(WebURL => 'HTTP://rt.example.com/'), 0, 'uppercase scheme is okay');
-is(warnings_from(WebURL => 'http://example.com/rt/'), 0);
-is(warnings_from(WebURL => 'http://example.com/rt/ir/'), 0);
-is(warnings_from(WebURL => 'http://rt.example.com:8888/'), 0, 'nonstandard port is okay');
-is(warnings_from(WebURL => 'https://rt.example.com:8888/'), 0, 'nonstandard port with https is okay');
+no_warnings_ok(WebURL => 'http://rt.example.com/');
+no_warnings_ok(WebURL => 'HTTP://rt.example.com/', 'uppercase scheme is okay');
+no_warnings_ok(WebURL => 'http://example.com/rt/');
+no_warnings_ok(WebURL => 'http://example.com/rt/ir/');
+no_warnings_ok(WebURL => 'http://rt.example.com:8888/', 'nonstandard port is okay');
+no_warnings_ok(WebURL => 'https://rt.example.com:8888/', 'nonstandard port with https is okay');
 
- at w = warnings_from(WebURL => '');
-is(@w, 1);
-like($w[0], qr{You must set the WebURL config option});
+one_warning_like(WebURL => '', qr{You must set the WebURL config option});
 
 @w = warnings_from(WebURL => 'rt.example.com');
 is(@w, 2);
 like($w[0], qr{The WebURL config option must contain a scheme});
 like($w[1], qr{The WebURL config option requires a trailing slash});
 
- at w = warnings_from(WebURL => 'http://rt.example.com');
-is(@w, 1);
-like($w[0], qr{The WebURL config option requires a trailing slash});
+one_warning_like(WebURL => 'http://rt.example.com', qr{The WebURL config option requires a trailing slash});
 
- at w = warnings_from(WebURL => 'xtp://example.com/rt/');
-is(@w, 1);
-like($w[0], qr{The WebURL config option must contain a scheme \(http or https\)});
+one_warning_like(WebURL => 'xtp://example.com/rt/', qr{The WebURL config option must contain a scheme \(http or https\)});
 
- at w = warnings_from(WebURL => 'http://rt.example.com/rt');
-is(@w, 1);
-like($w[0], qr{The WebURL config option requires a trailing slash});
+one_warning_like(WebURL => 'http://rt.example.com/rt', qr{The WebURL config option requires a trailing slash});
 
- at w = warnings_from(WebURL => 'http://rt.example.com/rt/ir');
-is(@w, 1);
-like($w[0], qr{The WebURL config option requires a trailing slash});
+one_warning_like(WebURL => 'http://rt.example.com/rt/ir', qr{The WebURL config option requires a trailing slash});
 
 # reinstate a valid WebURL for other tests
-is(warnings_from(WebURL => 'http://rt.example.com/rt/'), 0);
+no_warnings_ok(WebURL => 'http://rt.example.com/rt/');
 

commit d8369fb109108b6cd528be10b4e7fc815d21ce1d
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Fri Jan 7 13:14:28 2011 -0500

    Ensure WebDomain doesn't contain a port

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index cc6be20..c38931b 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -581,6 +581,11 @@ our %META = (
                 $RT::Logger->error("The WebDomain config option must not contain a path ($1)");
                 return;
             }
+
+            if ($value =~ m{:(\d*)}) {
+                $RT::Logger->error("The WebDomain config option must not contain a port ($1)");
+                return;
+            }
         },
     },
     WebPort => {
diff --git a/t/api/web-config.t b/t/api/web-config.t
index 4a4f5c3..fb2b362 100644
--- a/t/api/web-config.t
+++ b/t/api/web-config.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use RT;
-use RT::Test nodb => 1, tests => 87;
+use RT::Test nodb => 1, tests => 89;
 
 sub no_warnings_ok {
     local $Test::Builder::Level = $Test::Builder::Level + 1;
@@ -85,6 +85,8 @@ one_warning_like(WebDomain => 'rt.example.com/path', qr{The WebDomain config opt
 
 one_warning_like(WebDomain => 'rt.example.com/path/more', qr{The WebDomain config option must not contain a path \(/path/more\)});
 
+one_warning_like(WebDomain => 'rt.example.com:80', qr{The WebDomain config option must not contain a port \(80\)});
+
 # reinstate a valid WebDomain for other tests
 no_warnings_ok(WebDomain => 'rt.example.com');
 

commit 70d0b47622d0d5851c4319364ea89e808e87cd4a
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Jan 18 10:14:06 2011 +0300

    make it possible to override user/pass in ::Handle->Connect

diff --git a/lib/RT/Handle.pm b/lib/RT/Handle.pm
index 49b5140..6f1118f 100644
--- a/lib/RT/Handle.pm
+++ b/lib/RT/Handle.pm
@@ -103,6 +103,7 @@ Takes nothing.
 
 sub Connect {
     my $self = shift;
+    my %args = (@_);
 
     my $db_type = RT->Config->Get('DatabaseType');
     if ( $db_type eq 'Oracle' ) {
@@ -113,6 +114,7 @@ sub Connect {
     $self->SUPER::Connect(
         User => RT->Config->Get('DatabaseUser'),
         Password => RT->Config->Get('DatabasePassword'),
+        %args,
     );
 
     if ( $db_type eq 'mysql' ) {

commit 7e8c06de31d1c50ff28c794d8854e253956c7801
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Jan 18 10:17:02 2011 +0300

    don't connect using system DSN when we don't need it

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index d0d465e..db0dd23 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -353,10 +353,6 @@ sub bootstrap_db {
     }
 
     require RT::Handle;
-    # bootstrap with dba cred
-    my $dbh = _get_dbh(RT::Handle->SystemDSN,
-               $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD});
-
     if (my $forceopt = $ENV{RT_TEST_FORCE_OPT}) {
         Test::More::diag "forcing $forceopt";
         $args{$forceopt}=1;
@@ -371,6 +367,12 @@ sub bootstrap_db {
     }
 
     unless ($args{nodb}) {
+        # bootstrap with dba cred
+        my $dbh = _get_dbh(
+            RT::Handle->SystemDSN,
+            $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD}
+        );
+
         unless ( $ENV{RT_TEST_PARALLEL} ) {
             # already dropped db in parallel tests, need to do so for other cases.
             RT::Handle->DropDatabase( $dbh, Force => 1 )

commit a150639b63733c99637319232a8ab81dbc6cfc64
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Jan 18 10:18:03 2011 +0300

    __reconnect_rt and __disconnect_rt functions

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index db0dd23..606cd1f 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -510,6 +510,33 @@ sub _get_dbh {
     return $dbh;
 }
 
+sub __reconnect_rt {
+    my $as_dba = shift;
+    __disconnect_rt();
+
+    # look at %DBIHandle and $PrevHandle in DBIx::SB::Handle for explanation
+    $RT::Handle = RT::Handle->new;
+    $RT::Handle->dbh( undef );
+    $RT::Handle->Connect(
+        $as_dba
+        ? (User => $ENV{RT_DBA_USER}, Password => $ENV{RT_DBA_PASSWORD})
+        : ()
+    );
+    $RT::Handle->PrintError;
+    $RT::Handle->dbh->{PrintError} = 1;
+    return $RT::Handle->dbh;
+}
+
+sub __disconnect_rt {
+    # look at %DBIHandle and $PrevHandle in DBIx::SB::Handle for explanation
+    return unless $RT::Handle;
+    my $dbh = $RT::Handle->dbh;
+    $RT::Handle->dbh(undef);
+    $dbh->disconnect if $dbh;
+    $RT::Handle = undef;
+}
+
+
 =head1 UTILITIES
 
 =head2 load_or_create_user

commit 6b0288d8cdb9094e8e876bf289e8970eaa0d405a
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Jan 18 10:20:20 2011 +0300

    use reconnect and disconnect functions

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 606cd1f..aaa2cdb 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -143,7 +143,7 @@ sub import {
 
     RT::InitPluginPaths();
 
-    RT::ConnectToDatabase()
+    __reconnect_rt()
         unless $args{nodb};
 
     RT::InitClasses();
@@ -381,34 +381,23 @@ sub bootstrap_db {
         $dbh->disconnect;
         $created_new_db++;
 
-        $dbh = _get_dbh(RT::Handle->DSN,
-                        $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD});
-
-        $RT::Handle = RT::Handle->new;
-        $RT::Handle->dbh( $dbh );
-        $RT::Handle->InsertSchema( $dbh );
+        __reconnect_rt('dba');
+        $RT::Handle->InsertSchema;
 
         my $db_type = RT->Config->Get('DatabaseType');
-        $RT::Handle->InsertACL( $dbh ) unless $db_type eq 'Oracle';
+        $RT::Handle->InsertACL unless $db_type eq 'Oracle';
 
-        $RT::Handle = RT::Handle->new;
-        $RT::Handle->dbh( undef );
-        RT->ConnectToDatabase;
         RT->InitLogging;
 
         unless ($args{noinitialdata}) {
+            __reconnect_rt();
             $RT::Handle->InsertInitialData;
 
             DBIx::SearchBuilder::Record::Cachable->FlushCache;
         }
 
-        $RT::Handle = RT::Handle->new;
-        $RT::Handle->dbh( undef );
-        RT->ConnectToDatabase();
-        $RT::Handle->PrintError;
-        $RT::Handle->dbh->{PrintError} = 1;
-
         unless ( $args{'nodata'} ) {
+            __reconnect_rt();
             $RT::Handle->InsertData( $RT::EtcPath . "/initialdata" );
             DBIx::SearchBuilder::Record::Cachable->FlushCache;
         }
@@ -1252,12 +1241,10 @@ sub start_plack_server {
         my $Tester = Test::Builder->new;
         $Tester->ok(1, @_);
 
-        $RT::Handle = RT::Handle->new;
-        $RT::Handle->dbh( undef );
-        RT->ConnectToDatabase;
         # the attribute cache holds on to a stale dbh
         delete $RT::System->{attributes};
 
+        __reconnect_rt();
         return ("http://localhost:$port", RT::Test::Web->new);
     }
 
@@ -1405,10 +1392,9 @@ END {
     if ( $ENV{RT_TEST_PARALLEL} && $created_new_db ) {
 
         # Pg doesn't like if you issue a DROP DATABASE while still connected
-        my $dbh = $RT::Handle->dbh;
-        $dbh->disconnect if $dbh;
+        __disconnect_rt();
 
-        $dbh = _get_dbh( RT::Handle->SystemDSN, $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD} );
+        my $dbh = _get_dbh( RT::Handle->SystemDSN, $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD} );
         RT::Handle->DropDatabase( $dbh, Force => 1 );
         $dbh->disconnect;
     }

commit 86724f50eda221da619a0db2525ea6a418d175c5
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Jan 18 10:46:07 2011 +0300

    Ensure that database handles are not left open across calls to fork()
    
    This solves a problem wherein the previous live database handle was
    still connected during cleanup in the parent, causing Postgres to be
    unable to drop the database.

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index aaa2cdb..edb0700 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -1226,6 +1226,7 @@ sub start_plack_server {
              kill 'USR1' => getppid();
          });
 
+    __disconnect_rt();
     my $pid = fork();
     die "failed to fork" unless defined $pid;
 

commit 4523baff8adedc5e1aaac2d524340189716578f7
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Feb 16 22:35:35 2011 -0500

    Give Apache testing the same disconnect/reconnect across the fork treatment

diff --git a/lib/RT/Test/Apache.pm b/lib/RT/Test/Apache.pm
index ae40e4c..a822741 100644
--- a/lib/RT/Test/Apache.pm
+++ b/lib/RT/Test/Apache.pm
@@ -158,6 +158,7 @@ sub find_apache_server {
 sub fork_exec {
     my $self = shift;
 
+    RT::Test::__disconnect_rt();
     my $pid = fork;
     unless ( defined $pid ) {
         die "cannot fork: $!";
@@ -165,6 +166,7 @@ sub fork_exec {
         exec @_;
         die "can't exec `". join(' ', @_) ."` program: $!";
     } else {
+        RT::Test::__reconnect_rt();
         return $pid;
     }
 }

commit 17f20f4d7702c8995d6e254c6bb4ea5d9d3ad509
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 10 01:43:10 2011 +0300

    extract create and drop database private helpers

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index edb0700..a7bef23 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -367,19 +367,7 @@ sub bootstrap_db {
     }
 
     unless ($args{nodb}) {
-        # bootstrap with dba cred
-        my $dbh = _get_dbh(
-            RT::Handle->SystemDSN,
-            $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD}
-        );
-
-        unless ( $ENV{RT_TEST_PARALLEL} ) {
-            # already dropped db in parallel tests, need to do so for other cases.
-            RT::Handle->DropDatabase( $dbh, Force => 1 )
-        }
-        RT::Handle->CreateDatabase( $dbh );
-        $dbh->disconnect;
-        $created_new_db++;
+        __create_database();
 
         __reconnect_rt('dba');
         $RT::Handle->InsertSchema;
@@ -499,6 +487,39 @@ sub _get_dbh {
     return $dbh;
 }
 
+sub __create_database {
+    # bootstrap with dba cred
+    my $dbh = _get_dbh(
+        RT::Handle->SystemDSN,
+        $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD}
+    );
+
+    unless ( $ENV{RT_TEST_PARALLEL} ) {
+        # already dropped db in parallel tests, need to do so for other cases.
+        __drop_database( $dbh );
+
+    }
+    RT::Handle->CreateDatabase( $dbh );
+    $dbh->disconnect;
+    $created_new_db++;
+}
+
+sub __drop_database {
+    my $dbh = shift;
+
+    # Pg doesn't like if you issue a DROP DATABASE while still connected
+    # it's still may fail if web-server is out there and holding a connection
+    __disconnect_rt();
+
+    my $my_dbh = $dbh? 0 : 1;
+    $dbh ||= _get_dbh(
+        RT::Handle->SystemDSN,
+        $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD}
+    );
+    RT::Handle->DropDatabase( $dbh, Force => 1 );
+    $dbh->disconnect if $my_dbh;
+}
+
 sub __reconnect_rt {
     my $as_dba = shift;
     __disconnect_rt();
@@ -1391,13 +1412,7 @@ END {
     }
 
     if ( $ENV{RT_TEST_PARALLEL} && $created_new_db ) {
-
-        # Pg doesn't like if you issue a DROP DATABASE while still connected
-        __disconnect_rt();
-
-        my $dbh = _get_dbh( RT::Handle->SystemDSN, $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD} );
-        RT::Handle->DropDatabase( $dbh, Force => 1 );
-        $dbh->disconnect;
+        __drop_database();
     }
 }
 

commit 34450f9a075110d0168059f4e1545441838af72b
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 10 01:44:29 2011 +0300

    disconnect and clean every possible handle for sure

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index a7bef23..4867a0e 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -541,8 +541,11 @@ sub __disconnect_rt {
     # look at %DBIHandle and $PrevHandle in DBIx::SB::Handle for explanation
     return unless $RT::Handle;
     my $dbh = $RT::Handle->dbh;
-    $RT::Handle->dbh(undef);
     $dbh->disconnect if $dbh;
+
+    %DBIx::SearchBuilder::Handle::DBIHandle = ();
+    $DBIx::SearchBuilder::Handle::PrevHandle = undef;
+
     $RT::Handle = undef;
 }
 

commit 2552e8a4b54dba236c5aed38004818132b4ba467
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Sun Jan 30 20:06:10 2011 -0500

    Remove references to "Force" argument to DropDatabase, removed back in 141625a

diff --git a/lib/RT/Handle.pm b/lib/RT/Handle.pm
index 6f1118f..d55519e 100644
--- a/lib/RT/Handle.pm
+++ b/lib/RT/Handle.pm
@@ -350,15 +350,15 @@ sub CreateDatabase {
     return ($status, $DBI::errstr);
 }
 
-=head3 DropDatabase $DBH [Force => 0]
+=head3 DropDatabase $DBH
 
 Drops RT's database. This method can be used as class method.
 
 Takes DBI handle as first argument. Many database systems require
-special handle to allow you to create a new database, so you have
-to use L<SystemDSN> method during connection.
+a special handle to allow you to drop a database, so you may have
+to use L<SystemDSN> when acquiring the DBI handle.
 
-Fetches type and name of the DB from the config.
+Fetches the type and name of the database from the config.
 
 =cut
 
diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 4867a0e..fd7fee8 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -516,7 +516,7 @@ sub __drop_database {
         RT::Handle->SystemDSN,
         $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD}
     );
-    RT::Handle->DropDatabase( $dbh, Force => 1 );
+    RT::Handle->DropDatabase( $dbh );
     $dbh->disconnect if $my_dbh;
 }
 

commit e7ee68b10d52111c8658e3edb443e02764b78200
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Mon Jan 24 22:48:19 2011 -0500

    Only CREATE DATABASE in postgres once
    
    The second CREATE DATABASE line dates from RT 3.0.0; not only have all
    versions of Postgres since 7.1 had support for "WITH ENCODING" (and we
    require 8.1), but lack of Unicode at the database level would likely
    cause other, subtler, errors.

diff --git a/lib/RT/Handle.pm b/lib/RT/Handle.pm
index d55519e..89da3d7 100644
--- a/lib/RT/Handle.pm
+++ b/lib/RT/Handle.pm
@@ -341,8 +341,7 @@ sub CreateDatabase {
     elsif ( $db_type eq 'Pg' ) {
         # XXX: as we get external DBH we don't know if RaiseError or PrintError
         # are enabled, so we have to setup it here and restore them back
-        $status = $dbh->do("CREATE DATABASE $db_name WITH ENCODING='UNICODE' TEMPLATE template0")
-            || $dbh->do("CREATE DATABASE $db_name TEMPLATE template0");
+        $status = $dbh->do("CREATE DATABASE $db_name WITH ENCODING='UNICODE' TEMPLATE template0");
     }
     else {
         $status = $dbh->do("CREATE DATABASE $db_name");

commit 1df624dffe0c3ad75a882530094da2d05908919a
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Mon Jan 24 22:50:46 2011 -0500

    Remove an incorrect comment
    
    Not only is there no reason that this comment would apply only to
    Postgres, but all places which call CreateDatabase do so with a dbh
    explicitly set RaiseError => 0.

diff --git a/lib/RT/Handle.pm b/lib/RT/Handle.pm
index 89da3d7..0711d9c 100644
--- a/lib/RT/Handle.pm
+++ b/lib/RT/Handle.pm
@@ -339,8 +339,6 @@ sub CreateDatabase {
         return (1, "Created user $db_user. All RT's objects should be in his schema.");
     }
     elsif ( $db_type eq 'Pg' ) {
-        # XXX: as we get external DBH we don't know if RaiseError or PrintError
-        # are enabled, so we have to setup it here and restore them back
         $status = $dbh->do("CREATE DATABASE $db_name WITH ENCODING='UNICODE' TEMPLATE template0");
     }
     else {

commit f1d13b4b77b3d51362d50877f254e1313a558276
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Feb 16 22:29:37 2011 -0500

    Ensure that FlushCache is called on every disconnect

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index fd7fee8..d0a7a44 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -380,14 +380,11 @@ sub bootstrap_db {
         unless ($args{noinitialdata}) {
             __reconnect_rt();
             $RT::Handle->InsertInitialData;
-
-            DBIx::SearchBuilder::Record::Cachable->FlushCache;
         }
 
         unless ( $args{'nodata'} ) {
             __reconnect_rt();
             $RT::Handle->InsertData( $RT::EtcPath . "/initialdata" );
-            DBIx::SearchBuilder::Record::Cachable->FlushCache;
         }
     }
 }
@@ -547,6 +544,9 @@ sub __disconnect_rt {
     $DBIx::SearchBuilder::Handle::PrevHandle = undef;
 
     $RT::Handle = undef;
+
+    DBIx::SearchBuilder::Record::Cachable->FlushCache
+          if DBIx::SearchBuilder::Record::Cachable->can("FlushCache");
 }
 
 

commit 1477965de50dce7dba4c4a004cff0bcbb6aa6d40
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Feb 16 22:31:48 2011 -0500

    Ensure that the system attribute cache, which holds a DB handle, is cleared on every disconnect

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index d0a7a44..5685196 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -545,6 +545,8 @@ sub __disconnect_rt {
 
     $RT::Handle = undef;
 
+    delete $RT::System->{attributes};
+
     DBIx::SearchBuilder::Record::Cachable->FlushCache
           if DBIx::SearchBuilder::Record::Cachable->can("FlushCache");
 }
@@ -1266,9 +1268,6 @@ sub start_plack_server {
         my $Tester = Test::Builder->new;
         $Tester->ok(1, @_);
 
-        # the attribute cache holds on to a stale dbh
-        delete $RT::System->{attributes};
-
         __reconnect_rt();
         return ("http://localhost:$port", RT::Test::Web->new);
     }

commit 657a54c497de93805953d2680b799329ad658b1d
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Jan 13 02:55:22 2011 +0300

    bootstrap DB if we're testing a plugin that doesn't require any plugins

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 919f755..005c88f 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -380,19 +380,21 @@ sub bootstrap_plugins {
     my $self = shift;
     my %args = @_;
 
-    return unless $args{'requires'};
-
-    my @plugins = @{ $args{'requires'} };
+    my @plugins;
+    push @plugins, @{ $args{'requires'} }
+        if $args{'requires'};
     push @plugins, $args{'testing'}
         if $args{'testing'};
 
-    require RT::Plugin;
+    return unless @plugins;
+
     my $cwd;
     if ( $args{'testing'} ) {
         require Cwd;
         $cwd = Cwd::getcwd();
     }
 
+    require RT::Plugin;
     my $old_func = \&RT::Plugin::_BasePath;
     no warnings 'redefine';
     *RT::Plugin::_BasePath = sub {

commit 49c7b26300aab43b869b63ef31783f61be3b5879
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Feb 16 22:33:55 2011 -0500

    Don't bail early from __disconnect_rt, to ensure that we clear all handles

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 5685196..6b9419c 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -536,9 +536,7 @@ sub __reconnect_rt {
 
 sub __disconnect_rt {
     # look at %DBIHandle and $PrevHandle in DBIx::SB::Handle for explanation
-    return unless $RT::Handle;
-    my $dbh = $RT::Handle->dbh;
-    $dbh->disconnect if $dbh;
+    $RT::Handle->dbh->disconnect if $RT::Handle and $RT::Handle->dbh;
 
     %DBIx::SearchBuilder::Handle::DBIHandle = ();
     $DBIx::SearchBuilder::Handle::PrevHandle = undef;

commit a403984c93cab9faef02964fdc84364e88c8e874
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Jan 18 10:31:30 2011 +0300

    create plugins element in %args out of testing and requires

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 005c88f..bd65467 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -130,6 +130,11 @@ sub import {
         $class->builder->no_plan unless $class->builder->has_plan;
     }
 
+    push @{ $args{'plugins'} ||= [] }, @{ $args{'requires'} }
+        if $args{'requires'};
+    push @{ $args{'plugins'} ||= [] }, $args{'testing'}
+        if $args{'testing'};
+
     $class->bootstrap_tempdir;
 
     $class->bootstrap_config( %args );

commit d50dc1233e464ca48718a8831fb5988ff3fe9a93
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Feb 16 22:37:33 2011 -0500

    Simplify bootstrap_db() logic; this also reduces the number of reconnects

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 6b9419c..919f755 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -358,35 +358,22 @@ sub bootstrap_db {
         $args{$forceopt}=1;
     }
 
-    if ($args{nodb}) {
-        $args{noinitialdata} = 1;
-        $args{nodata} = 1;
-    }
-    elsif ($args{noinitialdata}) {
-        $args{nodata} = 1;
-    }
-
-    unless ($args{nodb}) {
-        __create_database();
-
-        __reconnect_rt('dba');
-        $RT::Handle->InsertSchema;
+    return if $args{nodb};
 
-        my $db_type = RT->Config->Get('DatabaseType');
-        $RT::Handle->InsertACL unless $db_type eq 'Oracle';
+    my $db_type = RT->Config->Get('DatabaseType');
+    __create_database();
+    __reconnect_rt('as dba');
+    $RT::Handle->InsertSchema;
+    $RT::Handle->InsertACL unless $db_type eq 'Oracle';
 
-        RT->InitLogging;
+    RT->InitLogging;
+    __reconnect_rt();
 
-        unless ($args{noinitialdata}) {
-            __reconnect_rt();
-            $RT::Handle->InsertInitialData;
-        }
+    $RT::Handle->InsertInitialData
+        unless $args{noinitialdata};
 
-        unless ( $args{'nodata'} ) {
-            __reconnect_rt();
-            $RT::Handle->InsertData( $RT::EtcPath . "/initialdata" );
-        }
-    }
+    $RT::Handle->InsertData( $RT::EtcPath . "/initialdata" )
+        unless $args{noinitialdata} or $args{nodata};
 }
 
 sub bootstrap_plugins {

commit 12db13fa39ffc0f08f817d42374a52e1345344dd
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Jan 18 10:32:20 2011 +0300

    put plugins into @Plugins when bootstraping config

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index bd65467..c04527f 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -246,6 +246,10 @@ Set( \$RTAddressRegexp , qr/^bad_re_that_doesnt_match\$/);
         print $config "Set( \$DatabaseUser , 'u${dbname}');\n";
     }
 
+    if ( $args{'plugins'} ) {
+        print $config "Set( \@Plugins, qw(". join( ' ', @{ $args{'plugins'} } ) .") );\n";
+    }
+
     if ( $INC{'Devel/Cover.pm'} ) {
         print $config "Set( \$DevelMode, 0 );\n";
     }

commit d308ca8606a69691f6381f3e75519fb6d8c39363
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Feb 16 23:08:55 2011 -0500

    Use the RT::Test methods to handle forced disconnection and reconnection

diff --git a/t/shredder/utils.pl b/t/shredder/utils.pl
index 34e6564..b8409bf 100644
--- a/t/shredder/utils.pl
+++ b/t/shredder/utils.pl
@@ -293,15 +293,9 @@ sub restore_savepoint { return __cp_db( savepoint_name( shift ) => db_name() ) }
 sub __cp_db
 {
     my( $orig, $dest ) = @_;
-    delete $RT::System->{attributes};
-    $RT::Handle->dbh->disconnect;
-    # DIRTY HACK: undef Handles to force reconnect
-    $RT::Handle = undef;
-    %DBIx::SearchBuilder::DBIHandle = ();
-    $DBIx::SearchBuilder::PrevHandle = undef;
-
+    RT::Test::__disconnect_rt();
     File::Copy::copy( $orig, $dest ) or die "Couldn't copy '$orig' => '$dest': $!";
-    RT::ConnectToDatabase();
+    RT::Test::__reconnect_rt();
     return;
 }
 

commit dbc3be4ee2b877725c516a39dc0eff435c63ac7d
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Jan 18 10:34:29 2011 +0300

    split bootstrap_plugins into *_paths and *_db functions

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index c04527f..b4470b6 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -385,17 +385,12 @@ sub bootstrap_db {
         unless $args{noinitialdata} or $args{nodata};
 }
 
-sub bootstrap_plugins {
+sub bootstrap_plugins_paths {
     my $self = shift;
     my %args = @_;
 
-    my @plugins;
-    push @plugins, @{ $args{'requires'} }
-        if $args{'requires'};
-    push @plugins, $args{'testing'}
-        if $args{'testing'};
-
-    return unless @plugins;
+    return unless $args{'plugins'};
+    my @plugins = @{ $args{'plugins'} };
 
     my $cwd;
     if ( $args{'testing'} ) {
@@ -418,9 +413,11 @@ sub bootstrap_plugins {
         }
         return $old_func->(@_);
     };
+}
 
-    RT->Config->Set( Plugins => @plugins );
-    RT->InitPluginPaths();
+sub bootstrap_plugins_db {
+    my $self = shift;
+    my %args = @_;
 
     my $dba_dbh;
     $dba_dbh = _get_dbh(

commit fd331c5ee0895c88d2c4defbc29e1240b4eb5a86
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Jan 18 10:35:47 2011 +0300

    refactor bootstrap plugin_db

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index b4470b6..26ce374 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -419,13 +419,11 @@ sub bootstrap_plugins_db {
     my $self = shift;
     my %args = @_;
 
-    my $dba_dbh;
-    $dba_dbh = _get_dbh(
-        RT::Handle->DSN,
-        $ENV{RT_DBA_USER}, $ENV{RT_DBA_PASSWORD},
-    ) if @plugins;
+    return unless $args{'plugins'};
 
     require File::Spec;
+
+    my @plugins = @{ $args{'plugins'} };
     foreach my $name ( @plugins ) {
         my $plugin = RT::Plugin->new( name => $name );
         Test::More::diag( "Initializing DB for the $name plugin" )
@@ -435,31 +433,37 @@ sub bootstrap_plugins_db {
         Test::More::diag( "etc path of the plugin is '$etc_path'" )
             if $ENV{'TEST_VERBOSE'};
 
-        if ( -e $etc_path ) {
-            my ($ret, $msg) = $RT::Handle->InsertSchema( $dba_dbh, $etc_path );
-            Test::More::ok($ret || $msg =~ /^Couldn't find schema/, "Created schema: ".($msg||''));
-
-            ($ret, $msg) = $RT::Handle->InsertACL( $dba_dbh, $etc_path );
-            Test::More::ok($ret || $msg =~ /^Couldn't find ACLs/, "Created ACL: ".($msg||''));
-
-            my $data_file = File::Spec->catfile( $etc_path, 'initialdata' );
-            if ( -e $data_file ) {
-                ($ret, $msg) = $RT::Handle->InsertData( $data_file );;
-                Test::More::ok($ret, "Inserted data".($msg||''));
-            } else {
-                Test::More::ok(1, "There is no data file" );
-            }
-        }
-        else {
+        unless ( -e $etc_path ) {
 # we can not say if plugin has no data or we screwed with etc path
             Test::More::ok(1, "There is no etc dir: no schema" );
             Test::More::ok(1, "There is no etc dir: no ACLs" );
             Test::More::ok(1, "There is no etc dir: no data" );
+            next;
+        }
+
+
+        { # schema
+            __reconnect_rt('dba');
+            my ($ret, $msg) = $RT::Handle->InsertSchema( undef, $etc_path );
+            Test::More::ok($ret || $msg =~ /^Couldn't find schema/, "Created schema: ".($msg||''));
         }
 
-        $RT::Handle->Connect; # XXX: strange but mysql can loose connection
+        { # ACLs
+            __reconnect_rt('dba');
+            my ($ret, $msg) = $RT::Handle->InsertACL( undef, $etc_path );
+            Test::More::ok($ret || $msg =~ /^Couldn't find ACLs/, "Created ACL: ".($msg||''));
+        }
+
+        # data
+        my $data_file = File::Spec->catfile( $etc_path, 'initialdata' );
+        if ( -e $data_file ) {
+            __reconnect_rt();
+            my ($ret, $msg) = $RT::Handle->InsertData( $data_file );;
+            Test::More::ok($ret, "Inserted data".($msg||''));
+        } else {
+            Test::More::ok(1, "There is no data file" );
+        }
     }
-    $dba_dbh->disconnect if $dba_dbh;
 }
 
 sub _get_dbh {

commit d8525aec55bf2ae9f5bca618f48843c1de924650
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Jan 18 10:37:18 2011 +0300

    reorder how we bootstrap plugins
    
    bootstrap paths asap
    
    set @Plugins in the config, so plugins' configs are loaded
    
    setup plugins' DB right after setting RT's DB

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 26ce374..5b4a100 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -137,6 +137,8 @@ sub import {
 
     $class->bootstrap_tempdir;
 
+    $class->bootstrap_plugins_paths( %args );
+
     $class->bootstrap_config( %args );
 
     use RT;
@@ -154,10 +156,8 @@ sub import {
     RT::InitClasses();
     RT::InitLogging();
 
-    $class->bootstrap_plugins( %args );
-
     RT->Plugins;
-    
+
     RT::I18N->Init();
     RT->Config->PostLoadCheck;
 
@@ -383,6 +383,9 @@ sub bootstrap_db {
 
     $RT::Handle->InsertData( $RT::EtcPath . "/initialdata" )
         unless $args{noinitialdata} or $args{nodata};
+
+    $self->bootstrap_plugins_db( %args );
+    __reconnect_rt();
 }
 
 sub bootstrap_plugins_paths {

commit cfcc4e864f5950d486cc92aae3e62e8aed455c30
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 10 01:47:04 2011 +0300

    minor, use less reconnections

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 5b4a100..00c254e 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -444,15 +444,14 @@ sub bootstrap_plugins_db {
             next;
         }
 
+        __reconnect_rt('as dba');
 
         { # schema
-            __reconnect_rt('dba');
             my ($ret, $msg) = $RT::Handle->InsertSchema( undef, $etc_path );
             Test::More::ok($ret || $msg =~ /^Couldn't find schema/, "Created schema: ".($msg||''));
         }
 
         { # ACLs
-            __reconnect_rt('dba');
             my ($ret, $msg) = $RT::Handle->InsertACL( undef, $etc_path );
             Test::More::ok($ret || $msg =~ /^Couldn't find ACLs/, "Created ACL: ".($msg||''));
         }

commit 67d0e3383ff17dd75fcdaef223eca457afac4e44
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Feb 16 22:23:49 2011 -0500

    Move reconnect for plugins to only fire if there are plugins enabled

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 00c254e..27d8ee0 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -385,7 +385,6 @@ sub bootstrap_db {
         unless $args{noinitialdata} or $args{nodata};
 
     $self->bootstrap_plugins_db( %args );
-    __reconnect_rt();
 }
 
 sub bootstrap_plugins_paths {
@@ -466,6 +465,7 @@ sub bootstrap_plugins_db {
             Test::More::ok(1, "There is no data file" );
         }
     }
+    __reconnect_rt();
 }
 
 sub _get_dbh {

commit d18f44f8b478172a1d2c955da15fffe123545dc5
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Wed Feb 16 23:13:39 2011 -0500

    Indent and reword a minor comment

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 27d8ee0..3fe6945 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -436,7 +436,7 @@ sub bootstrap_plugins_db {
             if $ENV{'TEST_VERBOSE'};
 
         unless ( -e $etc_path ) {
-# we can not say if plugin has no data or we screwed with etc path
+            # We can't tell if the plugin has no data, or we screwed up the etc/ path
             Test::More::ok(1, "There is no etc dir: no schema" );
             Test::More::ok(1, "There is no etc dir: no ACLs" );
             Test::More::ok(1, "There is no etc dir: no data" );

commit b3aff1dee707578d50c3a6e0295805d6be85aff5
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Wed Mar 2 21:49:00 2011 -0500

    Add a hook for validating Web* config against %ENV once per server process

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index bd5b1fb..39bbdc1 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -208,6 +208,8 @@ sub HandleRequest {
     $HTML::Mason::Commands::m->autoflush( $HTML::Mason::Commands::m->request_comp->attr('AutoFlush') )
         if ( $HTML::Mason::Commands::m->request_comp->attr_exists('AutoFlush') );
 
+    ValidateWebConfig();
+
     DecodeARGS($ARGS);
     PreprocessTimeUpdates($ARGS);
 
@@ -1003,6 +1005,16 @@ sub LogRecordedSQLStatements {
 
 }
 
+my $_has_validated_web_config = 0;
+sub ValidateWebConfig {
+    my $self = shift;
+
+    # do this once per server instance, not once per request
+    return if $_has_validated_web_config;
+    $_has_validated_web_config = 1;
+
+}
+
 package HTML::Mason::Commands;
 
 use vars qw/$r $m %session/;

commit b3fc9c44065c675c224a612fdfab808d034e9962
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Mar 3 01:18:19 2011 -0500

    Complain when $SERVER_PORT != WebPort

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 39bbdc1..559bf21 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1013,6 +1013,9 @@ sub ValidateWebConfig {
     return if $_has_validated_web_config;
     $_has_validated_web_config = 1;
 
+    if ($ENV{SERVER_PORT} != RT->Config->Get('WebPort')) {
+        $RT::Logger->warn("The \$SERVER_PORT environment variable ($ENV{SERVER_PORT}) from a web request does NOT match the configured WebPort ($RT::WebPort)");
+    }
 }
 
 package HTML::Mason::Commands;

commit accd61356beaba2d8783a5d53efd5566b5b88f74
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Mar 3 01:35:58 2011 -0500

    Complain about WebDomain too

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 559bf21..fe484f5 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1014,7 +1014,11 @@ sub ValidateWebConfig {
     $_has_validated_web_config = 1;
 
     if ($ENV{SERVER_PORT} != RT->Config->Get('WebPort')) {
-        $RT::Logger->warn("The \$SERVER_PORT environment variable ($ENV{SERVER_PORT}) from a web request does NOT match the configured WebPort ($RT::WebPort)");
+        $RT::Logger->warn("The SERVER_PORT environment variable ($ENV{SERVER_PORT}) from a web request does NOT match the configured WebPort ($RT::WebPort)");
+    }
+
+    if ($ENV{SERVER_NAME} ne RT->Config->Get('WebDomain')) {
+        $RT::Logger->warn("The SERVER_NAME environment variable ($ENV{SERVER_PORT}) from a web request does NOT match the configured WebDomain ($RT::WebDomain)");
     }
 }
 

commit 6442feddcc84987e8b35e00f78b53996ef7590da
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Mar 3 01:40:59 2011 -0500

    Complain about a bad WebPath

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index fe484f5..7a1b5cc 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1020,6 +1020,10 @@ sub ValidateWebConfig {
     if ($ENV{SERVER_NAME} ne RT->Config->Get('WebDomain')) {
         $RT::Logger->warn("The SERVER_NAME environment variable ($ENV{SERVER_PORT}) from a web request does NOT match the configured WebDomain ($RT::WebDomain)");
     }
+
+    if ($ENV{PATH_INFO} !~ /^\Q$RT::WebPath\E/) {
+        $RT::Logger->warn("A requested path ($ENV{PATH_INFO}) does NOT fall within the configured WebPath ($RT::WebPath)");
+    }
 }
 
 package HTML::Mason::Commands;

commit 8c07aaac4bbb832493506c8d351cd25244ba405e
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Mar 3 01:41:19 2011 -0500

    No nee to specify "from a web request"

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 7a1b5cc..14962c3 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1014,11 +1014,11 @@ sub ValidateWebConfig {
     $_has_validated_web_config = 1;
 
     if ($ENV{SERVER_PORT} != RT->Config->Get('WebPort')) {
-        $RT::Logger->warn("The SERVER_PORT environment variable ($ENV{SERVER_PORT}) from a web request does NOT match the configured WebPort ($RT::WebPort)");
+        $RT::Logger->warn("The SERVER_PORT environment variable ($ENV{SERVER_PORT}) does NOT match the configured WebPort ($RT::WebPort)");
     }
 
     if ($ENV{SERVER_NAME} ne RT->Config->Get('WebDomain')) {
-        $RT::Logger->warn("The SERVER_NAME environment variable ($ENV{SERVER_PORT}) from a web request does NOT match the configured WebDomain ($RT::WebDomain)");
+        $RT::Logger->warn("The SERVER_NAME environment variable ($ENV{SERVER_PORT}) does NOT match the configured WebDomain ($RT::WebDomain)");
     }
 
     if ($ENV{PATH_INFO} !~ /^\Q$RT::WebPath\E/) {

commit 9a21d6831ca5319f10596b8b14194d881167bca5
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Mar 3 01:41:49 2011 -0500

    Fix log message to use the right variable

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 14962c3..b8985d5 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1018,7 +1018,7 @@ sub ValidateWebConfig {
     }
 
     if ($ENV{SERVER_NAME} ne RT->Config->Get('WebDomain')) {
-        $RT::Logger->warn("The SERVER_NAME environment variable ($ENV{SERVER_PORT}) does NOT match the configured WebDomain ($RT::WebDomain)");
+        $RT::Logger->warn("The SERVER_NAME environment variable ($ENV{SERVER_NAME}) does NOT match the configured WebDomain ($RT::WebDomain)");
     }
 
     if ($ENV{PATH_INFO} !~ /^\Q$RT::WebPath\E/) {

commit d90da0291be55147ba7e081d5b650916eba7203d
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Mar 3 01:46:58 2011 -0500

    PSGI spec says prefer HTTP_HOST over SERVER_NAME
    
        Unfortunately it's not that trivial since HTTP_HOST likes including the
        port

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index b8985d5..e3cbf2f 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1014,11 +1014,21 @@ sub ValidateWebConfig {
     $_has_validated_web_config = 1;
 
     if ($ENV{SERVER_PORT} != RT->Config->Get('WebPort')) {
-        $RT::Logger->warn("The SERVER_PORT environment variable ($ENV{SERVER_PORT}) does NOT match the configured WebPort ($RT::WebPort)");
+        $RT::Logger->warn("The actual SERVER_PORT ($ENV{SERVER_PORT}) does NOT match the configured WebPort ($RT::WebPort)");
     }
 
-    if ($ENV{SERVER_NAME} ne RT->Config->Get('WebDomain')) {
-        $RT::Logger->warn("The SERVER_NAME environment variable ($ENV{SERVER_NAME}) does NOT match the configured WebDomain ($RT::WebDomain)");
+    if ($ENV{HTTP_HOST}) {
+        # match "example.com" or "example.com:80"
+        my ($host) = $ENV{HTTP_HOST} =~ /^(.*?)(:\d+)?$/;
+
+        if ($host ne RT->Config->Get('WebDomain')) {
+            $RT::Logger->warn("The actual HTTP_HOST ($host) does NOT match the configured WebDomain ($RT::WebDomain)");
+        }
+    }
+    else {
+        if ($ENV{SERVER_NAME} ne RT->Config->Get('WebDomain')) {
+            $RT::Logger->warn("The actual SERVER_NAME ($ENV{SERVER_NAME}) does NOT match the configured WebDomain ($RT::WebDomain)");
+        }
     }
 
     if ($ENV{PATH_INFO} !~ /^\Q$RT::WebPath\E/) {

commit c800c1498b983994a64c262229a321f282143f30
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Mar 3 02:05:21 2011 -0500

    "making the error message suggest a direction to fix might be good"

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index e3cbf2f..769217d 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1014,7 +1014,7 @@ sub ValidateWebConfig {
     $_has_validated_web_config = 1;
 
     if ($ENV{SERVER_PORT} != RT->Config->Get('WebPort')) {
-        $RT::Logger->warn("The actual SERVER_PORT ($ENV{SERVER_PORT}) does NOT match the configured WebPort ($RT::WebPort)");
+        $RT::Logger->warn("The actual SERVER_PORT ($ENV{SERVER_PORT}) does NOT match the configured WebPort ($RT::WebPort). Perhaps you should Set(\$WebPort, $ENV{SERVER_PORT}) in RT_SiteConfig.pm, otherwise your internal links may be broken.");
     }
 
     if ($ENV{HTTP_HOST}) {
@@ -1022,17 +1022,17 @@ sub ValidateWebConfig {
         my ($host) = $ENV{HTTP_HOST} =~ /^(.*?)(:\d+)?$/;
 
         if ($host ne RT->Config->Get('WebDomain')) {
-            $RT::Logger->warn("The actual HTTP_HOST ($host) does NOT match the configured WebDomain ($RT::WebDomain)");
+            $RT::Logger->warn("The actual HTTP_HOST ($host) does NOT match the configured WebDomain ($RT::WebDomain). Perhaps you should Set(\$WebDomain, '$host') in RT_SiteConfig.pm, otherwise your internal links may be broken.");
         }
     }
     else {
         if ($ENV{SERVER_NAME} ne RT->Config->Get('WebDomain')) {
-            $RT::Logger->warn("The actual SERVER_NAME ($ENV{SERVER_NAME}) does NOT match the configured WebDomain ($RT::WebDomain)");
+            $RT::Logger->warn("The actual SERVER_NAME ($ENV{SERVER_NAME}) does NOT match the configured WebDomain ($RT::WebDomain). Perhaps you should Set(\$WebDomain, '$host') in RT_SiteConfig.pm, otherwise your internal links may be broken.");
         }
     }
 
     if ($ENV{PATH_INFO} !~ /^\Q$RT::WebPath\E/) {
-        $RT::Logger->warn("A requested path ($ENV{PATH_INFO}) does NOT fall within the configured WebPath ($RT::WebPath)");
+        $RT::Logger->warn("A requested path ($ENV{PATH_INFO}) does NOT fall within the configured WebPath ($RT::WebPath). You should fix your Set(\$WebPath, ...) setting in RT_SiteConfig.pm otherwise your internal links may be broken.");
     }
 }
 

commit 07ee408ad96bd427ecb0bbcdade82ce7e3bb43d7
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Mar 3 02:14:54 2011 -0500

    We don't use $host in this branch

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 769217d..fafd2e9 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1027,7 +1027,7 @@ sub ValidateWebConfig {
     }
     else {
         if ($ENV{SERVER_NAME} ne RT->Config->Get('WebDomain')) {
-            $RT::Logger->warn("The actual SERVER_NAME ($ENV{SERVER_NAME}) does NOT match the configured WebDomain ($RT::WebDomain). Perhaps you should Set(\$WebDomain, '$host') in RT_SiteConfig.pm, otherwise your internal links may be broken.");
+            $RT::Logger->warn("The actual SERVER_NAME ($ENV{SERVER_NAME}) does NOT match the configured WebDomain ($RT::WebDomain). Perhaps you should Set(\$WebDomain, '$ENV{SERVER_NAME}') in RT_SiteConfig.pm, otherwise your internal links may be broken.");
         }
     }
 

commit a1f2fef4ffb0ae40efacc4cdb7c1ba8cee31cdad
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Thu Mar 3 16:53:52 2011 -0500

    Cope with rt-server --port by putting rt.port into %ENV

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index fafd2e9..82c153f 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1013,8 +1013,15 @@ sub ValidateWebConfig {
     return if $_has_validated_web_config;
     $_has_validated_web_config = 1;
 
-    if ($ENV{SERVER_PORT} != RT->Config->Get('WebPort')) {
-        $RT::Logger->warn("The actual SERVER_PORT ($ENV{SERVER_PORT}) does NOT match the configured WebPort ($RT::WebPort). Perhaps you should Set(\$WebPort, $ENV{SERVER_PORT}) in RT_SiteConfig.pm, otherwise your internal links may be broken.");
+    if ($ENV{'rt.port'}) {
+        if ($ENV{SERVER_PORT} != $ENV{'rt.port'}) {
+            $RT::Logger->warn("The actual SERVER_PORT ($ENV{SERVER_PORT}) does NOT match the requested port ($ENV{'rt.port'}). Perhaps you should Set(\$WebPort, $ENV{SERVER_PORT}) in RT_SiteConfig.pm, otherwise your internal links may be broken.");
+        }
+    }
+    else {
+        if ($ENV{SERVER_PORT} != RT->Config->Get('WebPort')) {
+            $RT::Logger->warn("The actual SERVER_PORT ($ENV{SERVER_PORT}) does NOT match the configured WebPort ($RT::WebPort). Perhaps you should Set(\$WebPort, $ENV{SERVER_PORT}) in RT_SiteConfig.pm, otherwise your internal links may be broken.");
+        }
     }
 
     if ($ENV{HTTP_HOST}) {
diff --git a/sbin/rt-server.in b/sbin/rt-server.in
index 8b19c22..7cd565c 100755
--- a/sbin/rt-server.in
+++ b/sbin/rt-server.in
@@ -185,6 +185,16 @@ else {
     push @args, '--port', $port;
 }
 
+# inform the rest of the system what port we're using
+my $old_app = $app;
+$app = sub {
+    my $env = shift;
+
+    $env->{'rt.port'} = $port;
+
+    $old_app->($env, @_);
+};
+
 push @args, '--server', 'Standalone' if RT->InstallMode;
 push @args, '--server', 'Starlet' unless $r->{server} || grep { m/--server/ } @args;
 

commit 8c6ce9794fb3cc7959e901faef13794c00b6eaf7
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Fri Mar 4 18:21:27 2011 -0500

    Clean up and simplify rt-server's --port configuration

diff --git a/sbin/rt-server.in b/sbin/rt-server.in
index 7cd565c..f5b47a6 100755
--- a/sbin/rt-server.in
+++ b/sbin/rt-server.in
@@ -162,10 +162,6 @@ unless ($0 eq __FILE__) {
 
 # load appropriate server
 
-my $explicit_port = $ARGV[0] && $ARGV[0] !~ m/-/ ? shift @ARGV : undef;
-warn "Deprecated: please run $0 --port $explicit_port instead".$/ if $explicit_port;
-my $port = $explicit_port || RT->Config->Get('WebPort') || '8080';
-
 require Plack::Runner;
 
 my $is_fastcgi = $0 =~ m/fcgi$/;
@@ -173,28 +169,43 @@ my $r = Plack::Runner->new( $0 =~ 'standalone' ? ( server => 'Standalone' ) :
                             $is_fastcgi        ? ( server => 'FCGI' )
                                                : (),
                             env => 'deployment' );
+
+# figure out the port
+my $port;
+
+# handle "rt-server 8888" for back-compat, but complain about it
+if ($ARGV[0] && $ARGV[0] =~ m/^\d+$/) {
+    warn "Deprecated: please run $0 --port $ARGV[0] instead\n";
+    unshift @ARGV, '--port';
+}
+
 my @args = @ARGV;
 
 use List::MoreUtils 'last_index';
-my $last_index = last_index { $_ eq '--port' } @args; 
+my $last_index = last_index { $_ eq '--port' } @args;
+
+my $explicit_port;
 
 if ( $last_index != -1 && $args[$last_index+1] =~ /^\d+$/ ) {
-    $port = $args[$last_index+1];
+    $explicit_port = $args[$last_index+1];
+    $port = $explicit_port;
+
+    # inform the rest of the system what port we manually chose
+    my $old_app = $app;
+    $app = sub {
+        my $env = shift;
+
+        $env->{'rt.port'} = $port;
+
+        $old_app->($env, @_);
+    };
 }
 else {
+    # default to the configured WebPort and inform Plack::Runner
+    $port = RT->Config->Get('WebPort') || '8080';
     push @args, '--port', $port;
 }
 
-# inform the rest of the system what port we're using
-my $old_app = $app;
-$app = sub {
-    my $env = shift;
-
-    $env->{'rt.port'} = $port;
-
-    $old_app->($env, @_);
-};
-
 push @args, '--server', 'Standalone' if RT->InstallMode;
 push @args, '--server', 'Starlet' unless $r->{server} || grep { m/--server/ } @args;
 

commit 8ac8c928cdc1bb940617b1f9f7dda1b694b0fb4d
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Fri Mar 4 18:22:16 2011 -0500

    Call the %ENV key rt.explicit_port instead of rt.port

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 82c153f..0f14341 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1013,9 +1013,9 @@ sub ValidateWebConfig {
     return if $_has_validated_web_config;
     $_has_validated_web_config = 1;
 
-    if ($ENV{'rt.port'}) {
-        if ($ENV{SERVER_PORT} != $ENV{'rt.port'}) {
-            $RT::Logger->warn("The actual SERVER_PORT ($ENV{SERVER_PORT}) does NOT match the requested port ($ENV{'rt.port'}). Perhaps you should Set(\$WebPort, $ENV{SERVER_PORT}) in RT_SiteConfig.pm, otherwise your internal links may be broken.");
+    if ($ENV{'rt.explicit_port'}) {
+        if ($ENV{SERVER_PORT} != $ENV{'rt.explicit_port'}) {
+            $RT::Logger->warn("The actual SERVER_PORT ($ENV{SERVER_PORT}) does NOT match the requested port ($ENV{'rt.explicit_port'}). Perhaps you should Set(\$WebPort, $ENV{SERVER_PORT}) in RT_SiteConfig.pm, otherwise your internal links may be broken.");
         }
     }
     else {
diff --git a/sbin/rt-server.in b/sbin/rt-server.in
index f5b47a6..75cb012 100755
--- a/sbin/rt-server.in
+++ b/sbin/rt-server.in
@@ -195,7 +195,7 @@ if ( $last_index != -1 && $args[$last_index+1] =~ /^\d+$/ ) {
     $app = sub {
         my $env = shift;
 
-        $env->{'rt.port'} = $port;
+        $env->{'rt.explicit_port'} = $port;
 
         $old_app->($env, @_);
     };

commit 2ff6caa73798ed55de2e2dc154bc3c790906dc8e
Merge: 01b8939 d308ca8
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Mon Mar 7 14:42:08 2011 -0500

    Merge branch '4.0/database-init-in-tests' into 4.0-trunk
    
    Conflicts:
    	lib/RT/Test.pm

diff --cc lib/RT/Test.pm
index 9375d58,919f755..5b3753a
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@@ -1213,12 -1237,7 +1242,13 @@@ sub start_plack_server 
               kill 'USR1' => getppid();
           });
  
 +    # We are expecting a USR1 from the child process after it's ready
 +    # to listen.  We set this up _before_ we fork to avoid race
 +    # conditions.
 +    my $handled;
 +    local $SIG{USR1} = sub { $handled = 1};
 +
+     __disconnect_rt();
      my $pid = fork();
      die "failed to fork" unless defined $pid;
  

commit 552191ec55d0387e5dde646397b10c609701ac1d
Merge: 2ff6caa d18f44f
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Mon Mar 7 14:42:27 2011 -0500

    Merge branch '4.0/plugin-database-init' into 4.0-trunk


commit 511e2d4d278bf2be2bd30b461eb84cdd2287849b
Merge: 552191e 8ac8c92
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Mon Mar 7 14:44:40 2011 -0500

    Merge branch '4.0/sanity-check-url-config' into 4.0-trunk
    
    Conflicts:
    	lib/RT/Config.pm

diff --cc lib/RT/Config.pm
index 06e411d,c38931b..9bfe80d
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@@ -536,34 -536,115 +536,143 @@@ our %META = 
                                'You can change the site default in your %Lifecycles config.');
          }
      },
+     WebPath => {
+         PostLoadCheck => sub {
+             my $self  = shift;
+             my $value = shift;
+ 
+             # "In most cases, you should leave $WebPath set to '' (an empty value)."
+             return unless $value;
+ 
+             # try to catch someone who assumes that you shouldn't leave this empty
+             if ($value eq '/') {
+                 $RT::Logger->error("For the WebPath config option, use the empty string instead of /");
+                 return;
+             }
+ 
+             # $WebPath requires a leading / but no trailing /, or it can be blank.
+             return if $value =~ m{^/.+[^/]$};
+ 
+             if ($value =~ m{/$}) {
+                 $RT::Logger->error("The WebPath config option requires no trailing slash");
+             }
+ 
+             if ($value !~ m{^/}) {
+                 $RT::Logger->error("The WebPath config option requires a leading slash");
+             }
+         },
+     },
+     WebDomain => {
+         PostLoadCheck => sub {
+             my $self  = shift;
+             my $value = shift;
+ 
+             if (!$value) {
+                 $RT::Logger->error("You must set the WebDomain config option");
+                 return;
+             }
+ 
+             if ($value =~ m{^(\w+://)}) {
+                 $RT::Logger->error("The WebDomain config option must not contain a scheme ($1)");
+                 return;
+             }
+ 
+             if ($value =~ m{(/.*)}) {
+                 $RT::Logger->error("The WebDomain config option must not contain a path ($1)");
+                 return;
+             }
+ 
+             if ($value =~ m{:(\d*)}) {
+                 $RT::Logger->error("The WebDomain config option must not contain a port ($1)");
+                 return;
+             }
+         },
+     },
+     WebPort => {
+         PostLoadCheck => sub {
+             my $self  = shift;
+             my $value = shift;
+ 
+             if (!$value) {
+                 $RT::Logger->error("You must set the WebPort config option");
+                 return;
+             }
+ 
+             if ($value !~ m{^\d+$}) {
+                 $RT::Logger->error("The WebPort config option must be an integer");
+             }
+         },
+     },
+     WebBaseURL => {
+         PostLoadCheck => sub {
+             my $self  = shift;
+             my $value = shift;
+ 
+             if (!$value) {
+                 $RT::Logger->error("You must set the WebBaseURL config option");
+                 return;
+             }
+ 
+             if ($value !~ m{^https?://}i) {
+                 $RT::Logger->error("The WebBaseURL config option must contain a scheme (http or https)");
+             }
+ 
+             if ($value =~ m{/$}) {
+                 $RT::Logger->error("The WebBaseURL config option requires no trailing slash");
+             }
+ 
+             if ($value =~ m{^https?://.+?(/[^/].*)}i) {
+                 $RT::Logger->error("The WebBaseURL config option must not contain a path ($1)");
+             }
+         },
+     },
+     WebURL => {
+         PostLoadCheck => sub {
+             my $self  = shift;
+             my $value = shift;
+ 
+             if (!$value) {
+                 $RT::Logger->error("You must set the WebURL config option");
+                 return;
+             }
+ 
+             if ($value !~ m{^https?://}i) {
+                 $RT::Logger->error("The WebURL config option must contain a scheme (http or https)");
+             }
+ 
+             if ($value !~ m{/$}) {
+                 $RT::Logger->error("The WebURL config option requires a trailing slash");
+             }
+         },
+     },
 +    EmailInputEncodings => {
 +        Type => 'ARRAY',
 +        PostLoadCheck => sub {
 +            my $self  = shift;
 +            my $value = $self->Get('EmailInputEncodings');
 +            return unless $value && @$value;
 +
 +            my %seen;
 +            foreach my $encoding ( grep defined && length, splice @$value ) {
 +                next if $seen{ $encoding }++;
 +                if ( $encoding eq '*' ) {
 +                    unshift @$value, '*';
 +                    next;
 +                }
 +
 +                my $canonic = Encode::resolve_alias( $encoding );
 +                unless ( $canonic ) {
 +                    warn "Unknown encoding '$encoding' in \@EmailInputEncodings option";
 +                }
 +                elsif ( $seen{ $canonic }++ ) {
 +                    next;
 +                }
 +                else {
 +                    push @$value, $canonic;
 +                }
 +            }
 +        },
-     }
++    },
  );
  my %OPTIONS = ();
  

-----------------------------------------------------------------------


More information about the Rt-commit mailing list