Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / net / http / http_network_transaction.cc
index 7e9819a..cf67b1d 100644 (file)
@@ -54,6 +54,7 @@
 #include "net/socket/ssl_client_socket.h"
 #include "net/socket/ssl_client_socket_pool.h"
 #include "net/socket/transport_client_socket_pool.h"
+#include "net/spdy/hpack_huffman_aggregator.h"
 #include "net/spdy/spdy_http_stream.h"
 #include "net/spdy/spdy_session.h"
 #include "net/spdy/spdy_session_pool.h"
@@ -193,10 +194,9 @@ int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
     proxy_ssl_config_.rev_checking_enabled = false;
   }
 
-  // Channel ID is enabled unless --disable-tls-channel-id flag is set,
-  // or if privacy mode is enabled.
+  // Channel ID is disabled if privacy mode is enabled for this request.
   bool channel_id_enabled = server_ssl_config_.channel_id_enabled &&
-      (request_->privacy_mode == kPrivacyModeDisabled);
+      (request_->privacy_mode == PRIVACY_MODE_DISABLED);
   server_ssl_config_.channel_id_enabled = channel_id_enabled;
 
   next_state_ = STATE_NOTIFY_BEFORE_CREATE_STREAM;
@@ -943,16 +943,6 @@ int HttpNetworkTransaction::DoReadHeaders() {
   return stream_->ReadResponseHeaders(io_callback_);
 }
 
-int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() {
-  if (!response_.headers.get() && !stream_->IsConnectionReused()) {
-    // The connection was closed before any data was sent. Likely an error
-    // rather than empty HTTP/0.9 response.
-    return ERR_EMPTY_RESPONSE;
-  }
-
-  return OK;
-}
-
 int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
   // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here
   // due to SSL renegotiation.
@@ -979,78 +969,58 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
     return OK;
   }
 
-  if (result < 0 && result != ERR_CONNECTION_CLOSED)
-    return HandleIOError(result);
-
-  if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) {
-    ResetConnectionAndRequestForResend();
-    return OK;
-  }
-
   // After we call RestartWithAuth a new response_time will be recorded, and
   // we need to be cautious about incorrectly logging the duration across the
   // authentication activity.
   if (result == OK)
     LogTransactionConnectedMetrics();
 
-  if (result == ERR_CONNECTION_CLOSED) {
-    // For now, if we get at least some data, we do the best we can to make
-    // sense of it and send it back up the stack.
-    int rv = HandleConnectionClosedBeforeEndOfHeaders();
-    if (rv != OK)
-      return rv;
-  }
+  // ERR_CONNECTION_CLOSED is treated differently at this point; if partial
+  // response headers were received, we do the best we can to make sense of it
+  // and send it back up the stack.
+  //
+  // TODO(davidben): Consider moving this to HttpBasicStream, It's a little
+  // bizarre for SPDY. Assuming this logic is useful at all.
+  // TODO(davidben): Bubble the error code up so we do not cache?
+  if (result == ERR_CONNECTION_CLOSED && response_.headers.get())
+    result = OK;
+
+  if (result < 0)
+    return HandleIOError(result);
+
   DCHECK(response_.headers.get());
 
 #if defined(SPDY_PROXY_AUTH_ORIGIN)
   // Server-induced fallback; see: http://crbug.com/143712
-  if (response_.was_fetched_via_proxy && response_.headers.get() != NULL) {
+  if (response_.was_fetched_via_proxy) {
     ProxyService::DataReductionProxyBypassEventType proxy_bypass_event =
         ProxyService::BYPASS_EVENT_TYPE_MAX;
-    net::HttpResponseHeaders::ChromeProxyInfo chrome_proxy_info;
-    bool chrome_proxy_used =
+    bool data_reduction_proxy_used =
         proxy_info_.proxy_server().isDataReductionProxy();
-    bool chrome_fallback_proxy_used = false;
+    bool data_reduction_fallback_proxy_used = false;
 #if defined(DATA_REDUCTION_FALLBACK_HOST)
-    if (!chrome_proxy_used) {
-      chrome_fallback_proxy_used =
+    if (!data_reduction_proxy_used) {
+      data_reduction_fallback_proxy_used =
           proxy_info_.proxy_server().isDataReductionProxyFallback();
     }
 #endif
 
-    if (chrome_proxy_used || chrome_fallback_proxy_used) {
-      // A Via header might not be present in a 304. Since the goal of a 304
-      // response is to minimize information transfer, a sender in general
-      // should not generate representation metadata other than Cache-Control,
-      // Content-Location, Date, ETag, Expires, and Vary.
-      if (!response_.headers->IsChromeProxyResponse() &&
-          (response_.headers->response_code() != HTTP_NOT_MODIFIED)) {
-        proxy_bypass_event = ProxyService::MISSING_VIA_HEADER;
-      } else if (response_.headers->GetChromeProxyInfo(&chrome_proxy_info)) {
-        if (chrome_proxy_info.bypass_duration < TimeDelta::FromMinutes(30))
-          proxy_bypass_event = ProxyService::SHORT_BYPASS;
-        else
-          proxy_bypass_event = ProxyService::LONG_BYPASS;
-      } else {
-        // Additionally, fallback if a 500, 502 or 503 is returned via the data
-        // reduction proxy. This is conservative, as the 500, 502 or 503 might
-        // have been generated by the origin, and not the proxy.
-        if (response_.headers->response_code() == HTTP_INTERNAL_SERVER_ERROR ||
-            response_.headers->response_code() == HTTP_BAD_GATEWAY ||
-            response_.headers->response_code() == HTTP_SERVICE_UNAVAILABLE) {
-          proxy_bypass_event = ProxyService::INTERNAL_SERVER_ERROR_BYPASS;
-        }
-      }
-
+    if (data_reduction_proxy_used || data_reduction_fallback_proxy_used) {
+      net::HttpResponseHeaders::DataReductionProxyInfo
+      data_reduction_proxy_info;
+      proxy_bypass_event
+          = response_.headers->GetDataReductionProxyBypassEventType(
+              &data_reduction_proxy_info);
       if (proxy_bypass_event < ProxyService::BYPASS_EVENT_TYPE_MAX) {
         ProxyService* proxy_service = session_->proxy_service();
 
         proxy_service->RecordDataReductionProxyBypassInfo(
-            chrome_proxy_used, proxy_info_.proxy_server(), proxy_bypass_event);
+            data_reduction_proxy_used, proxy_info_.proxy_server(),
+            proxy_bypass_event);
 
         ProxyServer proxy_server;
 #if defined(DATA_REDUCTION_FALLBACK_HOST)
-        if (chrome_proxy_used && chrome_proxy_info.bypass_all) {
+        if (data_reduction_proxy_used && data_reduction_proxy_info.bypass_all) {
           // TODO(bengr): Rename as DATA_REDUCTION_FALLBACK_ORIGIN.
           GURL proxy_url(DATA_REDUCTION_FALLBACK_HOST);
           if (proxy_url.SchemeIsHTTPOrHTTPS()) {
@@ -1063,7 +1033,7 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
 #endif
         if (proxy_service->MarkProxiesAsBadUntil(
                 proxy_info_,
-                chrome_proxy_info.bypass_duration,
+                data_reduction_proxy_info.bypass_duration,
                 proxy_server,
                 net_log_)) {
           // Only retry idempotent methods. We don't want to resubmit a POST
@@ -1130,6 +1100,14 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
     stream_->GetSSLInfo(&response_.ssl_info);
 
   headers_valid_ = true;
+
+  if (session_->huffman_aggregator()) {
+    session_->huffman_aggregator()->AggregateTransactionCharacterCounts(
+        *request_,
+        request_headers_,
+        proxy_info_.proxy_server(),
+        *response_.headers);
+  }
   return OK;
 }
 
@@ -1455,7 +1433,11 @@ int HttpNetworkTransaction::HandleIOError(int error) {
     // likely happen when trying to retrieve its IP address.
     // See http://crbug.com/105824 for more details.
     case ERR_SOCKET_NOT_CONNECTED:
-      if (ShouldResendRequest(error)) {
+    // If a socket is closed on its initial request, HttpStreamParser returns
+    // ERR_EMPTY_RESPONSE. This may still be close/reuse race if the socket was
+    // preconnected but failed to be used before the server timed it out.
+    case ERR_EMPTY_RESPONSE:
+      if (ShouldResendRequest()) {
         net_log_.AddEventWithNetErrorCode(
             NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, error);
         ResetConnectionAndRequestForResend();
@@ -1506,7 +1488,7 @@ HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const {
   return response_.headers.get();
 }
 
-bool HttpNetworkTransaction::ShouldResendRequest(int error) const {
+bool HttpNetworkTransaction::ShouldResendRequest() const {
   bool connection_is_proven = stream_->IsConnectionReused();
   bool has_received_headers = GetResponseHeaders() != NULL;