AU: Expose the server's HTTP response code in HttpFetcher.

A step towards resolving 2394 -- we'll need to exponentially back
off on 500 and 503 as well as 502 if possible.

BUG=2394
TEST=unit tests, gmerged and made sure updates can happen

Change-Id: I7928e3af37f23ce1ba197315ec52ab0b2ed0dc4c

Review URL: http://codereview.chromium.org/3106038
diff --git a/http_fetcher.h b/http_fetcher.h
index 5cd6f08..f8e510a 100644
--- a/http_fetcher.h
+++ b/http_fetcher.h
@@ -23,14 +23,15 @@
 
 class HttpFetcher {
  public:
-  HttpFetcher() : post_data_set_(false), delegate_(NULL) {}
+  HttpFetcher()
+      : post_data_set_(false),
+        http_response_code_(0),
+        delegate_(NULL) {}
   virtual ~HttpFetcher() {}
-  void set_delegate(HttpFetcherDelegate* delegate) {
-    delegate_ = delegate;
-  }
-  HttpFetcherDelegate* delegate() const {
-    return delegate_;
-  }
+
+  void set_delegate(HttpFetcherDelegate* delegate) { delegate_ = delegate; }
+  HttpFetcherDelegate* delegate() const { return delegate_; }
+  int http_response_code() const { return http_response_code_; }
 
   // Optional: Post data to the server. The HttpFetcher should make a copy
   // of this data and upload it via HTTP POST during the transfer.
@@ -66,6 +67,11 @@
   bool post_data_set_;
   std::vector<char> post_data_;
 
+  // The server's HTTP response code from the last transfer. This
+  // field should be set to 0 when a new transfer is initiated, and
+  // set to the response code when the transfer is complete.
+  int http_response_code_;
+
   // The delegate; may be NULL.
   HttpFetcherDelegate* delegate_;
  private:
diff --git a/http_fetcher_unittest.cc b/http_fetcher_unittest.cc
index f7dad8e..d096267 100644
--- a/http_fetcher_unittest.cc
+++ b/http_fetcher_unittest.cc
@@ -161,6 +161,7 @@
     memcpy(str, bytes, length);
   }
   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
+    EXPECT_EQ(200, fetcher->http_response_code());
     g_main_loop_quit(loop_);
   }
   GMainLoop* loop_;
@@ -332,6 +333,7 @@
 
     g_main_loop_run(loop);
     g_source_destroy(timeout_source_);
+    EXPECT_EQ(0, fetcher->http_response_code());
   }
   g_main_loop_unref(loop);
 }
@@ -345,6 +347,7 @@
   }
   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
     EXPECT_TRUE(successful);
+    EXPECT_EQ(206, fetcher->http_response_code());
     g_main_loop_quit(loop_);
   }
   string data;
@@ -398,6 +401,7 @@
   }
   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
     EXPECT_FALSE(successful);
+    EXPECT_EQ(0, fetcher->http_response_code());
     g_main_loop_quit(loop_);
   }
   GMainLoop* loop_;
@@ -466,6 +470,12 @@
   }
   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
     EXPECT_EQ(expected_successful_, successful);
+    if (expected_successful_)
+      EXPECT_EQ(200, fetcher->http_response_code());
+    else {
+      EXPECT_GE(fetcher->http_response_code(), 301);
+      EXPECT_LE(fetcher->http_response_code(), 307);
+    }
     g_main_loop_quit(loop_);
   }
   bool expected_successful_;
diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc
index a07a825..9989ba2 100644
--- a/libcurl_http_fetcher.cc
+++ b/libcurl_http_fetcher.cc
@@ -78,6 +78,7 @@
   bytes_downloaded_ = 0;
   resume_offset_ = 0;
   retry_count_ = 0;
+  http_response_code_ = 0;
   ResumeTransfer(url);
   CurlPerformOnce();
 }
@@ -105,6 +106,7 @@
     } else {
       LOG(ERROR) << "Unable to get http response code.";
     }
+    http_response_code_ = static_cast<int>(http_response_code);
 
     // we're done!
     CleanUp();
diff --git a/mock_http_fetcher.cc b/mock_http_fetcher.cc
index 04ec7f6..2e11865 100644
--- a/mock_http_fetcher.cc
+++ b/mock_http_fetcher.cc
@@ -17,6 +17,7 @@
 }
 
 void MockHttpFetcher::BeginTransfer(const std::string& url) {
+  http_response_code_ = 0;
   if (sent_size_ < data_.size())
     SendData(true);
 }
@@ -34,7 +35,8 @@
     sent_size_ += chunk_size;
     CHECK_LE(sent_size_, data_.size());
     if (sent_size_ == data_.size()) {
-      // We've sent all the data. notify of success
+      // We've sent all the data. Notify of success.
+      http_response_code_ = 200;
       delegate_->TransferComplete(this, true);
     }
   }