Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.867
diff -u -r1.867 common.inc
--- includes/common.inc	13 Feb 2009 04:43:00 -0000	1.867
+++ includes/common.inc	18 Feb 2009 06:46:54 -0000
@@ -323,7 +323,28 @@
  * @see drupal_get_destination()
  */
 function drupal_goto($path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) {
+  $url = drupal_get_goto_url($path, $query, $fragment);
+  drupal_goto_finalize($url);
+  header('Location: ' . $url, TRUE, $http_response_code);
+
+  // The "Location" header sends a redirect status code to the HTTP daemon. In
+  // some cases this can be wrong, so we make sure none of the code below the
+  // drupal_goto() call gets executed upon redirection.
+  exit();
+}
 
+/**
+ * Construct the redirect URL to be used by drupal_goto().
+ *
+ * @param $path
+ *   A Drupal path or a full URL.
+ * @param $query
+ *   A query string component, if any.
+ * @param $fragment
+ *   A destination fragment identifier (named anchor).
+ * @see drupal_goto()
+ */  
+function drupal_get_goto_url($path = '', $query = NULL, $fragment = NULL) {
   if (isset($_REQUEST['destination'])) {
     extract(parse_url(urldecode($_REQUEST['destination'])));
   }
@@ -331,7 +352,18 @@
   $url = url($path, array('query' => $query, 'fragment' => $fragment, 'absolute' => TRUE));
   // Remove newlines from the URL to avoid header injection attacks.
   $url = str_replace(array("\n", "\r"), '', $url);
+  return $url;
+}
 
+/**
+ * Prepare to redirect to a new page.
+ * Broadcast hook_exit and close the session.
+ *
+ * @param $url
+ *   The path that is about to be redirected to.
+ * @see drupal_goto()
+ */
+function drupal_goto_finalize($url) {
   // Allow modules to react to the end of the page request before redirecting.
   // We do not want this while running update.php.
   if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
@@ -343,15 +375,7 @@
     // we need all session data written to the database before redirecting.
     session_write_close();
   }
-
-  header('Location: ' . $url, TRUE, $http_response_code);
-
-  // The "Location" header sends a redirect status code to the HTTP daemon. In
-  // some cases this can be wrong, so we make sure none of the code below the
-  // drupal_goto() call gets executed upon redirection.
-  exit();
 }
-
 /**
  * Generates a site offline message.
  */
