QueryParams.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
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.
7  */
8 
9 /* DEBUG: section 16 Cache Manager API */
10 
11 #include "squid.h"
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"
19 
20 #include <limits>
21 
23 Mgr::QueryParams::get(const String& name) const
24 {
25  Must(name.size() != 0);
26  Params::const_iterator pos = find(name);
27  return (pos == params.end() ? nullptr : pos->second);
28 }
29 
30 void
32 {
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 != nullptr);
38  iter->second->pack(msg);
39  }
40 }
41 
42 void
44 {
45  int count = msg.getInt();
46  Must(count >= 0);
47  params.clear();
48  for ( ; count > 0; --count) {
49  String name;
50  msg.getString(name);
51  Must(name.size() != 0);
52  QueryParam::Type type;
53  msg.getPod(type);
54  QueryParam::Pointer value = CreateParam(type);
55  value->unpackValue(msg);
56  params.push_back(Param(name, value));
57  }
58 }
59 
60 Mgr::QueryParams::Params::const_iterator
61 Mgr::QueryParams::find(const String& name) const
62 {
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)
67  break;
68  }
69  return iter;
70 }
71 
81 ParseParamValue(const SBuf &rawValue)
82 {
83  static const CharacterSet comma("comma", ",");
84 
85  Parser::Tokenizer tok(rawValue);
86  std::vector<int> array;
87  int64_t intVal = 0;
88  while (tok.int64(intVal, 10, false)) {
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);
96  }
97 
98  if (tok.atEnd())
99  return new Mgr::IntParam(array);
100  else
101  return new Mgr::StringParam(SBufToString(rawValue));
102 }
103 
111 void
113 {
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", "&");
117 
118  while (!tok.atEnd()) {
119 
120  // TODO: remove '#' processing when AnyP::Uri splits 'query#fragment' properly
121  // #fragment handled by caller. Do not throw.
122  if (tok.remaining()[0] == '#')
123  return;
124 
125  if (tok.skipAll(delimChars))
126  continue;
127 
128  SBuf nameStr;
129  if (!tok.prefix(nameStr, nameChars))
130  throw TextException("invalid query parameter name", Here());
131  if (!tok.skip('='))
132  throw TextException("missing parameter value", Here());
133 
134  SBuf valueStr;
135  if (!tok.prefix(valueStr, valueChars))
136  throw TextException("missing or malformed parameter value", Here());
137 
138  const auto name = SBufToString(nameStr);
139  const auto value = ParseParamValue(valueStr);
140  aParams.params.emplace_back(name, value);
141  }
142 }
143 
146 {
147  switch (aType) {
148  case QueryParam::ptInt:
149  return new IntParam();
150 
152  return new StringParam();
153 
154  default:
155  throw TexcHere("unknown parameter type");
156  break;
157  }
158  return nullptr;
159 }
160 
int caseCmp(char const *) const
Definition: String.cc:266
static QueryParam::Pointer CreateParam(QueryParam::Type aType)
creates a parameter of the specified type
Definition: QueryParams.cc:145
#define Here()
source code location of the caller
Definition: Here.h:15
Params::const_iterator find(const String &name) const
find query parameter by name
Definition: QueryParams.cc:61
Definition: SBuf.h:93
QueryParam::Pointer get(const String &name) const
returns query parameter by name
Definition: QueryParams.cc:23
CharacterSet complement(const char *complementLabel=nullptr) const
Definition: CharacterSet.cc:74
const A & max(A const &lhs, A const &rhs)
static const CharacterSet ALPHA
Definition: CharacterSet.h:76
#define TexcHere(msg)
legacy convenience macro; it is not difficult to type Here() now
Definition: TextException.h:63
void pack(Ipc::TypedMsgHdr &msg) const
store params into msg
Definition: QueryParams.cc:31
void unpack(const Ipc::TypedMsgHdr &msg)
Definition: QueryParams.cc:43
void putInt(int n)
store an integer
Definition: TypedMsgHdr.cc:119
int getInt() const
load an integer
Definition: TypedMsgHdr.cc:111
static const CharacterSet DIGIT
Definition: CharacterSet.h:84
void getString(String &s) const
load variable-length string
Definition: TypedMsgHdr.cc:125
static Mgr::QueryParam::Pointer ParseParamValue(const SBuf &rawValue)
Definition: QueryParams.cc:81
static void Parse(Parser::Tokenizer &, QueryParams &)
parses the query string parameters
Definition: QueryParams.cc:112
Definition: parse.c:160
an std::runtime_error with thrower location info
Definition: TextException.h:20
size_type size() const
Definition: SquidString.h:73
#define Must(condition)
Definition: TextException.h:75
struct msghdr with a known type, fixed-size I/O and control buffers
Definition: TypedMsgHdr.h:34
std::pair< String, QueryParam::Pointer > Param
Definition: QueryParams.h:28
optimized set of C chars, with quick membership test and merge support
Definition: CharacterSet.h:17
String SBufToString(const SBuf &s)
Definition: StringConvert.h:26
void getPod(Pod &pod) const
load POD
Definition: TypedMsgHdr.h:118
const A & min(A const &lhs, A const &rhs)
void putString(const String &s)
store variable-length string
Definition: TypedMsgHdr.cc:143

 

Introduction

Documentation

Support

Miscellaneous