]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/mgr/QueryParams.cc
2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 16 Cache Manager API */
12 #include "base/TextException.h"
13 #include "ipc/TypedMsgHdr.h"
14 #include "mgr/IntParam.h"
15 #include "mgr/QueryParams.h"
16 #include "mgr/StringParam.h"
17 #include "parser/Tokenizer.h"
18 #include "sbuf/StringConvert.h"
22 Mgr::QueryParam::Pointer
23 Mgr::QueryParams::get(const String
& name
) const
25 Must(name
.size() != 0);
26 Params::const_iterator pos
= find(name
);
27 return (pos
== params
.end() ? NULL
: pos
->second
);
31 Mgr::QueryParams::pack(Ipc::TypedMsgHdr
& msg
) const
33 msg
.putInt(params
.size());
34 for (Params::const_iterator iter
= params
.begin(); iter
!= params
.end(); ++iter
) {
35 Must(iter
->first
.size() != 0);
36 msg
.putString(iter
->first
);
37 Must(iter
->second
!= NULL
);
38 iter
->second
->pack(msg
);
43 Mgr::QueryParams::unpack(const Ipc::TypedMsgHdr
& msg
)
45 int count
= msg
.getInt();
48 for ( ; count
> 0; --count
) {
51 Must(name
.size() != 0);
52 QueryParam::Type type
;
54 QueryParam::Pointer value
= CreateParam(type
);
55 value
->unpackValue(msg
);
56 params
.push_back(Param(name
, value
));
60 Mgr::QueryParams::Params::const_iterator
61 Mgr::QueryParams::find(const String
& name
) const
63 Must(name
.size() != 0);
64 Params::const_iterator iter
= params
.begin();
65 for ( ; iter
!= params
.end(); ++iter
) {
66 if (name
.caseCmp(iter
->first
) == 0)
73 * Parses the value part of a "param=value" URL section.
74 * Value can be a comma-separated list of integers or an opaque string.
76 * value = *pchar | ( 1*DIGIT *( ',' 1*DIGIT ) )
78 * \note opaque string may be a list with a non-integer (e.g., "1,2,3,z")
80 Mgr::QueryParam::Pointer
81 ParseParamValue(const SBuf
&rawValue
)
83 static const CharacterSet
comma("comma", ",");
85 Parser::Tokenizer
tok(rawValue
);
86 std::vector
<int> array
;
88 while (tok
.int64(intVal
, 10, false)) {
89 Must(intVal
>= std::numeric_limits
<int>::min());
90 Must(intVal
<= std::numeric_limits
<int>::max());
91 array
.emplace_back(intVal
);
92 // integer list has comma between values.
93 // Require at least one potential DIGIT after the skipped ','
94 if (tok
.remaining().length() > 1)
95 (void)tok
.skipOne(comma
);
99 return new Mgr::IntParam(array
);
101 return new Mgr::StringParam(SBufToString(rawValue
));
106 * query = [ param *( '&' param ) ]
107 * param = name '=' value
108 * name = [a-zA-Z0-9]+
109 * value = *pchar | ( 1*DIGIT *( ',' 1*DIGIT ) )
112 Mgr::QueryParams::Parse(Parser::Tokenizer
&tok
, QueryParams
&aParams
)
114 static const CharacterSet nameChars
= CharacterSet("param-name", "_") + CharacterSet::ALPHA
+ CharacterSet::DIGIT
;
115 static const CharacterSet valueChars
= CharacterSet("param-value", "&= #").complement();
116 static const CharacterSet
delimChars("param-delim", "&");
118 while (!tok
.atEnd()) {
120 // TODO: remove '#' processing when AnyP::Uri splits 'query#fragment' properly
121 // #fragment handled by caller. Do not throw.
122 if (tok
.remaining()[0] == '#')
125 if (tok
.skipAll(delimChars
))
129 if (!tok
.prefix(nameStr
, nameChars
))
130 throw TextException("invalid query parameter name", Here());
132 throw TextException("missing parameter value", Here());
135 if (!tok
.prefix(valueStr
, valueChars
))
136 throw TextException("missing or malformed parameter value", Here());
138 const auto name
= SBufToString(nameStr
);
139 const auto value
= ParseParamValue(valueStr
);
140 aParams
.params
.emplace_back(name
, value
);
144 Mgr::QueryParam::Pointer
145 Mgr::QueryParams::CreateParam(QueryParam::Type aType
)
148 case QueryParam::ptInt
:
149 return new IntParam();
151 case QueryParam::ptString
:
152 return new StringParam();
155 throw TexcHere("unknown parameter type");