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.
5 #include "net/base/url_util.h"
9 #include "base/logging.h"
10 #include "base/strings/string_piece.h"
11 #include "net/base/escape.h"
16 GURL
AppendQueryParameter(const GURL
& url
,
17 const std::string
& name
,
18 const std::string
& value
) {
19 std::string
query(url
.query());
24 query
+= (EscapeQueryParamValue(name
, true) + "=" +
25 EscapeQueryParamValue(value
, true));
26 GURL::Replacements replacements
;
27 replacements
.SetQueryStr(query
);
28 return url
.ReplaceComponents(replacements
);
31 GURL
AppendOrReplaceQueryParameter(const GURL
& url
,
32 const std::string
& name
,
33 const std::string
& value
) {
34 bool replaced
= false;
35 std::string param_name
= EscapeQueryParamValue(name
, true);
36 std::string param_value
= EscapeQueryParamValue(value
, true);
38 const std::string input
= url
.query();
39 url::Component
cursor(0, input
.size());
41 url::Component key_range
, value_range
;
42 while (url::ExtractQueryKeyValue(input
.data(), &cursor
, &key_range
,
44 const base::StringPiece
key(
45 input
.data() + key_range
.begin
, key_range
.len
);
46 std::string key_value_pair
;
47 // Check |replaced| as only the first pair should be replaced.
48 if (!replaced
&& key
== param_name
) {
50 key_value_pair
= (param_name
+ "=" + param_value
);
52 key_value_pair
.assign(input
.data(),
54 value_range
.end() - key_range
.begin
);
59 output
+= key_value_pair
;
65 output
+= (param_name
+ "=" + param_value
);
67 GURL::Replacements replacements
;
68 replacements
.SetQueryStr(output
);
69 return url
.ReplaceComponents(replacements
);
72 QueryIterator::QueryIterator(const GURL
& url
)
74 at_end_(!url
.is_valid()) {
76 query_
= url
.parsed_for_possibly_invalid_spec().query
;
81 QueryIterator::~QueryIterator() {
84 std::string
QueryIterator::GetKey() const {
86 if (key_
.is_nonempty())
87 return url_
.spec().substr(key_
.begin
, key_
.len
);
91 std::string
QueryIterator::GetValue() const {
93 if (value_
.is_nonempty())
94 return url_
.spec().substr(value_
.begin
, value_
.len
);
98 const std::string
& QueryIterator::GetUnescapedValue() {
100 if (value_
.is_nonempty() && unescaped_value_
.empty()) {
101 unescaped_value_
= UnescapeURLComponent(
103 UnescapeRule::SPACES
|
104 UnescapeRule::URL_SPECIAL_CHARS
|
105 UnescapeRule::REPLACE_PLUS_WITH_SPACE
);
107 return unescaped_value_
;
110 bool QueryIterator::IsAtEnd() const {
114 void QueryIterator::Advance() {
118 unescaped_value_
.clear();
120 !url::ExtractQueryKeyValue(url_
.spec().c_str(), &query_
, &key_
, &value_
);
123 bool GetValueForKeyInQuery(const GURL
& url
,
124 const std::string
& search_key
,
125 std::string
* out_value
) {
126 for (QueryIterator
it(url
); !it
.IsAtEnd(); it
.Advance()) {
127 if (it
.GetKey() == search_key
) {
128 *out_value
= it
.GetUnescapedValue();