? sites/default/files
? sites/default/private
? sites/default/settings.php
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.427
diff -u -p -r1.427 form.inc
--- includes/form.inc	25 Jan 2010 10:38:34 -0000	1.427
+++ includes/form.inc	25 Jan 2010 19:14:48 -0000
@@ -731,7 +731,11 @@ function drupal_prepare_form($form_id, &
     $form['#id'] = drupal_html_id($form_id);
   }
 
+  if (isset($form_state['action'])) {
+    $form['#action'] = $form_state['action'];
+  }
   $form += element_info('form');
+  $form_state['action'] = $form['#action'];
   $form += array('#tree' => FALSE, '#parents' => array());
 
   if (!isset($form['#validate'])) {
@@ -1215,12 +1219,9 @@ function form_builder($form_id, $element
 
   // Special handling if we're on the top level form element.
   if (isset($element['#type']) && $element['#type'] == 'form') {
-    if (!empty($element['#https']) && variable_get('https', FALSE) &&
-        !url_is_external($element['#action'])) {
-      global $base_root;
-
-      // Not an external URL so ensure that it is secure.
-      $element['#action'] = str_replace('http://', 'https://', $base_root) . $element['#action'];
+    // Ensure that internal URLs are secure when HTTPS is enabled.
+    if (!empty($element['#https']) && variable_get('https', FALSE) && !url_is_external($element['#action'])) {
+      $element['#action'] = str_replace('http://', 'https://', $GLOBALS['base_root']) . $element['#action'];
     }
 
     // Store a complete copy of the form in form_state prior to building the form.
@@ -2881,9 +2882,12 @@ function theme_textfield($variables) {
  */
 function theme_form($variables) {
   $element = $variables['element'];
-  // Anonymous div to satisfy XHTML compliance.
+  $element['#attributes']['accept-charset'] = 'UTF-8';
+  $element['#attributes']['method'] = $element['#method'];
+  $element['#attributes']['id'] = $element['#id'];
   $action = $element['#action'] ? 'action="' . check_url($element['#action']) . '" ' : '';
-  return '<form ' . $action . ' accept-charset="UTF-8" method="' . $element['#method'] . '" id="' . $element['#id'] . '"' . drupal_attributes($element['#attributes']) . ">\n<div>" . $element['#children'] . "\n</div></form>\n";
+  // Anonymous div to satisfy XHTML compliance.
+  return '<form ' . $action . drupal_attributes($element['#attributes']) . ">\n<div>" . $element['#children'] . "\n</div></form>\n";
 }
 
 /**
Index: modules/simpletest/tests/form.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form.test,v
retrieving revision 1.33
diff -u -p -r1.33 form.test
--- modules/simpletest/tests/form.test	8 Jan 2010 06:36:34 -0000	1.33
+++ modules/simpletest/tests/form.test	25 Jan 2010 19:14:48 -0000
@@ -784,3 +784,41 @@ class FormsRebuildTestCase extends Drupa
     $this->assertFieldById('edit-text-2', 'DEFAULT 2', t('A newly added textfield was initialized with its default value.'));
   }
 }
+
+/**
+ * Test to ensure cached forms preserve their #action across different urls.
+ */
+class FormActionFunctionalTest extends DrupalWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Form action test',
+      'description' => 'Test to ensure form\'s #action remains the same for cached forms',
+      'group' => 'Form API',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('form_test');
+  }
+
+  function testFormAction() {
+    // Warm the cache.
+    $this->drupalGet('form-test/form-action');
+
+    $build_id_element = $this->xpath('//form[@id="form-test-action-persist"]/div/input[@name="form_build_id"]');
+    foreach ($build_id_element[0]->attributes() as $key => $value) {
+      if ($key == 'value') {
+        $build_id = $value;
+      }
+    }
+
+    // Pass the build id to the callback that drupal_rebuild_form().
+    // This is very similar to ajax_get_form().
+    $this->drupalGet('form-test/form-action-cache/' . $build_id);
+
+    // Check to make sure the action matches the first url.
+    $form = $this->xpath('//form[@action="/form-test/form-action"]');
+    $this->assertTrue(!empty($form), t('The form action for the cached form is preserved'));
+  }
+}
Index: modules/simpletest/tests/form_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form_test.module,v
retrieving revision 1.26
diff -u -p -r1.26 form_test.module
--- modules/simpletest/tests/form_test.module	8 Jan 2010 06:36:34 -0000	1.26
+++ modules/simpletest/tests/form_test.module	25 Jan 2010 19:14:48 -0000
@@ -118,6 +118,22 @@ function form_test_menu() {
     'type' => MENU_CALLBACK,
   );
 
+  $items['form-test/form-action'] = array(
+    'title' => 'Form action persistence when cached',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('form_test_action_persist'),
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+  );
+
+  $items['form-test/form-action-cache/%'] = array(
+    'title' => 'Render the same form except the form action should match form-test/form-action',
+    'page callback' => 'form_test_cached_form',
+    'page arguments' => array(2),
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+  );
+
   return $items;
 }
 
@@ -889,3 +905,29 @@ function form_test_form_form_test_state_
     $form_state['cache'] = TRUE;
   }
 }
+
+/**
+ * Form builder for testing the preservation of the form action.
+ */
+function form_test_action_persist($form, &$form_state) {
+  $form_state['cache'] = TRUE;
+  $form['submit_button'] = array(
+    '#type' => 'submit',
+    '#value' => t('Submit'),
+  );
+}
+
+/**
+ * Menu callback for rendering the cached form again.
+ *
+ * @param $form_build_id
+ *  The build id of the form.
+ *
+ * @return string
+ *  HTML for the page.
+ */
+function form_test_cached_form($form_build_id) {
+  $form_state = form_state_defaults();
+  $form = form_get_cache($form_build_id, $form_state);
+  return drupal_rebuild_form($form['#form_id'], $form_state, $form_build_id);
+}
\ No newline at end of file
