Index: captcha.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/captcha/captcha.module,v
retrieving revision 1.42.2.34
diff -u -u -p -r1.42.2.34 captcha.module
--- captcha.module	2 Oct 2007 19:21:20 -0000	1.42.2.34
+++ captcha.module	14 Oct 2007 14:07:22 -0000
@@ -16,6 +16,10 @@ define('CAPTCHA_PERSISTENCE_SHOW_ALWAYS'
 define('CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL_PER_FORM', 2);
 define('CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL', 3);
 
+define('CAPTCHA_FAILURE_REACTION_FORM_ERROR', 1);
+define('CAPTCHA_FAILURE_REACTION_SPARTAN403', 2);
+define('CAPTCHA_FAILURE_REACTION_DRUPAL_ACCESS_DENIED', 3);
+
 /**
  * Implementation of hook_help().
  */
@@ -254,6 +258,18 @@ function captcha_admin_settings() {
     ),
     '#description' => t('Define if challenges should be omitted during the rest of a session once the user successfully responses to a challenge.'),
   );
+  // option for how to react on a wrong answer
+  $form['captcha_reaction_on_wrong_response'] = array(
+    '#type' => 'radios',
+    '#title' => t('Reaction on wrong response'),
+    '#options' => array(
+      CAPTCHA_FAILURE_REACTION_FORM_ERROR => t('Reshow form with error message (default Drupal behavior).'),
+      CAPTCHA_FAILURE_REACTION_DRUPAL_ACCESS_DENIED => t('Show the <a href="!errorreporting">access denied error page</a>.', array('!errorreporting' => url('admin/settings/error-reporting'))),
+      CAPTCHA_FAILURE_REACTION_SPARTAN403 => t('Show bare error message (with HTTP status code 403).'),
+    ),
+    '#default_value' => variable_get('captcha_reaction_on_wrong_response', CAPTCHA_FAILURE_REACTION_FORM_ERROR),
+    '#description' => t('By changing the reaction on wrong responses, you can reduce the resources spend on processing wrong responses, presumably of spammers. Note however that this is less user friendly to human users, which can make errors too.'),
+  );
   // submit button
   $form['submit'] = array(
     '#type' => 'submit',
@@ -304,6 +320,7 @@ function captcha_admin_settings_submit($
       variable_set('captcha_description', $form_values['captcha_description']);
     }
     variable_set('captcha_persistence', $form_values['captcha_persistence']);
+    variable_set('captcha_reaction_on_wrong_response', $form_values['captcha_reaction_on_wrong_response']);
     drupal_set_message(t('The CAPTCHA settings were saved.'), 'status');
   }
 }
@@ -511,6 +528,27 @@ function captcha_form_alter($form_id, &$
 }
 
 /**
+ * Helper function for reacting on validate errors
+ */
+function _captcha_form_set_error($name, $message) {
+  switch (variable_get('captcha_reaction_on_wrong_response', CAPTCHA_FAILURE_REACTION_FORM_ERROR)) {
+    case CAPTCHA_FAILURE_REACTION_FORM_ERROR:
+      form_set_error($name, $message);
+      break;
+    case CAPTCHA_FAILURE_REACTION_SPARTAN403:
+      header('HTTP/1.1 403 Forbidden');
+      print $message;
+      // stop further validation, processing and subsequent form rendering
+      exit();
+      break;
+    case CAPTCHA_FAILURE_REACTION_DRUPAL_ACCESS_DENIED:
+      drupal_access_denied();
+      exit();
+      break;
+  }
+}
+
+/**
  * Implementation of form #validate.
  */
 function captcha_validate($form_values) {
@@ -524,7 +562,7 @@ function captcha_validate($form_values) 
   $captcha_token = $form_values['#post']['captcha_token'];
   // Check if captcha_token exists
   if (!isset($_SESSION['captcha'][$form_id][$captcha_token])) {
-    form_set_error('captcha_token', t('Invalid CAPTCHA token.'));
+    _captcha_form_set_error('captcha_token', t('Invalid CAPTCHA token.'));
   }
   // Check answer
   if ($captcha_response === $_SESSION['captcha'][$form_id][$captcha_token]) {
@@ -532,7 +570,7 @@ function captcha_validate($form_values) 
     $_SESSION['captcha']['success'] = TRUE;
   }
   else {
-    form_set_error('captcha_response', t('The answer you entered for the CAPTCHA was not correct.'));
+    _captcha_form_set_error('captcha_response', t('The answer you entered for the CAPTCHA was not correct.'));
     // If CAPTCHA was on a login form: stop validating, quit the current request
     // and forward to the current page (like a reload) to prevent loging in.
     // We do that because the log in procedure, which happens after
