Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TS-4042: Add feature to buffer request body before making downstream requests #351

Closed
wants to merge 4 commits into from

Conversation

bgaff
Copy link
Member

@bgaff bgaff commented Nov 25, 2015

We need a way to examine the request body without making a downstream request, this feature has many use cases including:

  • Ability to buffer the body and ensure a full post is received before committing downstream resources.
  • Ability to choose an origin based on request body
  • Ability to do request content filtering such as a WAF might provide before the origin is involved.

Today you have two options to inspect a request body:

  1. Transformations: the problem with transformations is that you only start receiving the request bytes after a sink has been established, which in this case is the downstream origin.
  2. Create an intercept and use fetch apis to then send the downstream request: while this technically works it turns out to be a ton of code and is in general pretty problematic, we actually tried this approach for a while and had nothing but problems with it.

We feel it would be ideal if we could intercept the body without breaking the normal ATS state flow. There used to exist code (and it's still in the core just #ifdefed out) to drain the request body. I use that code as the basis for this request buffering code. We added APIs to both the C and C++ APIs so that this request buffering can be enabled from a plugin and the plugin can inspect the body as chunks arrive or when it's complete. We've included an example plugin that will error a transaction if a minimum rate of transfer is not maintained. We've been using a very similar method in the core for buffer request bodies for several months without issues so the code that is new (for us) is basically all the API stuff.

I'm confident that this feature will bring plenty of questions / feedback, so let's get that party started. @zwoop @SolidWallOfCode @jpeach @sudheerv : if you have time would you mind commenting / reviewing.

cc. @jacksontj @zizhong @canselcik

@jacksontj
Copy link
Contributor

Glad to see this PR finally make its way out :) We've been running with the base for this PR for quite a while. In addition to simplifying the code-- it really cleans up metrics/debugging as we are no longer required to loop requests back through the state machine.

@jpeach
Copy link
Contributor

jpeach commented Nov 26, 2015

I quickly scanned the diff. The API changes will still need to go through API review on dev@. Documentation for the new APIs should be done as an API man page in the main documentation rather than in headerdoc (perfectly OK to do that as a subsequent patch).

@bgaff
Copy link
Member Author

bgaff commented Nov 29, 2015

@jpeach sure thing. Does anyone else have comments regarding the approach before we discuss the individual APIs?

@sudheerv
Copy link
Contributor

+1 on the approach.

A specific comment on a quick scan of the code - it seems like the patch only handles the case with Content-Length header, what about Chunked-Encoding or H2/SPDY scenarios that don't present the Content-Length header?

@bgaff
Copy link
Member Author

bgaff commented Dec 7, 2015

@sudheerv , the chunked encoding case is one that I don't think any browser actually does, have you ever seen a browser make a request w/ chunked encoding if so I'll have to look into that case.

@bgaff
Copy link
Member Author

bgaff commented Dec 7, 2015

@sudheerv, I've asked @zizhong to help in addressing the transfer-encoding chunked case, we should have an update soon.

@bgaff
Copy link
Member Author

bgaff commented Dec 14, 2015

@sudheerv / @jpeach this pull request has been updated w/ tests for the chunked encoding case that @sudheerv was concerned about. Please let me know if you have any other questions about this?

@sudheerv
Copy link
Contributor

@bgaff - Thanks, I'd have to double check though that the change made automatically handles a H2/SPDY upload. There's no Content-Length, nor even a TE header in those cases (although, perhaps, ATS implementation may make it appear like CHUNKED_ENCODING from FetchSM to HttpSM layer?)

@bgaff
Copy link
Member Author

bgaff commented Dec 14, 2015

That's correct since both use fetchsm if just works like a normal http 1.1 request, as that's what fetch sm is. I've verified this functionality.

@sudheerv
Copy link
Contributor

Cool, thanks!

@bgaff
Copy link
Member Author

bgaff commented Jan 5, 2016

Any other questions about this?

@bryancall
Copy link
Contributor

Talking at the github meeting. We should have a maximum size that will be buffered in memory. This should go through API review. Please provide documentation on the APIs.

@zwoop
Copy link
Contributor

zwoop commented Mar 22, 2016

ping on API review?

@zwoop
Copy link
Contributor

zwoop commented Jun 27, 2016

@bgaff What do you want to do with this? It's been sitting here for quite a while.

@zwoop zwoop added this to the 7.0.0 milestone Jun 27, 2016
consumed += data_len;
block = TSIOBufferBlockNext(block);
}
// play with the body
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you copying the body if you aren't doing anything with it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is just a demo plugin that shows we can get the body.

@bryancall
Copy link
Contributor

Looking over the pull request I didn't see any limits on how much is going to be buffered on the server. It might be good to start the transfer to the origin once a configurable limite gets reached.

@jacksontj
Copy link
Contributor

@bryancall it'd be nice if we could have some way to "re-enable" the bytes-- such that a plugin could either buffer everything or stream (since the "buffer everything" case is a possible use-case.

@zwoop zwoop modified the milestones: 7.1.0, 7.0.0 Sep 15, 2016
@zwoop zwoop modified the milestones: 7.1.0, 7.2.0 Jan 8, 2017
@zwoop zwoop modified the milestones: 7.2.0, 7.1.0 Jan 8, 2017
@zizhong
Copy link
Member

zizhong commented Jan 24, 2017

@bgaff @bryancall @zwoop What are the remaining works to get this pull request merged? Is there anything I can help with?

As a summary in this thread,

  1. add a limit for the buffered body;
  2. API review.

What else?

@bryancall
Copy link
Contributor

I haven't seen an update to this PR for awhile. I will close it in a week if it hasn't been updated.

@bgaff
Copy link
Member Author

bgaff commented Jan 24, 2017

I can help, @zizhong what of the previous asks haven't been completed?

@zizhong
Copy link
Member

zizhong commented Jan 24, 2017

Thanks, @bgaff . After reading the previous comments, I think @bryancall suggested there should be a limit for the request body. And have you guys done API review about this PR?

SolidWallOfCode pushed a commit to SolidWallOfCode/trafficserver that referenced this pull request Feb 1, 2017
YTSATS-1085: url-encoding the Location header
@zizhong
Copy link
Member

zizhong commented Mar 6, 2017

@bryancall @bgaff @zwoop @SolidWallOfCode @jpeach @sudheerv Local patches of request buffer we have in Linkedin ATS repo really hurt us a lot(merge issues, etc). I'll work on updating this PR and push it out.
Before that, just want to make sure that upstream still agree on this approach.

@zwoop zwoop modified the milestones: 7.2.0, 8.0.0 Apr 25, 2017
@bryancall bryancall closed this May 15, 2017
@zwoop zwoop removed this from the 8.0.0 milestone May 25, 2017
bneradt pushed a commit to bneradt/trafficserver that referenced this pull request Nov 19, 2020
moonchen pushed a commit to moonchen/trafficserver that referenced this pull request Jul 26, 2022
* change MemArena::make test to remove memory leak (apache#8352)

(cherry picked from commit 2a6156f)

* Fix leaks in ConfigManager::configName (apache#8269)

This fixes an ASan reported leak of ConfigManager::configName. It used
to be strdup'd but not freed in the destructor. This simply changes it
to a std::string.

ASan also reported a leak in AddConfigFilesHere which is fixed with an
ats_free as well.

(cherry picked from commit ee820c7)

* Lua plugin memory leak on remap configuration reloads (apache#8764)

This fix adds reference counting for the Lua plugin remap instance handles. The reference counting
allows us to eliminate an existing memory leak of the instance handles. In addition, this means
that the old Lua memory allocated by LuaJIT may also be freed via LuaJIT garbage collection.

This fix also adds the '--ljgc' remap instance plugin parameter to the Lua plugin. This paramter
enables on-demand LuaJIT garbage collection while the remap instances are created and deleted.
This is useful when operating close to the LuaJIT memory limit, which is currently 2GB on Linux
using LuaJIT v2.1.0-beta3 from 2017.

Fixes apache#8728

(cherry picked from commit b6f83f1)

* Fixes leak of SNI config filename on load

(cherry picked from commit e99f33c)

* Fixes leak of ssl_ocsp_response_path_only on reload

(cherry picked from commit 18c5404)

* SNIConfig (tunnel_route): Change the way we extract matched subgroups from the server name. (apache#8589)

This now uses the provided offsets from pcre_exec to read each matched group, this avoids
allocating memory for the subgroups. There was a memory leak here as well which is now eliminated.
This also changes the ActionItem::Context vector of strings to a vector of views to keep each matched group.

(cherry picked from commit 4f0c4f2)

Conflicts:
    iocore/net/P_SSLSNI.h
    iocore/net/TLSSNISupport.cc

* Fixes leak in SNIAction name globbing (apache#8827)

pcre_compile allocated object is never pcre_free-ed

(cherry picked from commit efaf441)

Conflicts:
    iocore/net/P_SSLSNI.h

Co-authored-by: Brian Olsen <bnolsen@gmail.com>
Co-authored-by: Brian Neradt <brian.neradt@gmail.com>
Co-authored-by: pbchou <pbchou@labs.att.com>
Co-authored-by: Damian Meden <damian.meden@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants