1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/base/url_util.h" 6 7 #include "base/strings/string_piece.h" 8 #include "net/base/escape.h" 9 #include "url/gurl.h" 10 11 namespace net { 12 13 GURL AppendQueryParameter(const GURL& url, 14 const std::string& name, 15 const std::string& value) { 16 std::string query(url.query()); 17 18 if (!query.empty()) 19 query += "&"; 20 21 query += (EscapeQueryParamValue(name, true) + "=" + 22 EscapeQueryParamValue(value, true)); 23 GURL::Replacements replacements; 24 replacements.SetQueryStr(query); 25 return url.ReplaceComponents(replacements); 26 } 27 28 GURL AppendOrReplaceQueryParameter(const GURL& url, 29 const std::string& name, 30 const std::string& value) { 31 bool replaced = false; 32 std::string param_name = EscapeQueryParamValue(name, true); 33 std::string param_value = EscapeQueryParamValue(value, true); 34 35 const std::string input = url.query(); 36 url_parse::Component cursor(0, input.size()); 37 std::string output; 38 url_parse::Component key_range, value_range; 39 while (url_parse::ExtractQueryKeyValue( 40 input.data(), &cursor, &key_range, &value_range)) { 41 const base::StringPiece key( 42 input.data() + key_range.begin, key_range.len); 43 const base::StringPiece value( 44 input.data() + value_range.begin, value_range.len); 45 std::string key_value_pair; 46 // Check |replaced| as only the first pair should be replaced. 47 if (!replaced && key == param_name) { 48 replaced = true; 49 key_value_pair = (param_name + "=" + param_value); 50 } else { 51 key_value_pair.assign(input.data(), 52 key_range.begin, 53 value_range.end() - key_range.begin); 54 } 55 if (!output.empty()) 56 output += "&"; 57 58 output += key_value_pair; 59 } 60 if (!replaced) { 61 if (!output.empty()) 62 output += "&"; 63 64 output += (param_name + "=" + param_value); 65 } 66 GURL::Replacements replacements; 67 replacements.SetQueryStr(output); 68 return url.ReplaceComponents(replacements); 69 } 70 71 bool GetValueForKeyInQuery(const GURL& url, 72 const std::string& search_key, 73 std::string* out_value) { 74 if (!url.is_valid()) 75 return false; 76 77 url_parse::Component query = url.parsed_for_possibly_invalid_spec().query; 78 url_parse::Component key, value; 79 while (url_parse::ExtractQueryKeyValue( 80 url.spec().c_str(), &query, &key, &value)) { 81 if (key.is_nonempty()) { 82 std::string key_string = url.spec().substr(key.begin, key.len); 83 if (key_string == search_key) { 84 if (value.is_nonempty()) { 85 *out_value = UnescapeURLComponent( 86 url.spec().substr(value.begin, value.len), 87 UnescapeRule::SPACES | 88 UnescapeRule::URL_SPECIAL_CHARS | 89 UnescapeRule::REPLACE_PLUS_WITH_SPACE); 90 } else { 91 *out_value = ""; 92 } 93 return true; 94 } 95 } 96 } 97 return false; 98 } 99 100 } // namespace net 101