Index: lib/http.c
===================================================================
RCS file: /repository/curl/lib/http.c,v
retrieving revision 1.204
diff -u -r1.204 http.c
--- lib/http.c	14 Mar 2004 18:15:04 -0000	1.204
+++ lib/http.c	29 Mar 2004 17:26:43 -0000
@@ -438,6 +438,63 @@
   return CURLE_OK;
 }
 
+/**
+ * determine whether an http response has gotten us into an
+ * error state or not.
+ *
+ * @param conn all information about the current connection
+ *
+ * @retval 0 communications should continue
+ *
+ * @retval 1 communications should not continue
+ */
+int Curl_http_should_fail(struct connectdata *conn,
+                          int httpcode)
+{
+  struct SessionHandle *data;
+  struct Curl_transfer_keeper *k;
+
+  curlassert(conn);
+  data = conn->data;
+  curlassert(data);
+
+  /*
+  ** For readability
+  */
+  k = &conn->keep;
+
+  /*
+  ** If we haven't been asked to fail on error,
+  ** don't fail.
+  */
+  if (!data->set.http_fail_on_error)
+    return 0;
+
+  /*
+  ** Any code < 400 is never terminal.
+  */
+  if (k->httpcode < 400)
+    return 0;
+
+  /*
+  ** Any code >= 400 that's not 401 or 407 is always
+  ** a terminal error
+  */
+  if ((k->httpcode != 401) &&
+      (k->httpcode != 407))
+    return 1;
+
+  /*
+  ** All we have left to deal with is 401 and 407
+  */
+  curlassert((k->httpcode == 401) || (k->httpcode == 407));
+
+  /*
+  ** For now, just return that this is a terminal
+  ** error until we put the proper logic in.
+  */
+  return 1;
+}
 
 /* fread() emulation to provide POST and/or request data */
 static size_t readmoredata(char *buffer,
Index: lib/http.h
===================================================================
RCS file: /repository/curl/lib/http.h,v
retrieving revision 1.20
diff -u -r1.20 http.h
--- lib/http.h	7 Jan 2004 09:19:35 -0000	1.20
+++ lib/http.h	29 Mar 2004 17:26:43 -0000
@@ -42,9 +42,13 @@
 void Curl_httpchunk_init(struct connectdata *conn);
 CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
                               ssize_t length, ssize_t *wrote);
+
+/* These functions are in http.c */
 void Curl_http_auth_stage(struct SessionHandle *data, int stage);
 CURLcode Curl_http_auth(struct connectdata *conn,
                         int httpcode, char *header);
 void Curl_http_auth_act(struct connectdata *conn);
+
+int Curl_http_should_fail(struct connectdata *conn);
 #endif
 #endif
Index: lib/transfer.c
===================================================================
RCS file: /repository/curl/lib/transfer.c,v
retrieving revision 1.213
diff -u -r1.213 transfer.c
--- lib/transfer.c	22 Mar 2004 22:38:12 -0000	1.213
+++ lib/transfer.c	29 Mar 2004 17:26:44 -0000
@@ -576,9 +576,21 @@
                 data->info.httpcode = k->httpcode;
                 data->info.httpversion = k->httpversion;
 
-                /* 404 -> URL not found! */
+                /*
+                ** This code executes as part of processing
+                ** the header.  As a result, it's not
+                ** totally clear how to interpret the
+                ** response code yet as that depends on what
+                ** other headers may be present.  401 and
+                ** 407 may be errors, but may be OK
+                ** depending on how authentication is
+                ** working.  Other codes are definitely
+                ** errors, so give up here.
+                */
                 if (data->set.http_fail_on_error &&
-                    (k->httpcode >= 400)) {
+                    (k->httpcode >= 400) &&
+                    (k->httpcode != 401) &&
+                    (k->httpcode != 407)) {
                   /* If we have been told to fail hard on HTTP-errors,
                      here is the check for that: */
                   /* serious error, go home! */
@@ -873,6 +885,17 @@
 
         }                       /* end if header mode */
 
+        /*
+        ** Now that all of the headers have been parsed, see
+        ** if we should give up and return an error.
+        */
+        if (Curl_http_should_fail(conn)
+        {
+          failf (data, "The requested URL returned error: %d",
+                 k->httpcode);
+          return CURLE_HTTP_RETURNED_ERROR;
+        }
+
         /* This is not an 'else if' since it may be a rest from the header
            parsing, where the beginning of the buffer is headers and the end
            is non-headers. */

