Skip to content

Instantly share code, notes, and snippets.

@nt
Created March 6, 2018 21:14
Show Gist options
  • Save nt/e97410fd29583a340c4bb8ab4c41d9b8 to your computer and use it in GitHub Desktop.
Save nt/e97410fd29583a340c4bb8ab4c41d9b8 to your computer and use it in GitHub Desktop.
#include <string>
#include <vector>
#include "envoy/http/codes.h"
#include "common/common/assert.h"
#include "common/common/enum_to_int.h"
#include "common/common/fmt.h"
#include "common/http/codes.h"
#include "common/router/config_impl.h"
namespace Envoy {
namespace Http {
namespace LazyLoad {
FilterHeadersStatus Filter::decodeHeaders(HeaderMap&, bool) {
if (config_->cm().lazyLoader() == nullptr) {
return FilterHeadersStatus::Continue;
}
Router::RouteConstSharedPtr route = callbacks_->route();
if (!route || !route->routeEntry()) {
return FilterHeadersStatus::Continue;
}
const Router::RouteEntry* route_entry = route->routeEntry();
Upstream::ThreadLocalCluster* cluster = config_->cm().get(route_entry->clusterName());
if (cluster) {
return FilterHeadersStatus::Continue;
}
cluster_name_ = route_entry->clusterName();
waiting_ = true;
config_->cm().lazyLoader()->loadCluster(route_entry->clusterName());
config_->cm().addClusterUpdateCallbacks(*this);
return FilterHeadersStatus::StopIteration;
}
FilterDataStatus Filter::decodeData(Buffer::Instance&, bool) {
return waiting_ ? FilterDataStatus::StopIterationAndWatermark : FilterDataStatus::Continue;
}
FilterTrailersStatus Filter::decodeTrailers(HeaderMap&) {
return waiting_ ? FilterTrailersStatus::StopIteration : FilterTrailersStatus::Continue;
}
void Filter::setDecoderFilterCallbacks(StreamDecoderFilterCallbacks& callbacks) {
callbacks_ = &callbacks;
}
void Filter::onDestroy() {
config_->cm().removeClusterUpdateCallbacks(*this);
}
void Filter::onClusterAddOrUpdate(const Upstream::Cluster& cluster) {
if (cluster.info()->name() != cluster_name_) {
return;
}
waiting_ = false;
config_->cm().removeClusterUpdateCallbacks(*this);
callbacks_->continueDecoding();
}
void onClusterRemoval(const Upstream::Cluster&) {}
} // namespace RateLimit
} // namespace Http
} // namespace Envoy
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include "envoy/config/filter/http/rate_limit/v2/rate_limit.pb.h"
#include "envoy/http/filter.h"
#include "envoy/local_info/local_info.h"
#include "envoy/ratelimit/ratelimit.h"
#include "envoy/runtime/runtime.h"
#include "envoy/upstream/cluster_manager.h"
#include "envoy/upstream/lazy_loader.h"
#include "common/common/assert.h"
#include "common/http/header_map_impl.h"
namespace Envoy {
namespace Http {
namespace LazyLoad {
/**
* Global configuration for the lazy load filter.
*/
class FilterConfig {
public:
FilterConfig(
const LocalInfo::LocalInfo& local_info, Stats::Scope& scope,
Runtime::Loader& runtime, Upstream::ClusterManager& cm)
: local_info_(local_info), scope_(scope), runtime_(runtime), cm_(cm) {}
const LocalInfo::LocalInfo& localInfo() const { return local_info_; }
Runtime::Loader& runtime() { return runtime_; }
Stats::Scope& scope() { return scope_; }
Upstream::ClusterManager& cm() { return cm_; }
private:
const LocalInfo::LocalInfo& local_info_;
Stats::Scope& scope_;
Runtime::Loader& runtime_;
Upstream::ClusterManager& cm_;
};
typedef std::shared_ptr<FilterConfig> FilterConfigSharedPtr;
class Filter : public StreamDecoderFilter, Upstream::ClusterUpdateCallbacks {
public:
Filter(FilterConfigSharedPtr config) : config_(config) {}
// Http::StreamFilterBase
void onDestroy() override;
// Http::StreamDecoderFilter
FilterHeadersStatus decodeHeaders(HeaderMap& headers, bool end_stream) override;
FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override;
FilterTrailersStatus decodeTrailers(HeaderMap& trailers) override;
void setDecoderFilterCallbacks(StreamDecoderFilterCallbacks& callbacks) override;
// Upstream::ClusterUpdateCallbacks
void onClusterAddOrUpdate(const Upstream::Cluster& cluster) override;
void onClusterRemoval(const Upstream::Cluster& cluster) override;
private:
FilterConfigSharedPtr config_;
StreamDecoderFilterCallbacks* callbacks_{};
std::string cluster_name_;
bool waiting_{};
};
} // namespace LazyLoad
} // namespace Http
} // namespace Envoy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment