| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/geolocation/network_location_request.h" | 5 #include "content/browser/geolocation/network_location_request.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| 11 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
| 12 #include "base/string_number_conversions.h" | 12 #include "base/string_number_conversions.h" |
| 13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "content/common/geoposition.h" | |
| 16 #include "content/common/net/url_fetcher_impl.h" | 15 #include "content/common/net/url_fetcher_impl.h" |
| 16 #include "content/public/common/geoposition.h" |
| 17 #include "net/base/escape.h" | 17 #include "net/base/escape.h" |
| 18 #include "net/base/load_flags.h" | 18 #include "net/base/load_flags.h" |
| 19 #include "net/url_request/url_request_context_getter.h" | 19 #include "net/url_request/url_request_context_getter.h" |
| 20 #include "net/url_request/url_request_status.h" | 20 #include "net/url_request/url_request_status.h" |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 const size_t kMaxRequestLength = 2048; | 24 const size_t kMaxRequestLength = 2048; |
| 25 | 25 |
| 26 const char kAccessTokenString[] = "access_token"; | 26 const char kAccessTokenString[] = "access_token"; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 37 const string16& access_token, | 37 const string16& access_token, |
| 38 const WifiData& wifi_data, | 38 const WifiData& wifi_data, |
| 39 const base::Time& timestamp); | 39 const base::Time& timestamp); |
| 40 | 40 |
| 41 // Parsers the server response. | 41 // Parsers the server response. |
| 42 void GetLocationFromResponse(bool http_post_result, | 42 void GetLocationFromResponse(bool http_post_result, |
| 43 int status_code, | 43 int status_code, |
| 44 const std::string& response_body, | 44 const std::string& response_body, |
| 45 const base::Time& timestamp, | 45 const base::Time& timestamp, |
| 46 const GURL& server_url, | 46 const GURL& server_url, |
| 47 Geoposition* position, | 47 content::Geoposition* position, |
| 48 string16* access_token); | 48 string16* access_token); |
| 49 | 49 |
| 50 // Parses the server response body. Returns true if parsing was successful. | 50 // Parses the server response body. Returns true if parsing was successful. |
| 51 // Sets |*position| to the parsed location if a valid fix was received, | 51 // Sets |*position| to the parsed location if a valid fix was received, |
| 52 // otherwise leaves it unchanged (i.e. IsInitialized() == false). | 52 // otherwise leaves it unchanged. |
| 53 bool ParseServerResponse(const std::string& response_body, | 53 bool ParseServerResponse(const std::string& response_body, |
| 54 const base::Time& timestamp, | 54 const base::Time& timestamp, |
| 55 Geoposition* position, | 55 content::Geoposition* position, |
| 56 string16* access_token); | 56 string16* access_token); |
| 57 void AddWifiData(const WifiData& wifi_data, | 57 void AddWifiData(const WifiData& wifi_data, |
| 58 int age_milliseconds, | 58 int age_milliseconds, |
| 59 std::vector<std::string>* params); | 59 std::vector<std::string>* params); |
| 60 } // namespace | 60 } // namespace |
| 61 | 61 |
| 62 int NetworkLocationRequest::url_fetcher_id_for_tests = 0; | 62 int NetworkLocationRequest::url_fetcher_id_for_tests = 0; |
| 63 | 63 |
| 64 NetworkLocationRequest::NetworkLocationRequest( | 64 NetworkLocationRequest::NetworkLocationRequest( |
| 65 net::URLRequestContextGetter* context, | 65 net::URLRequestContextGetter* context, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 return true; | 99 return true; |
| 100 } | 100 } |
| 101 | 101 |
| 102 void NetworkLocationRequest::OnURLFetchComplete( | 102 void NetworkLocationRequest::OnURLFetchComplete( |
| 103 const content::URLFetcher* source) { | 103 const content::URLFetcher* source) { |
| 104 DCHECK_EQ(url_fetcher_.get(), source); | 104 DCHECK_EQ(url_fetcher_.get(), source); |
| 105 | 105 |
| 106 net::URLRequestStatus status = source->GetStatus(); | 106 net::URLRequestStatus status = source->GetStatus(); |
| 107 int response_code = source->GetResponseCode(); | 107 int response_code = source->GetResponseCode(); |
| 108 | 108 |
| 109 Geoposition position; | 109 content::Geoposition position; |
| 110 string16 access_token; | 110 string16 access_token; |
| 111 std::string data; | 111 std::string data; |
| 112 source->GetResponseAsString(&data); | 112 source->GetResponseAsString(&data); |
| 113 GetLocationFromResponse(status.is_success(), | 113 GetLocationFromResponse(status.is_success(), |
| 114 response_code, | 114 response_code, |
| 115 data, | 115 data, |
| 116 timestamp_, | 116 timestamp_, |
| 117 source->GetURL(), | 117 source->GetURL(), |
| 118 &position, | 118 &position, |
| 119 &access_token); | 119 &access_token); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 // interpreted as the wifi parameter separator. | 230 // interpreted as the wifi parameter separator. |
| 231 ReplaceSubstringsAfterOffset(&ssid, 0, "|", "\\|"); | 231 ReplaceSubstringsAfterOffset(&ssid, 0, "|", "\\|"); |
| 232 AddString("ssid:", ssid, &wifi_params); | 232 AddString("ssid:", ssid, &wifi_params); |
| 233 params->push_back( | 233 params->push_back( |
| 234 "wifi=" + net::EscapeQueryParamValue(wifi_params, false)); | 234 "wifi=" + net::EscapeQueryParamValue(wifi_params, false)); |
| 235 } | 235 } |
| 236 } | 236 } |
| 237 | 237 |
| 238 void FormatPositionError(const GURL& server_url, | 238 void FormatPositionError(const GURL& server_url, |
| 239 const std::string& message, | 239 const std::string& message, |
| 240 Geoposition* position) { | 240 content::Geoposition* position) { |
| 241 position->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; | 241 position->error_code = |
| 242 content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; |
| 242 position->error_message = "Network location provider at '"; | 243 position->error_message = "Network location provider at '"; |
| 243 position->error_message += server_url.possibly_invalid_spec(); | 244 position->error_message += server_url.possibly_invalid_spec(); |
| 244 position->error_message += "' : "; | 245 position->error_message += "' : "; |
| 245 position->error_message += message; | 246 position->error_message += message; |
| 246 position->error_message += "."; | 247 position->error_message += "."; |
| 247 VLOG(1) << "NetworkLocationRequest::GetLocationFromResponse() : " | 248 VLOG(1) << "NetworkLocationRequest::GetLocationFromResponse() : " |
| 248 << position->error_message; | 249 << position->error_message; |
| 249 } | 250 } |
| 250 | 251 |
| 251 void GetLocationFromResponse(bool http_post_result, | 252 void GetLocationFromResponse(bool http_post_result, |
| 252 int status_code, | 253 int status_code, |
| 253 const std::string& response_body, | 254 const std::string& response_body, |
| 254 const base::Time& timestamp, | 255 const base::Time& timestamp, |
| 255 const GURL& server_url, | 256 const GURL& server_url, |
| 256 Geoposition* position, | 257 content::Geoposition* position, |
| 257 string16* access_token) { | 258 string16* access_token) { |
| 258 DCHECK(position); | 259 DCHECK(position); |
| 259 DCHECK(access_token); | 260 DCHECK(access_token); |
| 260 | 261 |
| 261 // HttpPost can fail for a number of reasons. Most likely this is because | 262 // HttpPost can fail for a number of reasons. Most likely this is because |
| 262 // we're offline, or there was no response. | 263 // we're offline, or there was no response. |
| 263 if (!http_post_result) { | 264 if (!http_post_result) { |
| 264 FormatPositionError(server_url, "No response received", position); | 265 FormatPositionError(server_url, "No response received", position); |
| 265 return; | 266 return; |
| 266 } | 267 } |
| 267 if (status_code != 200) { // HTTP OK. | 268 if (status_code != 200) { // HTTP OK. |
| 268 std::string message = "Returned error code "; | 269 std::string message = "Returned error code "; |
| 269 message += base::IntToString(status_code); | 270 message += base::IntToString(status_code); |
| 270 FormatPositionError(server_url, message, position); | 271 FormatPositionError(server_url, message, position); |
| 271 return; | 272 return; |
| 272 } | 273 } |
| 273 // We use the timestamp from the device data that was used to generate | 274 // We use the timestamp from the device data that was used to generate |
| 274 // this position fix. | 275 // this position fix. |
| 275 if (!ParseServerResponse(response_body, timestamp, position, access_token)) { | 276 if (!ParseServerResponse(response_body, timestamp, position, access_token)) { |
| 276 // We failed to parse the repsonse. | 277 // We failed to parse the repsonse. |
| 277 FormatPositionError(server_url, "Response was malformed", position); | 278 FormatPositionError(server_url, "Response was malformed", position); |
| 278 return; | 279 return; |
| 279 } | 280 } |
| 280 // The response was successfully parsed, but it may not be a valid | 281 // The response was successfully parsed, but it may not be a valid |
| 281 // position fix. | 282 // position fix. |
| 282 if (!position->IsValidFix()) { | 283 if (!position->Validate()) { |
| 283 FormatPositionError(server_url, | 284 FormatPositionError(server_url, |
| 284 "Did not provide a good position fix", position); | 285 "Did not provide a good position fix", position); |
| 285 return; | 286 return; |
| 286 } | 287 } |
| 287 } | 288 } |
| 288 | 289 |
| 289 // Numeric values without a decimal point have type integer and IsDouble() will | 290 // Numeric values without a decimal point have type integer and IsDouble() will |
| 290 // return false. This is convenience function for detecting integer or floating | 291 // return false. This is convenience function for detecting integer or floating |
| 291 // point numeric values. Note that isIntegral() includes boolean values, which | 292 // point numeric values. Note that isIntegral() includes boolean values, which |
| 292 // is not what we want. | 293 // is not what we want. |
| 293 bool GetAsDouble(const DictionaryValue& object, | 294 bool GetAsDouble(const DictionaryValue& object, |
| 294 const std::string& property_name, | 295 const std::string& property_name, |
| 295 double* out) { | 296 double* out) { |
| 296 DCHECK(out); | 297 DCHECK(out); |
| 297 Value* value = NULL; | 298 Value* value = NULL; |
| 298 if (!object.Get(property_name, &value)) | 299 if (!object.Get(property_name, &value)) |
| 299 return false; | 300 return false; |
| 300 int value_as_int; | 301 int value_as_int; |
| 301 DCHECK(value); | 302 DCHECK(value); |
| 302 if (value->GetAsInteger(&value_as_int)) { | 303 if (value->GetAsInteger(&value_as_int)) { |
| 303 *out = value_as_int; | 304 *out = value_as_int; |
| 304 return true; | 305 return true; |
| 305 } | 306 } |
| 306 return value->GetAsDouble(out); | 307 return value->GetAsDouble(out); |
| 307 } | 308 } |
| 308 | 309 |
| 309 bool ParseServerResponse(const std::string& response_body, | 310 bool ParseServerResponse(const std::string& response_body, |
| 310 const base::Time& timestamp, | 311 const base::Time& timestamp, |
| 311 Geoposition* position, | 312 content::Geoposition* position, |
| 312 string16* access_token) { | 313 string16* access_token) { |
| 313 DCHECK(position); | 314 DCHECK(position); |
| 314 DCHECK(!position->IsInitialized()); | 315 DCHECK(!position->Validate()); |
| 316 DCHECK(position->error_code == content::Geoposition::ERROR_CODE_NONE); |
| 315 DCHECK(access_token); | 317 DCHECK(access_token); |
| 316 DCHECK(!timestamp.is_null()); | 318 DCHECK(!timestamp.is_null()); |
| 317 | 319 |
| 318 if (response_body.empty()) { | 320 if (response_body.empty()) { |
| 319 LOG(WARNING) << "ParseServerResponse() : Response was empty."; | 321 LOG(WARNING) << "ParseServerResponse() : Response was empty."; |
| 320 return false; | 322 return false; |
| 321 } | 323 } |
| 322 DVLOG(1) << "ParseServerResponse() : Parsing response " << response_body; | 324 DVLOG(1) << "ParseServerResponse() : Parsing response " << response_body; |
| 323 | 325 |
| 324 // Parse the response, ignoring comments. | 326 // Parse the response, ignoring comments. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 position->longitude = longitude; | 408 position->longitude = longitude; |
| 407 position->timestamp = timestamp; | 409 position->timestamp = timestamp; |
| 408 | 410 |
| 409 // Other fields are optional. | 411 // Other fields are optional. |
| 410 GetAsDouble(*response_object, kAccuracyString, &position->accuracy); | 412 GetAsDouble(*response_object, kAccuracyString, &position->accuracy); |
| 411 | 413 |
| 412 return true; | 414 return true; |
| 413 } | 415 } |
| 414 | 416 |
| 415 } // namespace | 417 } // namespace |
| OLD | NEW |