-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
advanced filters: introduce interface for more complex filter interac…
…tions (#1029) Description: Introduces platform-bridged filter interfaces that allow stopping and stopping filter iteration, and asynchronous resumption of filter chain. The following conventions are adopted with these new interfaces: - 'Continue' is the status used to indicate HTTP entities should be forwarded when filter iteration is ongoing. - 'StopIteration' causes forwarding to halt (though invocations of the current filter will continue). - The 'ResumeIteration' status or an asynchronous resume call must be used to begin iteration and forwarding again. 'Continue' is not valid when iteration is stopped. - Using an asynchronous call to resume iteration will result in a special 'onResume' invocation of the filter, that will allow interaction with the HTTP stream on the same thread as other invocations, avoiding the need for synchronization. - Resume mechanisms offer optional parameters attached to the return status that can be used to provide parts of the stream that have not yet been forwarded. e.g., if you resume during an 'onData' invocation, you can attach headers to the 'ResumeIteration' status (and must do so, if headers have not yet been forwarded). Risk: Low Testing: Local and CI Signed-off-by: Mike Schore <mike.schore@gmail.com> Signed-off-by: JP Simard <jp@jpsim.com>
- Loading branch information
Showing
24 changed files
with
358 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
mobile/library/kotlin/src/io/envoyproxy/envoymobile/filters/AsyncRequestFilter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package io.envoyproxy.envoymobile | ||
|
||
import java.nio.ByteBuffer | ||
|
||
/* | ||
* RequestFilter supporting asynchronous resumption. | ||
*/ | ||
interface AsyncRequestFilter : RequestFilter { | ||
/** | ||
* Called by the filter manager once to initialize the filter callbacks that the filter should | ||
* use. | ||
* | ||
* @param callbacks: The callbacks for this filter to use to interact with the chain. | ||
*/ | ||
fun setRequestFilterCallbacks(callbacks: RequestFilterCallbacks) | ||
|
||
/** | ||
* Invoked explicitly in response to an asynchronous `resumeRequest()` callback when filter | ||
* iteration has been stopped. The parameters passed to this invocation will be a snapshot | ||
* of any stream state that has not yet been forwarded along the filter chain. | ||
* | ||
* As with other filter invocations, this will be called on Envoy's main thread, and thus | ||
* no additional synchronization is required between this and other invocations. | ||
* | ||
* @param headers: Headers, if `StopIteration` was returned from `onRequestHeaders`. | ||
* @param data: Any data that has been buffered where `StopIterationAndBuffer` was returned. | ||
* @param trailers: Trailers, if `StopIteration` was returned from `onRequestTrailers`. | ||
* @param endStream: True, if the stream ended with the previous (and thus, last) invocation. | ||
* | ||
* @return: The resumption status including any HTTP entities that will be forwarded. | ||
*/ | ||
fun onResumeRequest( | ||
headers: RequestHeaders?, | ||
data: ByteBuffer?, | ||
trailers: RequestTrailers?, | ||
endStream: Boolean | ||
): FilterResumeStatus<RequestHeaders, RequestTrailers> | ||
} |
38 changes: 38 additions & 0 deletions
38
mobile/library/kotlin/src/io/envoyproxy/envoymobile/filters/AsyncResponseFilter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package io.envoyproxy.envoymobile | ||
|
||
import java.nio.ByteBuffer | ||
|
||
/* | ||
* ResponseFilter supporting asynchronous resumption. | ||
*/ | ||
interface AsyncResponseFilter : ResponseFilter { | ||
/** | ||
* Called by the filter manager once to initialize the filter callbacks that the filter should | ||
* use. | ||
* | ||
* @param callbacks: The callbacks for this filter to use to interact with the chain. | ||
*/ | ||
fun setResponseFilterCallbacks(callbacks: ResponseFilterCallbacks) | ||
|
||
/** | ||
* Invoked explicitly in response to an asynchronous `resumeResponse()` callback when filter | ||
* iteration has been stopped. The parameters passed to this invocation will be a snapshot | ||
* of any stream state that has not yet been forwarded along the filter chain. | ||
* | ||
* As with other filter invocations, this will be called on Envoy's main thread, and thus | ||
* no additional synchronization is required between this and other invocations. | ||
* | ||
* @param headers: Headers, if `StopIteration` was returned from `onResponseHeaders`. | ||
* @param data: Any data that has been buffered where `StopIterationAndBuffer` was returned. | ||
* @param trailers: Trailers, if `StopIteration` was returned from `onReponseTrailers`. | ||
* @param endStream: True, if the stream ended with the previous (and thus, last) invocation. | ||
* | ||
* @return: The resumption status including any HTTP entities that will be forwarded. | ||
*/ | ||
fun onResumeResponse( | ||
headers: ResponseHeaders?, | ||
data: ByteBuffer?, | ||
trailers: ResponseTrailers?, | ||
endStream: Boolean | ||
): FilterResumeStatus<ResponseHeaders, ResponseTrailers> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 6 additions & 4 deletions
10
mobile/library/kotlin/src/io/envoyproxy/envoymobile/filters/FilterHeadersStatus.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,22 @@ | ||
package io.envoyproxy.envoymobile | ||
|
||
/* | ||
* Status returned by filters when transmitting or receiving headers. | ||
* Status to be returned by filters when transmitting or receiving headers. | ||
*/ | ||
sealed class FilterHeadersStatus<T : Headers> { | ||
/** | ||
* Continue filter chain iteration, passing the provided headers through. | ||
* | ||
* @param headers: The (potentially-modified) headers to be forwarded along the filter chain. | ||
*/ | ||
class Continue<T : Headers>(val headers: T) : FilterHeadersStatus<T>() | ||
|
||
/** | ||
* Do not iterate to any of the remaining filters in the chain with headers. | ||
* | ||
* Returning `continue` from `onRequestData()`/`onResponseData()` or calling | ||
* `continueRequest()`/`continueResponse()` MUST occur when continued filter iteration is | ||
* Returning `ResumeIteration` from another filter invocation or calling | ||
* `resumeRequest()`/`resumeResponse()` MUST occur when continued filter iteration is | ||
* desired. | ||
*/ | ||
class StopIteration<T : Headers>(val headers: T) : FilterHeadersStatus<T>() | ||
class StopIteration<T : Headers> : FilterHeadersStatus<T>() | ||
} |
28 changes: 28 additions & 0 deletions
28
mobile/library/kotlin/src/io/envoyproxy/envoymobile/filters/FilterResumeStatus.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package io.envoyproxy.envoymobile | ||
|
||
import java.nio.ByteBuffer | ||
|
||
/* | ||
* Status to be returned by filters after resuming iteration asynchronously. | ||
*/ | ||
sealed class FilterResumeStatus<T : Headers, U : Headers> { | ||
/** | ||
* Resume previously-stopped iteration, potentially forwarding headers, data, and/or trailers | ||
* that have not yet been passed along the filter chain. | ||
* | ||
* It is an error to return ResumeIteration if iteration is not currently stopped, and it is | ||
* an error to include headers if headers have already been forwarded to the next filter | ||
* (i.e. iteration was stopped during an on*Data invocation instead of on*Headers). It is also | ||
* an error to include data or trailers if `endStream` was previously set or if trailers have | ||
* already been forwarded. | ||
* | ||
* @param headers: Headers to be forwarded (if needed). | ||
* @param data: Data to be forwarded (if needed). | ||
* @param trailers: Trailers to be forwarded (if needed). | ||
*/ | ||
class ResumeIteration<T : Headers, U : Headers>( | ||
val headers: T?, | ||
val data: ByteBuffer?, | ||
val trailers: U? | ||
) : FilterResumeStatus<T, U>() | ||
} |
35 changes: 29 additions & 6 deletions
35
mobile/library/kotlin/src/io/envoyproxy/envoymobile/filters/FilterTrailersStatus.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,43 @@ | ||
package io.envoyproxy.envoymobile | ||
|
||
import java.nio.ByteBuffer | ||
|
||
/* | ||
* Status returned by filters when transmitting or receiving trailers. | ||
* Status to be returned by filters when transmitting or receiving trailers. | ||
*/ | ||
// TODO: create abstract Trailers class. | ||
sealed class FilterTrailersStatus<T : Headers> { | ||
sealed class FilterTrailersStatus<T : Headers, U : Headers> { | ||
/** | ||
* Continue filter chain iteration, passing the provided trailers through. | ||
* | ||
* @param trailers: The (potentially-modified) trailers to be forwarded along the filter chain. | ||
*/ | ||
class Continue<T : Headers>(val trailers: T) : FilterTrailersStatus<T>() | ||
class Continue<T : Headers, U : Headers>(val trailers: U) : FilterTrailersStatus<T, U>() | ||
|
||
/** | ||
* Do not iterate to any of the remaining filters in the chain with trailers. | ||
* | ||
* Calling `continueRequest()`/`continueResponse()` MUST occur when continued filter iteration | ||
* Because trailers are by definition the last HTTP entity of a request or response, only | ||
* asynchronous filters support resumption after returning `StopIteration` from on*Trailers. | ||
* Calling `resumeRequest()`/`resumeResponse()` MUST occur if continued filter iteration | ||
* is desired. | ||
*/ | ||
class StopIteration<T : Headers>(val trailers: T) : FilterTrailersStatus<T>() | ||
class StopIteration<T : Headers, U : Headers> : FilterTrailersStatus<T, U>() | ||
|
||
/** | ||
* Resume previously-stopped iteration, possibly forwarding headers and data if iteration was | ||
* stopped during an on*Headers or on*Data invocation. | ||
* | ||
* It is an error to return `ResumeIteration` if iteration is not currently stopped, and it is | ||
* an error to include headers if headers have already been forwarded to the next filter | ||
* (i.e. iteration was stopped during an on*Data invocation instead of on*Headers). | ||
* | ||
* @param headers: Headers to be forwarded (if needed). | ||
* @param data: Data to be forwarded (if needed). | ||
* @param trailers: Trailers to be forwarded. | ||
*/ | ||
class ResumeIteration<T : Headers, U : Headers>( | ||
val headers: T?, | ||
val data: ByteBuffer?, | ||
val trailers: U? | ||
) : FilterTrailersStatus<T, U>() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.