Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Yershov <syershov@maps.me>2016-12-07 17:38:47 +0300
committerSergey Yershov <syershov@maps.me>2016-12-09 13:39:57 +0300
commitd67c82407eee4f8b5f7ad1c493497476d83c4529 (patch)
treebab0d31bce50df147b56fdf96d77fb40b08a648b /traffic
parentfc8189106a38692a746597ebb9548bbcd218068e (diff)
HEAD request for check traffic update
Diffstat (limited to 'traffic')
-rw-r--r--traffic/traffic_info.cpp88
-rw-r--r--traffic/traffic_info.hpp16
-rw-r--r--traffic/traffic_tests/traffic_info_test.cpp9
3 files changed, 73 insertions, 40 deletions
diff --git a/traffic/traffic_info.cpp b/traffic/traffic_info.cpp
index d3346adb99..23138ba085 100644
--- a/traffic/traffic_info.cpp
+++ b/traffic/traffic_info.cpp
@@ -75,6 +75,8 @@ string MakeRemoteURL(string const & name, uint64_t version)
ss << UrlEncode(name) << TRAFFIC_FILE_EXTENSION;
return ss.str();
}
+
+char const kETag[] = "Etag";
} // namespace
// TrafficInfo::RoadSegmentId -----------------------------------------------------------------
@@ -133,10 +135,10 @@ void TrafficInfo::SetTrafficKeysForTesting(vector<RoadSegmentId> const & keys)
m_availability = Availability::IsAvailable;
}
-bool TrafficInfo::ReceiveTrafficData()
+bool TrafficInfo::ReceiveTrafficData(string & etag)
{
vector<SpeedGroup> values;
- if (!ReceiveTrafficValues(values))
+ if (!ReceiveTrafficValues(etag, values))
return false;
return UpdateTrafficData(values);
@@ -396,48 +398,28 @@ bool TrafficInfo::ReceiveTrafficKeys()
return true;
}
-bool TrafficInfo::ReceiveTrafficValues(vector<SpeedGroup> & values)
+bool TrafficInfo::ReceiveTrafficValues(string & etag, vector<SpeedGroup> & values)
{
auto const & info = m_mwmId.GetInfo();
if (!info)
return false;
- string const url = MakeRemoteURL(info->GetCountryName(), info->GetVersion());
+ uint64_t const version = info->GetVersion();
+ string const url = MakeRemoteURL(info->GetCountryName(), version);
if (url.empty())
return false;
- vector<uint8_t> contents;
- int errorCode;
- if (!ReadRemoteFile(url, contents, errorCode))
- {
- if (errorCode == 404)
- {
- string const result(reinterpret_cast<char*>(contents.data()), contents.size());
-
- int64_t version = 0;
- strings::to_int64(result.c_str(), version);
-
- if (version > info->GetVersion() && version <= m_currentDataVersion)
- m_availability = Availability::ExpiredData;
- else if (version > m_currentDataVersion)
- m_availability = Availability::ExpiredApp;
- else
- m_availability = Availability::NoData;
- }
- else
- {
- m_availability = Availability::Unknown;
-
- alohalytics::LogEvent(
- "$TrafficNetworkError",
- alohalytics::TStringMap({{"code", strings::to_string(errorCode)}}));
- }
- return false;
- }
+ platform::HttpClient request(url);
+ request.LoadHeaders(true);
+ request.SetRawHeader("If-None-Match", etag);
+ if (!request.RunHttpRequest() || request.ErrorCode() != 200)
+ return ProcessFailure(request, version);
try
{
+ string const & response = request.ServerResponse();
+ vector<uint8_t> contents(response.cbegin(), response.cend());
DeserializeTrafficValues(contents, values);
}
catch (Reader::Exception const & e)
@@ -453,6 +435,12 @@ bool TrafficInfo::ReceiveTrafficValues(vector<SpeedGroup> & values)
return false;
}
+ // Update ETag for this MWM.
+ auto const & headers = request.GetHeaders();
+ auto const it = headers.find(kETag);
+ if (it != headers.end())
+ etag = it->second;
+
m_availability = Availability::IsAvailable;
return true;
}
@@ -480,13 +468,45 @@ bool TrafficInfo::UpdateTrafficData(vector<SpeedGroup> const & values)
return true;
}
+bool TrafficInfo::ProcessFailure(platform::HttpClient const & request, uint64_t const mwmVersion)
+{
+ switch (request.ErrorCode())
+ {
+ case 404: /* Not Found */
+ {
+ int64_t version = 0;
+ strings::to_int64(request.ServerResponse().c_str(), version);
+
+ if (version > mwmVersion && version <= m_currentDataVersion)
+ m_availability = Availability::ExpiredData;
+ else if (version > m_currentDataVersion)
+ m_availability = Availability::ExpiredApp;
+ else
+ m_availability = Availability::NoData;
+ return false;
+ }
+ case 304: /* Not Modified */
+ {
+ m_availability = Availability::IsAvailable;
+ return true;
+ }
+ }
+
+ m_availability = Availability::Unknown;
+ alohalytics::LogEvent(
+ "$TrafficNetworkError",
+ alohalytics::TStringMap({{"code", strings::to_string(request.ErrorCode())}}));
+
+ return false;
+}
+
string DebugPrint(TrafficInfo::RoadSegmentId const & id)
{
string const dir =
- id.m_dir == TrafficInfo::RoadSegmentId::kForwardDirection ? "Forward" : "Backward";
+ id.m_dir == TrafficInfo::RoadSegmentId::kForwardDirection ? "Forward" : "Backward";
ostringstream oss;
oss << "RoadSegmentId ["
- << " fid = " << id.m_fid << " idx = " << id.m_idx << " dir = " << dir << " ]";
+ << " fid = " << id.m_fid << " idx = " << id.m_idx << " dir = " << dir << " ]";
return oss.str();
}
} // namespace traffic
diff --git a/traffic/traffic_info.hpp b/traffic/traffic_info.hpp
index 4c0ace5d21..23cbb268f0 100644
--- a/traffic/traffic_info.hpp
+++ b/traffic/traffic_info.hpp
@@ -9,6 +9,11 @@
#include "std/shared_ptr.hpp"
#include "std/vector.hpp"
+namespace platform
+{
+class HttpClient;
+}
+
namespace traffic
{
// This class is responsible for providing the real-time
@@ -74,10 +79,13 @@ public:
static TrafficInfo BuildForTesting(Coloring && coloring);
void SetTrafficKeysForTesting(vector<RoadSegmentId> const & keys);
- // Fetches the latest traffic data from the server and updates the coloring.
+ // Fetches the latest traffic data from the server and updates the coloring and ETag.
// Construct the url by passing an MwmId.
+ // The ETag or entity tag is part of HTTP, the protocol for the World Wide Web.
+ // It is one of several mechanisms that HTTP provides for web cache validation,
+ // which allows a client to make conditional requests.
// *NOTE* This method must not be called on the UI thread.
- bool ReceiveTrafficData();
+ bool ReceiveTrafficData(string & etag);
// Returns the latest known speed group by a feature segment's id
// or SpeedGroup::Unknown if there is no information about the segment.
@@ -119,11 +127,13 @@ private:
// Returns true and updates m_coloring if the values are read successfully and
// their number is equal to the number of keys.
// Otherwise, returns false and does not change m_coloring.
- bool ReceiveTrafficValues(vector<SpeedGroup> & values);
+ bool ReceiveTrafficValues(string & etag, vector<SpeedGroup> & values);
// Updates the coloring and changes the availability status if needed.
bool UpdateTrafficData(vector<SpeedGroup> const & values);
+ bool ProcessFailure(platform::HttpClient const & request, uint64_t const mwmVersion);
+
// The mapping from feature segments to speed groups (see speed_groups.hpp).
Coloring m_coloring;
diff --git a/traffic/traffic_tests/traffic_info_test.cpp b/traffic/traffic_tests/traffic_info_test.cpp
index 45f962c65a..d804824580 100644
--- a/traffic/traffic_tests/traffic_info_test.cpp
+++ b/traffic/traffic_tests/traffic_info_test.cpp
@@ -44,21 +44,24 @@ UNIT_TEST(TrafficInfo_RemoteFile)
auto const & r =
mwmSet.Register(platform::LocalCountryFile::MakeForTesting("traffic_data_test"));
TrafficInfo trafficInfo(r.first, r.first.GetInfo()->GetVersion());
- TEST(trafficInfo.ReceiveTrafficData(), ());
+ string etag;
+ TEST(trafficInfo.ReceiveTrafficData(etag), ());
}
{
TestMwmSet mwmSet;
auto const & r =
mwmSet.Register(platform::LocalCountryFile::MakeForTesting("traffic_data_test2"));
TrafficInfo trafficInfo(r.first, r.first.GetInfo()->GetVersion());
- TEST(!trafficInfo.ReceiveTrafficData(), ());
+ string etag;
+ TEST(!trafficInfo.ReceiveTrafficData(etag), ());
}
{
TestMwmSet mwmSet;
auto const & r =
mwmSet.Register(platform::LocalCountryFile::MakeForTesting("traffic_data_test", 101010));
TrafficInfo trafficInfo(r.first, r.first.GetInfo()->GetVersion());
- TEST(trafficInfo.ReceiveTrafficData(), ());
+ string etag;
+ TEST(trafficInfo.ReceiveTrafficData(etag), ());
}
}