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 const base::StringPiece
value(
47 input
.data() + value_range
.begin
, value_range
.len
);
48 std::string key_value_pair
;
49 // Check |replaced| as only the first pair should be replaced.
50 if (!replaced
&& key
== param_name
) {
52 key_value_pair
= (param_name
+ "=" + param_value
);
54 key_value_pair
.assign(input
.data(),
56 value_range
.end() - key_range
.begin
);
61 output
+= key_value_pair
;
67 output
+= (param_name
+ "=" + param_value
);
69 GURL::Replacements replacements
;
70 replacements
.SetQueryStr(output
);
71 return url
.ReplaceComponents(replacements
);
74 QueryIterator::QueryIterator(const GURL
& url
)
76 at_end_(!url
.is_valid()) {
78 query_
= url
.parsed_for_possibly_invalid_spec().query
;
83 QueryIterator::~QueryIterator() {
86 std::string
QueryIterator::GetKey() const {
88 if (key_
.is_nonempty())
89 return url_
.spec().substr(key_
.begin
, key_
.len
);
93 std::string
QueryIterator::GetValue() const {
95 if (value_
.is_nonempty())
96 return url_
.spec().substr(value_
.begin
, value_
.len
);
100 const std::string
& QueryIterator::GetUnescapedValue() {
102 if (value_
.is_nonempty() && unescaped_value_
.empty()) {
103 unescaped_value_
= UnescapeURLComponent(
105 UnescapeRule::SPACES
|
106 UnescapeRule::URL_SPECIAL_CHARS
|
107 UnescapeRule::REPLACE_PLUS_WITH_SPACE
);
109 return unescaped_value_
;
112 bool QueryIterator::IsAtEnd() const {
116 void QueryIterator::Advance() {
120 unescaped_value_
.clear();
122 !url::ExtractQueryKeyValue(url_
.spec().c_str(), &query_
, &key_
, &value_
);
125 bool GetValueForKeyInQuery(const GURL
& url
,
126 const std::string
& search_key
,
127 std::string
* out_value
) {
128 for (QueryIterator
it(url
); !it
.IsAtEnd(); it
.Advance()) {
129 if (it
.GetKey() == search_key
) {
130 *out_value
= it
.GetUnescapedValue();