passenger 5.1.6 → 5.1.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG +13 -4
- data/build/support/cxx_dependency_map.rb +48 -0
- data/src/agent/Core/Controller.h +1 -0
- data/src/agent/Core/Controller/StateInspection.cpp +5 -0
- data/src/agent/Core/CoreMain.cpp +3 -0
- data/src/agent/Core/SecurityUpdateChecker.h +30 -11
- data/src/agent/Core/SpawningKit/PipeWatcher.h +1 -1
- data/src/agent/UstRouter/RemoteSender.h +9 -2
- data/src/cxx_supportlib/ConfigKit/Common.h +5 -0
- data/src/cxx_supportlib/ConfigKit/DummyTranslator.h +76 -0
- data/src/cxx_supportlib/ConfigKit/PrefixTranslator.h +166 -0
- data/src/cxx_supportlib/ConfigKit/README.md +57 -32
- data/src/cxx_supportlib/ConfigKit/Schema.h +23 -15
- data/src/cxx_supportlib/ConfigKit/Store.h +15 -3
- data/src/cxx_supportlib/ConfigKit/Utils.h +6 -0
- data/src/cxx_supportlib/ConfigKit/VariantMapUtils.h +12 -0
- data/src/cxx_supportlib/Constants.h +1 -1
- data/src/cxx_supportlib/Utils.cpp +15 -5
- data/src/cxx_supportlib/Utils.h +2 -0
- data/src/cxx_supportlib/Utils/Curl.h +1 -1
- data/src/cxx_supportlib/vendor-modified/jsoncpp/json-forwards.h +10 -4
- data/src/cxx_supportlib/vendor-modified/jsoncpp/json.h +30 -9
- data/src/cxx_supportlib/vendor-modified/jsoncpp/jsoncpp.cpp +85 -51
- data/src/ruby_supportlib/phusion_passenger.rb +1 -1
- metadata +4 -2
@@ -336,7 +336,11 @@ private:
|
|
336
336
|
prepareRequest(pingURL);
|
337
337
|
|
338
338
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
339
|
-
|
339
|
+
CURLcode code;
|
340
|
+
if (CURLE_OK == (code = setCurlDefaultCaInfo(curl))) {
|
341
|
+
code = curl_easy_perform(curl);
|
342
|
+
}
|
343
|
+
if (code != 0) {
|
340
344
|
setPingError(
|
341
345
|
"Could not ping Union Station gateway server " +
|
342
346
|
ip + ": " + lastCurlErrorMessage);
|
@@ -406,7 +410,10 @@ private:
|
|
406
410
|
P_DEBUG("Sending Union Station packet: key=" << item.unionStationKey <<
|
407
411
|
", node=" << item.nodeName << ", category=" << item.category <<
|
408
412
|
", compressedDataSize=" << item.data.size());
|
409
|
-
CURLcode code
|
413
|
+
CURLcode code;
|
414
|
+
if (CURLE_OK == (code = setCurlDefaultCaInfo(curl))) {
|
415
|
+
code = curl_easy_perform(curl);
|
416
|
+
}
|
410
417
|
curl_formfree(post);
|
411
418
|
|
412
419
|
if (code == CURLE_OK) {
|
@@ -44,10 +44,15 @@ class Store;
|
|
44
44
|
|
45
45
|
enum Type {
|
46
46
|
STRING_TYPE,
|
47
|
+
PASSWORD_TYPE, // Like STRING_TYPE, but inspect() won't show its value
|
47
48
|
INT_TYPE,
|
48
49
|
UINT_TYPE,
|
49
50
|
FLOAT_TYPE,
|
50
51
|
BOOL_TYPE,
|
52
|
+
|
53
|
+
ARRAY_TYPE,
|
54
|
+
STRING_ARRAY_TYPE,
|
55
|
+
|
51
56
|
UNKNOWN_TYPE
|
52
57
|
};
|
53
58
|
|
@@ -0,0 +1,76 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2017 Phusion Holding B.V.
|
4
|
+
*
|
5
|
+
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
|
+
* trademarks of Phusion Holding B.V.
|
7
|
+
*
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
* of this software and associated documentation files (the "Software"), to deal
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
13
|
+
* furnished to do so, subject to the following conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be included in
|
16
|
+
* all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
* THE SOFTWARE.
|
25
|
+
*/
|
26
|
+
#ifndef _PASSENGER_CONFIG_KIT_DUMMY_TRANSLATOR_H_
|
27
|
+
#define _PASSENGER_CONFIG_KIT_DUMMY_TRANSLATOR_H_
|
28
|
+
|
29
|
+
#include <vector>
|
30
|
+
#include <ConfigKit/Common.h>
|
31
|
+
#include <StaticString.h>
|
32
|
+
|
33
|
+
namespace Passenger {
|
34
|
+
namespace ConfigKit {
|
35
|
+
|
36
|
+
using namespace std;
|
37
|
+
|
38
|
+
|
39
|
+
/**
|
40
|
+
* A translator that does nothing.
|
41
|
+
*
|
42
|
+
* You can learn more about translators in the ConfigKit README, section
|
43
|
+
* "The special problem of overlapping configuration names and translation".
|
44
|
+
*/
|
45
|
+
class DummyTranslator {
|
46
|
+
public:
|
47
|
+
Json::Value translate(const Json::Value &doc) const {
|
48
|
+
return doc;
|
49
|
+
}
|
50
|
+
|
51
|
+
Json::Value reverseTranslate(const Json::Value &doc) const {
|
52
|
+
return doc;
|
53
|
+
}
|
54
|
+
|
55
|
+
vector<Error> translate(const vector<Error> &errors) const {
|
56
|
+
return errors;
|
57
|
+
}
|
58
|
+
|
59
|
+
vector<Error> reverseTranslate(const vector<Error> &errors) const {
|
60
|
+
return errors;
|
61
|
+
}
|
62
|
+
|
63
|
+
StaticString translateOne(const StaticString &key) const {
|
64
|
+
return key;
|
65
|
+
}
|
66
|
+
|
67
|
+
StaticString reverseTranslateOne(const StaticString &key) const {
|
68
|
+
return key;
|
69
|
+
}
|
70
|
+
};
|
71
|
+
|
72
|
+
|
73
|
+
} // namespace ConfigKit
|
74
|
+
} // namespace Passenger
|
75
|
+
|
76
|
+
#endif /* _PASSENGER_CONFIG_KIT_DUMMY_TRANSLATOR_H_ */
|
@@ -0,0 +1,166 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2017 Phusion Holding B.V.
|
4
|
+
*
|
5
|
+
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
|
+
* trademarks of Phusion Holding B.V.
|
7
|
+
*
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
* of this software and associated documentation files (the "Software"), to deal
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
13
|
+
* furnished to do so, subject to the following conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be included in
|
16
|
+
* all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
* THE SOFTWARE.
|
25
|
+
*/
|
26
|
+
#ifndef _PASSENGER_CONFIG_KIT_PREFIX_TRANSLATOR_H_
|
27
|
+
#define _PASSENGER_CONFIG_KIT_PREFIX_TRANSLATOR_H_
|
28
|
+
|
29
|
+
#include <boost/bind.hpp>
|
30
|
+
#include <cassert>
|
31
|
+
#include <string>
|
32
|
+
#include <vector>
|
33
|
+
#include <jsoncpp/json.h>
|
34
|
+
|
35
|
+
#include <ConfigKit/Common.h>
|
36
|
+
#include <StaticString.h>
|
37
|
+
|
38
|
+
namespace Passenger {
|
39
|
+
namespace ConfigKit {
|
40
|
+
|
41
|
+
using namespace std;
|
42
|
+
|
43
|
+
|
44
|
+
/**
|
45
|
+
* A translator that translates keys by adding a prefix.
|
46
|
+
*
|
47
|
+
* You can learn more about translators in the ConfigKit README, section
|
48
|
+
* "The special problem of overlapping configuration names and translation".
|
49
|
+
*/
|
50
|
+
class PrefixTranslator {
|
51
|
+
private:
|
52
|
+
string prefix;
|
53
|
+
bool finalized;
|
54
|
+
|
55
|
+
string translateErrorKey(const StaticString &key) const {
|
56
|
+
return "{{" + translateOne(key) + "}}";
|
57
|
+
}
|
58
|
+
|
59
|
+
string reverseTranslateErrorKey(const StaticString &key) const {
|
60
|
+
return "{{" + reverseTranslateOne(key) + "}}";
|
61
|
+
}
|
62
|
+
|
63
|
+
public:
|
64
|
+
PrefixTranslator()
|
65
|
+
: finalized(false)
|
66
|
+
{ }
|
67
|
+
|
68
|
+
PrefixTranslator(const string &_prefix)
|
69
|
+
: prefix(_prefix),
|
70
|
+
finalized(true)
|
71
|
+
{ }
|
72
|
+
|
73
|
+
void setPrefixAndFinalize(const string &_prefix) {
|
74
|
+
assert(!finalized);
|
75
|
+
prefix = _prefix;
|
76
|
+
finalized = true;
|
77
|
+
}
|
78
|
+
|
79
|
+
bool isFinalized() const {
|
80
|
+
return finalized;
|
81
|
+
}
|
82
|
+
|
83
|
+
Json::Value translate(const Json::Value &doc) const {
|
84
|
+
assert(finalized);
|
85
|
+
Json::Value result(Json::objectValue);
|
86
|
+
Json::Value::const_iterator it, end = doc.end();
|
87
|
+
|
88
|
+
for (it = doc.begin(); it != end; it++) {
|
89
|
+
const char *keyEnd;
|
90
|
+
const char *key = it.memberName(&keyEnd);
|
91
|
+
result[translateOne(StaticString(key, keyEnd - key))] = *it;
|
92
|
+
}
|
93
|
+
|
94
|
+
return result;
|
95
|
+
}
|
96
|
+
|
97
|
+
Json::Value reverseTranslate(const Json::Value &doc) const {
|
98
|
+
assert(finalized);
|
99
|
+
Json::Value result(Json::objectValue);
|
100
|
+
Json::Value::const_iterator it, end = doc.end();
|
101
|
+
|
102
|
+
for (it = doc.begin(); it != end; it++) {
|
103
|
+
const char *keyEnd;
|
104
|
+
const char *key = it.memberName(&keyEnd);
|
105
|
+
result[reverseTranslateOne(StaticString(key, keyEnd - key))] = *it;
|
106
|
+
}
|
107
|
+
|
108
|
+
return result;
|
109
|
+
}
|
110
|
+
|
111
|
+
vector<Error> translate(const vector<Error> &errors) const {
|
112
|
+
assert(finalized);
|
113
|
+
vector<Error> result;
|
114
|
+
vector<Error>::const_iterator it, end = errors.end();
|
115
|
+
Error::KeyProcessor keyProcessor =
|
116
|
+
boost::bind(&PrefixTranslator::translateErrorKey, this,
|
117
|
+
boost::placeholders::_1);
|
118
|
+
|
119
|
+
for (it = errors.begin(); it != end; it++) {
|
120
|
+
const Error &error = *it;
|
121
|
+
result.push_back(Error(error.getMessage(keyProcessor)));
|
122
|
+
}
|
123
|
+
|
124
|
+
return result;
|
125
|
+
}
|
126
|
+
|
127
|
+
vector<Error> reverseTranslate(const vector<Error> &errors) const {
|
128
|
+
assert(finalized);
|
129
|
+
vector<Error> result;
|
130
|
+
vector<Error>::const_iterator it, end = errors.end();
|
131
|
+
Error::KeyProcessor keyProcessor =
|
132
|
+
boost::bind(&PrefixTranslator::reverseTranslateErrorKey, this,
|
133
|
+
boost::placeholders::_1);
|
134
|
+
|
135
|
+
for (it = errors.begin(); it != end; it++) {
|
136
|
+
const Error &error = *it;
|
137
|
+
result.push_back(Error(error.getMessage(keyProcessor)));
|
138
|
+
}
|
139
|
+
|
140
|
+
return result;
|
141
|
+
}
|
142
|
+
|
143
|
+
string translateOne(const StaticString &key) const {
|
144
|
+
assert(finalized);
|
145
|
+
if (key.substr(0, prefix.size()) == prefix) {
|
146
|
+
return key.substr(prefix.size());
|
147
|
+
} else {
|
148
|
+
return key;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
string reverseTranslateOne(const StaticString &key) const {
|
153
|
+
assert(finalized);
|
154
|
+
if (key.substr(0, prefix.size()) != prefix) {
|
155
|
+
return prefix + key;
|
156
|
+
} else {
|
157
|
+
return key;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
};
|
161
|
+
|
162
|
+
|
163
|
+
} // namespace ConfigKit
|
164
|
+
} // namespace Passenger
|
165
|
+
|
166
|
+
#endif /* _PASSENGER_CONFIG_KIT_PREFIX_TRANSLATOR_H_ */
|
@@ -4,34 +4,41 @@ ConfigKit is a configuration management system that lets you define configuratio
|
|
4
4
|
|
5
5
|
**Table of contents:**
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
7
|
+
<!-- MarkdownTOC depth=3 autolink="true" bracket="round" -->
|
8
|
+
|
9
|
+
- [Motivations](#motivations)
|
10
|
+
- [Configuration flow from high-level to low-level with a minimum of repeated code](#configuration-flow-from-high-level-to-low-level-with-a-minimum-of-repeated-code)
|
11
|
+
- [Unifying configuration management](#unifying-configuration-management)
|
12
|
+
- [Status inside the Passenger codebase](#status-inside-the-passenger-codebase)
|
13
|
+
- [Features and class overview](#features-and-class-overview)
|
14
|
+
- [ConfigKit::Schema](#configkitschema)
|
15
|
+
- [ConfigKit::Store](#configkitstore)
|
16
|
+
- [Translators](#translators)
|
17
|
+
- [Using the schema](#using-the-schema)
|
18
|
+
- [Defining the schema](#defining-the-schema)
|
19
|
+
- [Types](#types)
|
20
|
+
- [Flags](#flags)
|
21
|
+
- [Defining default values](#defining-default-values)
|
22
|
+
- [Defining custom validators](#defining-custom-validators)
|
23
|
+
- [Inspecting the schema](#inspecting-the-schema)
|
24
|
+
- [Using the store](#using-the-store)
|
25
|
+
- [Putting data in the store](#putting-data-in-the-store)
|
26
|
+
- [Updating data](#updating-data)
|
27
|
+
- [Unregistered keys are ignored](#unregistered-keys-are-ignored)
|
28
|
+
- [Deleting data](#deleting-data)
|
29
|
+
- [Fetching data](#fetching-data)
|
30
|
+
- [Default values](#default-values)
|
31
|
+
- [Inspecting all data](#inspecting-all-data)
|
32
|
+
- [Putting it all together: synchronous version](#putting-it-all-together-synchronous-version)
|
33
|
+
- [SecurityChecker example: a configurable, low-level component](#securitychecker-example-a-configurable-low-level-component)
|
34
|
+
- [DnsQuerier example: a low-level component with post-configuration application operations](#dnsquerier-example-a-low-level-component-with-post-configuration-application-operations)
|
35
|
+
- [Downloader example: a high-level component that combines subcomponents](#downloader-example-a-high-level-component-that-combines-subcomponents)
|
36
|
+
- [The special problem of conflicting overlapping configuration names and translation](#the-special-problem-of-conflicting-overlapping-configuration-names-and-translation)
|
37
|
+
- [Code example](#code-example)
|
38
|
+
- [Main function example](#main-function-example)
|
39
|
+
- [Putting it all together: asynchronous version](#putting-it-all-together-asynchronous-version)
|
40
|
+
|
41
|
+
<!-- /MarkdownTOC -->
|
35
42
|
|
36
43
|
## Motivations
|
37
44
|
|
@@ -109,13 +116,13 @@ There is also `ConfigKit::Store`. This is a class that stores configuration valu
|
|
109
116
|
|
110
117
|
### Translators
|
111
118
|
|
112
|
-
And finally there
|
119
|
+
And finally there are "translator" classes: `ConfigKit::TableTranslator` and `ConfigKit::PrefixTranslator`. The role of translators are described in the section "The special problem of conflicting overlapping configuration names and translation".
|
113
120
|
|
114
121
|
## Using the schema
|
115
122
|
|
116
123
|
### Defining the schema
|
117
124
|
|
118
|
-
Start using ConfigKit by defining a schema. There are two ways to do this. The first one is to simply create ConfigKit::Schema object and adding definitions to it
|
125
|
+
Start using ConfigKit by defining a schema. There are two ways to do this. The first one is to simply create ConfigKit::Schema object and adding definitions to it with `schema.add(name, type, flags, [default value])`:
|
119
126
|
|
120
127
|
~~~c++
|
121
128
|
ConfigKit::Schema schema;
|
@@ -150,7 +157,25 @@ struct YourSchema: public ConfigKit::Schema {
|
|
150
157
|
YourSchema schema;
|
151
158
|
~~~
|
152
159
|
|
153
|
-
|
160
|
+
#### Types
|
161
|
+
|
162
|
+
The following types are available:
|
163
|
+
|
164
|
+
* `STRING_TYPE` -- a string.
|
165
|
+
* `PASSWORD_TYPE` -- a password string. Unlike `STRING_TYPE`, the value of password fields will be filtered out in the output generated by `ConfigKit::Store::inspect()`. Learn more about `inspect()` in [Using the store -- Inspecting all data](#inspecting-all-data).
|
166
|
+
* `INT_TYPE` -- a signed integer.
|
167
|
+
* `UINT_TYPE` -- an unsigned integer.
|
168
|
+
* `FLOAT_TYPE` -- a floating point number.
|
169
|
+
* `BOOL_TYPE` -- a boolean.
|
170
|
+
* `ARRAY_TYPE` -- an generic array. May contain any values.
|
171
|
+
* `STRING_ARRAY_TYPE` -- an array of strings.
|
172
|
+
|
173
|
+
#### Flags
|
174
|
+
|
175
|
+
* `REQUIRED` -- this field is required. Mutually exclusive with `OPTIONAL`.
|
176
|
+
* `OPTIONAL` -- this field is optional. Mutually exclusive with `REQUIRED`.
|
177
|
+
* `CACHE_DEFAULT_VALUE` -- use in combination with [dynamic default values](#defining-default-values). When this flag is set, the value returned by the dynamic value function is cached so that the function won't be called over and over again.
|
178
|
+
* `READ_ONLY` -- this field can only be set once. Only the first `ConfigKit::Store::update()` call actually updates the value; subsequent calls won't. Learn more about `update()` in [Using the store -- Putting data in the store](#putting-data-in-the-store).
|
154
179
|
|
155
180
|
### Defining default values
|
156
181
|
|
@@ -598,7 +623,7 @@ Whenever Downloader is configured, it configures subcomponents too. But whenever
|
|
598
623
|
There is one special problem that deserves attention: a high-level component may not necessarily want to expose their subcomponents' configuration options using the same names. For example, both `SecurityChecker` and `DnsQuerier` expose a `timeout` option, but they are *different* timeouts, and are even distinct from the Downloader's own download timeout. To solve this special problem of **conflicting overlapping configuration names**, we utilize a **translation system**. We define how the Downloader's configuration keys are to be mapped a specific subcomponent's configuration keys. We obviously can't define the entire mapping, because that would return us to the original problem of having to manually write so much repeated code. There are several ways to deal with this, such as:
|
599
624
|
|
600
625
|
- Assuming that most options don't have to be renamed, and only define exceptions to this rule. This is the approach that is demonstrated in this example. The `ConfigKit::TableTranslator` class implements this translation strategy.
|
601
|
-
- Prefixing the subcomponents' options.
|
626
|
+
- Prefixing the subcomponents' options. The `ConfigKit::PrefixTranslator` class implements this translation strategy.
|
602
627
|
|
603
628
|
#### Code example
|
604
629
|
|
@@ -37,6 +37,7 @@
|
|
37
37
|
#include <Exceptions.h>
|
38
38
|
#include <Logging.h>
|
39
39
|
#include <ConfigKit/Common.h>
|
40
|
+
#include <ConfigKit/DummyTranslator.h>
|
40
41
|
#include <ConfigKit/Utils.h>
|
41
42
|
#include <DataStructures/StringKeyTable.h>
|
42
43
|
#include <Utils/StrIntUtils.h>
|
@@ -94,21 +95,6 @@ public:
|
|
94
95
|
typedef boost::function<void (const Store &store, vector<Error> &errors)> Validator;
|
95
96
|
|
96
97
|
private:
|
97
|
-
class DummyTranslator {
|
98
|
-
public:
|
99
|
-
StaticString translateOne(const StaticString &key) const {
|
100
|
-
return key;
|
101
|
-
}
|
102
|
-
|
103
|
-
StaticString reverseTranslateOne(const StaticString &key) const {
|
104
|
-
return key;
|
105
|
-
}
|
106
|
-
|
107
|
-
vector<Error> reverseTranslate(const vector<Error> &errors) const {
|
108
|
-
return errors;
|
109
|
-
}
|
110
|
-
};
|
111
|
-
|
112
98
|
StringKeyTable<Entry> entries;
|
113
99
|
boost::container::vector<Validator> validators;
|
114
100
|
bool finalized;
|
@@ -255,6 +241,7 @@ public:
|
|
255
241
|
|
256
242
|
switch (entry->type) {
|
257
243
|
case STRING_TYPE:
|
244
|
+
case PASSWORD_TYPE:
|
258
245
|
if (value.isConvertibleTo(Json::stringValue)) {
|
259
246
|
return true;
|
260
247
|
} else {
|
@@ -294,6 +281,27 @@ public:
|
|
294
281
|
error = Error("'{{" + key + "}}' must be a boolean");
|
295
282
|
return false;
|
296
283
|
}
|
284
|
+
case ARRAY_TYPE:
|
285
|
+
if (value.isConvertibleTo(Json::arrayValue)) {
|
286
|
+
return true;
|
287
|
+
} else {
|
288
|
+
error = Error("'{{" + key + "}}' must be an array");
|
289
|
+
return false;
|
290
|
+
}
|
291
|
+
case STRING_ARRAY_TYPE:
|
292
|
+
if (value.isConvertibleTo(Json::arrayValue)) {
|
293
|
+
Json::Value::const_iterator it, end = value.end();
|
294
|
+
for (it = value.begin(); it != end; it++) {
|
295
|
+
if (it->type() != Json::stringValue) {
|
296
|
+
error = Error("'{{" + key + "}}' may only contain strings");
|
297
|
+
return false;
|
298
|
+
}
|
299
|
+
}
|
300
|
+
return true;
|
301
|
+
} else {
|
302
|
+
error = Error("'{{" + key + "}}' must be an array");
|
303
|
+
return false;
|
304
|
+
}
|
297
305
|
default:
|
298
306
|
P_BUG("Unknown type " + Passenger::toString((int) entry->type));
|
299
307
|
return false;
|