-
Notifications
You must be signed in to change notification settings - Fork 11
Miscellaneous cleanup. #43
Changes from all commits
43e0b34
bcd4796
7681105
1edb94f
dea4fd0
abd09a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| /* | ||
| * Copyright 2017 Google Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| **/ | ||
| #ifndef HTTP_COMMON_H_ | ||
| #define HTTP_COMMON_H_ | ||
|
|
||
| #include <boost/network/protocol/http/client.hpp> | ||
| #include <boost/network/protocol/http/server.hpp> | ||
| #include <iostream> | ||
|
|
||
| namespace google { | ||
|
|
||
| // Allow logging request headers. | ||
| inline std::ostream& operator<<( | ||
| std::ostream& o, | ||
| const boost::network::http::basic_request<boost::network::http::tags::http_server>::headers_container_type& hv) { | ||
| o << "["; | ||
| for (const auto& h : hv) { | ||
| o << " " << h.name << ": " << h.value; | ||
| } | ||
| o << " ]"; | ||
| return o; | ||
| } | ||
|
|
||
| // Allow logging response headers. | ||
| inline std::ostream& operator<<( | ||
| std::ostream& o, | ||
| const boost::network::http::basic_response<boost::network::http::BOOST_NETWORK_HTTP_CLIENT_DEFAULT_TAG>::headers_container_type& hv) { | ||
| o << "["; | ||
| for (const auto& h : hv) { | ||
| o << " " << h.first << ": " << h.second; | ||
| } | ||
| o << " ]"; | ||
| return o; | ||
| } | ||
|
|
||
| } | ||
|
|
||
| #endif // HTTP_COMMON_H_ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -223,17 +223,13 @@ class TopLevelContext : public Context { | |
| public: | ||
| TopLevelContext() : Context(nullptr) {} | ||
| void AddValue(std::unique_ptr<Value> value) override { | ||
| if (value_ != nullptr) { | ||
| std::cerr << "Replacing " << *value_ | ||
| << " with " << *value << std::endl; | ||
| } | ||
| value_ = std::move(value); | ||
| values_.emplace_back(std::move(value)); | ||
| } | ||
| std::unique_ptr<Value> value() { | ||
| return std::move(value_); | ||
| std::vector<std::unique_ptr<Value>> values() { | ||
| return std::move(values_); | ||
| } | ||
| private: | ||
| std::unique_ptr<Value> value_; | ||
| std::vector<std::unique_ptr<Value>> values_; | ||
| }; | ||
|
|
||
| class ArrayContext : public Context { | ||
|
|
@@ -320,13 +316,12 @@ class JSONBuilder { | |
| } | ||
|
|
||
| // Top-level context only. | ||
| std::unique_ptr<Value> value() { | ||
| std::vector<std::unique_ptr<Value>> values() throw(Exception) { | ||
| TopLevelContext* top_level = dynamic_cast<TopLevelContext*>(context_); | ||
| if (top_level == nullptr) { | ||
| std::cerr << "value() called for an inner context" << std::endl; | ||
| return nullptr; | ||
| throw Exception("values() called for an inner context"); | ||
| } | ||
| return top_level->value(); | ||
| return top_level->values(); | ||
| } | ||
|
|
||
| private: | ||
|
|
@@ -424,13 +419,17 @@ yajl_callbacks callbacks = { | |
|
|
||
| } | ||
|
|
||
| std::unique_ptr<Value> Parser::FromStream(std::istream& stream) { | ||
| std::vector<std::unique_ptr<Value>> Parser::AllFromStream(std::istream& stream) | ||
| throw(Exception) | ||
| { | ||
| JSONBuilder builder; | ||
|
|
||
| const int kMax = 65536; | ||
| unsigned char data[kMax]; | ||
| yajl_handle handle = yajl_alloc(&callbacks, NULL, (void*) &builder); | ||
| yajl_config(handle, yajl_allow_comments, 1); | ||
| yajl_config(handle, yajl_allow_multiple_values, 1); | ||
| //yajl_config(handle, yajl_allow_trailing_garbage, 1); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we commenting out these two lines on purpose? If so, maybe leave a comment for the reason and under what circumstances we might want to uncomment them?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. These were robustness changes that would allow us to talk to less formalized APIs. I decided we should instead do some validation on the Kubernetes API, but if it turns out to be buggy or unstable, we may end up uncommenting these. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see. Now I understand. |
||
| //yajl_config(handle, yajl_dont_validate_strings, 1); | ||
|
|
||
| for (;;) { | ||
|
|
@@ -446,17 +445,41 @@ std::unique_ptr<Value> Parser::FromStream(std::istream& stream) { | |
|
|
||
| if (stat != yajl_status_ok) { | ||
| unsigned char* str = yajl_get_error(handle, 1, data, kMax); | ||
| // TODO cerr << str << endl; | ||
| std::string error_str((const char*)str); | ||
| yajl_free_error(handle, str); | ||
| return nullptr; | ||
| throw Exception(error_str); | ||
| } | ||
|
|
||
| yajl_free(handle); | ||
| return builder.value(); | ||
| return builder.values(); | ||
| } | ||
|
|
||
| std::unique_ptr<Value> Parser::FromStream(std::istream& stream) | ||
| throw(Exception) | ||
| { | ||
| std::vector<std::unique_ptr<Value>> all_values = AllFromStream(stream); | ||
| if (all_values.empty()) { | ||
| return nullptr; | ||
| } | ||
| if (all_values.size() > 1) { | ||
| std::ostringstream out; | ||
| out << "Single value expected, " << all_values.size() << " values seen"; | ||
| throw Exception(out.str()); | ||
| } | ||
| return std::move(all_values[0]); | ||
| } | ||
|
|
||
| std::vector<std::unique_ptr<Value>> Parser::AllFromString( | ||
| const std::string& input) throw(Exception) | ||
| { | ||
| std::istringstream stream(input); | ||
| return AllFromStream(stream); | ||
| } | ||
|
|
||
| std::unique_ptr<Value> Parser::FromString(const std::string& input) { | ||
| std::stringstream stream(input); | ||
| std::unique_ptr<Value> Parser::FromString(const std::string& input) | ||
| throw(Exception) | ||
| { | ||
| std::istringstream stream(input); | ||
| return FromStream(stream); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -247,13 +247,13 @@ class Object : public Value, public std::map<std::string, std::unique_ptr<Value> | |||
| const T* GetField(const std::string& field) const throw(Exception) { | ||||
| auto value_it = find(field); | ||||
| if (value_it == end()) { | ||||
| throw json::Exception("There is no " + field + " in " + ToString()); | ||||
| throw Exception("There is no " + field + " in " + ToString()); | ||||
| } | ||||
| if (value_it->second->type() != internal::TypeHelper<T>::type) { | ||||
| constexpr const char* name = internal::TypeHelper<T>::name; | ||||
| constexpr const char* article = internal::ArticleHelper<name[0]>::value(); | ||||
| throw json::Exception(field + " " + value_it->second->ToString() + | ||||
| " is not " + article + " " + name); | ||||
| throw Exception(field + " " + value_it->second->ToString() + | ||||
| " is not " + article + " " + name); | ||||
| } | ||||
| return value_it->second->As<T>(); | ||||
| } | ||||
|
|
@@ -267,7 +267,8 @@ class Object : public Value, public std::map<std::string, std::unique_ptr<Value> | |||
| struct FieldGetter { | ||||
| using return_type = const T*; | ||||
| static const T* GetField(const Object* obj, const std::string& field) | ||||
| throw(Exception) { | ||||
| throw(Exception) | ||||
| { | ||||
| return obj->GetField<T>(field); | ||||
| } | ||||
| }; | ||||
|
|
@@ -277,7 +278,8 @@ class Object : public Value, public std::map<std::string, std::unique_ptr<Value> | |||
| using value_type = typename std::result_of<decltype(&T::value)(T)>::type; | ||||
| using return_type = typename std::remove_reference<value_type>::type; | ||||
| static return_type GetField(const Object* obj, const std::string& field) | ||||
| throw(Exception) { | ||||
| throw(Exception) | ||||
| { | ||||
| return obj->GetField<T>(field)->value(); | ||||
| } | ||||
| }; | ||||
|
|
@@ -288,7 +290,8 @@ class Object : public Value, public std::map<std::string, std::unique_ptr<Value> | |||
| // Field accessors. | ||||
| template<class T> | ||||
| typename FieldGetter<T>::return_type Get(const std::string& field) const | ||||
| throw(Exception) { | ||||
| throw(Exception) | ||||
| { | ||||
| return FieldGetter<T>::GetField(this, field); | ||||
| } | ||||
|
|
||||
|
|
@@ -328,8 +331,14 @@ inline std::unique_ptr<Value> object( | |||
|
|
||||
| class Parser { | ||||
| public: | ||||
| static std::unique_ptr<Value> FromStream(std::istream& stream); | ||||
| static std::unique_ptr<Value> FromString(const std::string& input); | ||||
| static std::vector<std::unique_ptr<Value>> AllFromStream( | ||||
| std::istream& stream) throw(Exception); | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we limit the throw to a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahh I was confused, why is it that we need to include Line 250 in 1edb94f
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was a typo. Fixed (there and in |
||||
| static std::vector<std::unique_ptr<Value>> AllFromString( | ||||
| const std::string& input) throw(Exception); | ||||
| static std::unique_ptr<Value> FromStream(std::istream& stream) | ||||
| throw(Exception); | ||||
| static std::unique_ptr<Value> FromString(const std::string& input) | ||||
| throw(Exception); | ||||
| }; | ||||
|
|
||||
| } | ||||
|
|
||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "allow" mean in this context? The method seems straight forward though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It means "enable" -- without this method, using
log << req.headers()would fail to compile. However, "enable" is overloaded (e.g., could mean a config option), so I went with a more neutral word.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. Thanks for the clarification.