=== modified file 'src/client_side_request.cc'
--- src/client_side_request.cc	2011-05-19 12:02:58 +0000
+++ src/client_side_request.cc	2011-05-19 12:50:57 +0000
@@ -1016,7 +1016,6 @@
 void
 ClientRequestContext::clientRedirectDone(char *result)
 {
-    HttpRequest *new_request = NULL;
     HttpRequest *old_request = http->request;
     debugs(85, 5, "clientRedirectDone: '" << http->uri << "' result=" << (result ? result : "NULL"));
     assert(redirect_state == REDIRECT_PENDING);
@@ -1042,41 +1041,33 @@
                     debugs(85, DBG_CRITICAL, "ERROR: URL-rewrite produces invalid 303 redirect Location: " << result);
             }
         } else if (strcmp(result, http->uri)) {
-            if (!(new_request = HttpRequest::CreateFromUrlAndMethod(result, old_request->method)))
+            // XXX: validate the URL properly *without* generating a whole new request object right here.
+            // XXX: the clone() should be done only AFTER we know the new URL is valid.
+            HttpRequest *new_request = old_request->clone();
+            if (!(new_request = urlParse(old_request->method, result, new_request))) {
                 debugs(85, DBG_CRITICAL, "ERROR: URL-rewrite produces invalid request: " <<
                        old_request->method << " " << result << " HTTP/1.1");
-        }
-    }
-
-    if (new_request) {
-        safe_free(http->uri);
-        http->uri = xstrdup(urlCanonical(new_request));
-        new_request->http_ver = old_request->http_ver;
-        new_request->header.append(&old_request->header);
-        new_request->client_addr = old_request->client_addr;
-#if FOLLOW_X_FORWARDED_FOR
-        new_request->indirect_client_addr = old_request->indirect_client_addr;
-#endif /* FOLLOW_X_FORWARDED_FOR */
-        new_request->my_addr = old_request->my_addr;
-        new_request->clientConnectionManager = old_request->clientConnectionManager;
-        new_request->flags = old_request->flags;
-        new_request->flags.redirected = 1;
-#if USE_AUTH
-        new_request->auth_user_request = old_request->auth_user_request;
-#endif
-        if (old_request->body_pipe != NULL) {
-            new_request->body_pipe = old_request->body_pipe;
-            old_request->body_pipe = NULL;
-            debugs(61,2, HERE << "URL-rewriter diverts body_pipe " << new_request->body_pipe <<
-                   " from request " << old_request << " to " << new_request);
-        }
-
-        new_request->content_length = old_request->content_length;
-        new_request->extacl_user = old_request->extacl_user;
-        new_request->extacl_passwd = old_request->extacl_passwd;
-        new_request->flags.proxy_keepalive = old_request->flags.proxy_keepalive;
-        HTTPMSGUNLOCK(old_request);
-        http->request = HTTPMSGLOCK(new_request);
+                delete new_request;
+            } else {
+                debugs(61,2, HERE << "URL-rewriter diverts URL from " << urlCanonical(old_request) << " to " << urlCanonical(new_request));
+
+                // update the new request to flag the re-writing was done on it
+                new_request->flags.redirected = 1;
+
+                // unlink bodypipe from the old request. Not needed there any longer.
+                if (old_request->body_pipe != NULL) {
+                    old_request->body_pipe = NULL;
+                    debugs(61,2, HERE << "URL-rewriter diverts body_pipe " << new_request->body_pipe <<
+                           " from request " << old_request << " to " << new_request);
+                }
+
+                // update the current working ClientHttpRequest fields
+                safe_free(http->uri);
+                http->uri = xstrdup(urlCanonical(new_request));
+                HTTPMSGUNLOCK(old_request);
+                http->request = HTTPMSGLOCK(new_request);
+            }
+        }
     }
 
     /* FIXME PIPELINE: This is innacurate during pipelining */

=== modified file 'src/url.cc'
--- src/url.cc	2011-04-10 02:00:38 +0000
+++ src/url.cc	2011-05-19 13:22:43 +0000
@@ -46,7 +46,7 @@
                                    const char *const login,
                                    const int port,
                                    HttpRequest *request);
-static HttpRequest *urnParse(const HttpRequestMethod& method, char *urn);
+static HttpRequest *urnParse(const HttpRequestMethod& method, char *urn, HttpRequest *request);
 static const char valid_hostname_chars_u[] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "abcdefghijklmnopqrstuvwxyz"
@@ -236,7 +236,7 @@
         port = urlDefaultPort(protocol);
         return urlParseFinish(method, protocol, url, host, login, port, request);
     } else if (!strncmp(url, "urn:", 4)) {
-        return urnParse(method, url);
+        return urnParse(method, url, request);
     } else {
         /* Parse the URL: */
         src = url;
@@ -442,6 +442,7 @@
         request = new HttpRequest(method, protocol, urlpath);
     else {
         request->initHTTP(method, protocol, urlpath);
+        safe_free(request->canonical);
     }
 
     request->SetHost(host);
@@ -451,9 +452,15 @@
 }
 
 static HttpRequest *
-urnParse(const HttpRequestMethod& method, char *urn)
+urnParse(const HttpRequestMethod& method, char *urn, HttpRequest *request)
 {
     debugs(50, 5, "urnParse: " << urn);
+    if (request) {
+        request->initHTTP(method, AnyP::PROTO_URN, urn + 4);
+        safe_free(request->canonical);
+        return request;
+    }
+
     return new HttpRequest(method, AnyP::PROTO_URN, urn + 4);
 }
 


