Skip to content

Commit

Permalink
Fix apply-remap-rule directive.
Browse files Browse the repository at this point in the history
Fix use of when directive in remap hook.
  • Loading branch information
SolidWallOfCode committed Mar 25, 2020
1 parent 08899b2 commit 42083fe
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 6 deletions.
4 changes: 3 additions & 1 deletion plugin/include/txn_box/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,18 +376,20 @@ BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, ValueMask const &
}

/// Supported hooks.
/// @internal These must be in order because that is used to check if the value for the _when_
/// directive is valid from the current hook.
enum class Hook {
INVALID, ///< Invalid hook (default initialization value).
POST_LOAD, ///< After configuration loading.
TXN_START, ///< Transaction start.
CREQ, ///< Read Request from user agent.
PRE_REMAP, ///< Before remap.
REMAP, ///< Remap (implicit).
POST_REMAP, ///< After remap.
PREQ, ///< Send request from proxy to upstream.
URSP, ///< Read response from upstream.
PRSP, ///< Send response to user agent from proxy.
TXN_CLOSE, ///< Transaction close.
REMAP, ///< Remap (implicit).
MSG ///< During plugin message handling (implicit).
};

Expand Down
24 changes: 24 additions & 0 deletions plugin/src/Features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,28 @@ void HttpFieldTuple::advance() {

Feature HttpFieldTuple::extract() const { return _current.value(); }

/* ------------------------------------------------------------------------------------ */
/** The entire URL.
* Because of the nature of the C API, this can only be a transient external string and
* therefore must be copied in to context storage.
*/
class Ex_preq_url : public StringExtractor {
public:
static constexpr TextView NAME { "preq-url" };

BufferWriter& format(BufferWriter& w, Spec const& spec, Context& ctx) override;
};

BufferWriter& Ex_preq_url::format(BufferWriter &w, Spec const &spec, Context &ctx) {
FeatureView zret;
if ( auto hdr { ctx.preq_hdr() } ; hdr.is_valid()) {
if ( ts::URL url { hdr.url() } ; url.is_valid()) {
bwformat(w, spec, url.view());
}
}
return w;
}

/* ------------------------------------------------------------------------------------ */
class Ex_preq_host : public Extractor {
public:
Expand Down Expand Up @@ -758,6 +780,7 @@ Ex_creq_field creq_field;

Ex_preq_host preq_host;

Ex_preq_url preq_url;
Ex_prsp_field prsp_field;
Ex_ursp_field ursp_field;

Expand Down Expand Up @@ -788,6 +811,7 @@ Ex_remainder_feature ex_remainder_feature;

Extractor::define(Ex_preq_host::NAME, &preq_host);

Extractor::define(Ex_preq_url::NAME, &preq_url);
Extractor::define(Ex_prsp_field::NAME, &prsp_field);
Extractor::define(Ex_ursp_field::NAME, &ursp_field);

Expand Down
12 changes: 7 additions & 5 deletions plugin/src/Machinery.cc
Original file line number Diff line number Diff line change
Expand Up @@ -312,13 +312,15 @@ Errata Do_apply_remap_rule::invoke(Context &ctx) {
// Need to do better - see if Context can provide an ArenaWriter?
swoc::LocalBufferWriter<(1<<16) - 1> url_w;
url_w.write(replacement_path);
if (request_path.size() > replacement_path.size()) {
if (replacement_path.size() > 0 && url_w.view()[replacement_path.size()-1] != '/') {
if (request_path.size() > target_path.size()) {
// Always slash separate the replacement from the remnant of the incoming request path.
if (url_w.size() && url_w.view()[url_w.size()-1] != '/') {
url_w.write('/');
}
url_w.write(request_path.substr(replacement_path.size()).ltrim('/'));
// Already have the separating slash, trim it from the target path.
url_w.write(request_path.substr(target_path.size()).ltrim('/'));
}
request_url.path_set(url_w.view());
request_url.path_set(TextView{url_w.view()}.ltrim('/'));
};

// TSUrlCopy(ctx._remap_info->requestBufp, ctx._remap_info->requestUrl, ctx._remap_info->requestBufp, ctx._remap_info->mapToUrl);
Expand Down Expand Up @@ -1541,7 +1543,7 @@ Errata With::load_case(Config & cfg, YAML::Node node) {

/* ------------------------------------------------------------------------------------ */
const std::string When::KEY { "when" };
const HookMask When::HOOKS { MaskFor({Hook::CREQ, Hook::PREQ, Hook::URSP, Hook::PRSP, Hook::PRE_REMAP, Hook::POST_REMAP }) };
const HookMask When::HOOKS { MaskFor({Hook::CREQ, Hook::PREQ, Hook::URSP, Hook::PRSP, Hook::PRE_REMAP, Hook::REMAP, Hook::POST_REMAP }) };

When::When(Hook hook_idx, Directive::Handle &&directive) : _hook(hook_idx), _directive(std::move
(directive)) {}
Expand Down

0 comments on commit 42083fe

Please sign in to comment.