diff --git a/docs/filters/ProtobufFilter.md b/docs/filters/ProtobufFilter.md new file mode 100644 index 000000000..535f6faf5 --- /dev/null +++ b/docs/filters/ProtobufFilter.md @@ -0,0 +1,68 @@ +## protobufFilter + +### Description + +Select exchanges having a protobuf request or response body. Filtering is made by inspecting value of `Content-Type` header on both request and response. + +### Evaluation scope + +Evaluation scope defines the timing where this filter will be applied. + +{.alert .alert-info} +::: +**responseHeaderReceivedFromRemote** This scope occurs the moment fluxzy has done parsing the response header. +::: + +### YAML configuration name + + protobufFilter + +### Settings + +This filter has no specific characteristic + +The following table describes the customizable properties available for this filter: + +{.property-table .property-table-filter} +::: +| Property | Type | Description | DefaultValue | +| :------- | :------- | :------- | -------- | +| inverted | boolean | Negate the filter result | false | +::: + +### Example of usage + +The following examples apply a comment to the filtered exchange + +Select exchanges with protobuf request or response body. + +```yaml +rules: +- filter: + typeKind: ProtobufFilter + actions: + - typeKind: ApplyCommentAction + comment: filter was applied +``` + + +Select exchanges without any protobuf body. + +```yaml +rules: +- filter: + typeKind: ProtobufFilter + actions: + - typeKind: ApplyCommentAction + comment: filter was applied +``` + + +### .NET reference + +View definition of [ProtobufFilter](https://docs.fluxzy.io/api/Fluxzy.Rules.Filters.ProtobufFilter.html) for .NET integration. + +### See also + +This filter has no related filter + diff --git a/docs/filters/ProtobufRequestFilter.md b/docs/filters/ProtobufRequestFilter.md new file mode 100644 index 000000000..ce9024f90 --- /dev/null +++ b/docs/filters/ProtobufRequestFilter.md @@ -0,0 +1,68 @@ +## protobufRequestFilter + +### Description + +Select requests sending a protobuf body. Filtering is made by inspecting value of `Content-Type` header. + +### Evaluation scope + +Evaluation scope defines the timing where this filter will be applied. + +{.alert .alert-info} +::: +**requestBodyReceivedFromClient** This scope occurs the moment fluxzy received fully the request body from the client. In a fullstreaming mode which is the default mode, this event occurs when the full body is already fully sent to the remote server. +::: + +### YAML configuration name + + protobufRequestFilter + +### Settings + +This filter has no specific characteristic + +The following table describes the customizable properties available for this filter: + +{.property-table .property-table-filter} +::: +| Property | Type | Description | DefaultValue | +| :------- | :------- | :------- | -------- | +| inverted | boolean | Negate the filter result | false | +::: + +### Example of usage + +The following examples apply a comment to the filtered exchange + +Select only exchanges with protobuf request body. + +```yaml +rules: +- filter: + typeKind: ProtobufRequestFilter + actions: + - typeKind: ApplyCommentAction + comment: filter was applied +``` + + +Select exchanges without protobuf request body. + +```yaml +rules: +- filter: + typeKind: ProtobufRequestFilter + actions: + - typeKind: ApplyCommentAction + comment: filter was applied +``` + + +### .NET reference + +View definition of [ProtobufRequestFilter](https://docs.fluxzy.io/api/Fluxzy.Rules.Filters.RequestFilters.ProtobufRequestFilter.html) for .NET integration. + +### See also + +This filter has no related filter + diff --git a/docs/filters/ProtobufResponseFilter.md b/docs/filters/ProtobufResponseFilter.md new file mode 100644 index 000000000..7e2fdaabb --- /dev/null +++ b/docs/filters/ProtobufResponseFilter.md @@ -0,0 +1,68 @@ +## protobufResponseFilter + +### Description + +Select exchanges having protobuf response body. The content-type header is checked to determine if the content body is protobuf. + +### Evaluation scope + +Evaluation scope defines the timing where this filter will be applied. + +{.alert .alert-info} +::: +**responseHeaderReceivedFromRemote** This scope occurs the moment fluxzy has done parsing the response header. +::: + +### YAML configuration name + + protobufResponseFilter + +### Settings + +This filter has no specific characteristic + +The following table describes the customizable properties available for this filter: + +{.property-table .property-table-filter} +::: +| Property | Type | Description | DefaultValue | +| :------- | :------- | :------- | -------- | +| inverted | boolean | Negate the filter result | false | +::: + +### Example of usage + +The following examples apply a comment to the filtered exchange + +Select only exchanges with protobuf response body. + +```yaml +rules: +- filter: + typeKind: ProtobufResponseFilter + actions: + - typeKind: ApplyCommentAction + comment: filter was applied +``` + + +Select exchanges without protobuf response body. + +```yaml +rules: +- filter: + typeKind: ProtobufResponseFilter + actions: + - typeKind: ApplyCommentAction + comment: filter was applied +``` + + +### .NET reference + +View definition of [ProtobufResponseFilter](https://docs.fluxzy.io/api/Fluxzy.Rules.Filters.ResponseFilters.ProtobufResponseFilter.html) for .NET integration. + +### See also + +This filter has no related filter + diff --git a/docs/searchable-items.json b/docs/searchable-items.json index 910fe3473..390f70950 100644 --- a/docs/searchable-items.json +++ b/docs/searchable-items.json @@ -1 +1 @@ -[{"title":"anyFilter","description":"Select all exchanges","fullTypeName":"Fluxzy.Rules.Filters.AnyFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"commentSearchFilter","description":"Select exchanges by searching a string pattern into the comment property.","fullTypeName":"Fluxzy.Rules.Filters.CommentSearchFilter","category":"Filter","scope":"outOfScope"},{"title":"filterCollection","description":"FilterCollection is a combination of multiple filters with a merging operator (OR / AND).","fullTypeName":"Fluxzy.Rules.Filters.FilterCollection","category":"Filter","scope":"onAuthorityReceived"},{"title":"hasCommentFilter","description":"Select exchanges having comment.","fullTypeName":"Fluxzy.Rules.Filters.HasCommentFilter","category":"Filter","scope":"outOfScope"},{"title":"hasTagFilter","description":"Select exchanges having tag.","fullTypeName":"Fluxzy.Rules.Filters.HasTagFilter","category":"Filter","scope":"outOfScope"},{"title":"ipEgressFilter","description":"Select exchanges according to upstream IP address. Full IP notation is used from IPv6.","fullTypeName":"Fluxzy.Rules.Filters.IpEgressFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"ipIngressFilter","description":"Select exchanges according to client ip address. Full IP notation is used from IPv6.","fullTypeName":"Fluxzy.Rules.Filters.IpIngressFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"isWebSocketFilter","description":"Select websocket exchange.","fullTypeName":"Fluxzy.Rules.Filters.IsWebSocketFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"contentTypeXmlFilter","description":"Select exchanges having XML response body.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.ContentTypeXmlFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"cssStyleFilter","description":"Select exchanges having response content type mime matching css.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.CssStyleFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"fontFilter","description":"Select exchanges having response content type matching a font payload.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.FontFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"htmlResponseFilter","description":"Select exchanges having HTML body. The content-type header is checked to determine if the content body is has text/html hint.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.HtmlResponseFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"imageFilter","description":"Select exchanges having response content type mime matching image.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.ImageFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"jsonResponseFilter","description":"Select exchanges having JSON response body. The content-type header is checked to determine if the content body is a JSON.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.JsonResponseFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"networkErrorFilter","description":"Select exchanges that fails due to network error.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.NetworkErrorFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"responseHeaderFilter","description":"Select exchanges according to response header values.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.ResponseHeaderFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"statusCodeClientErrorFilter","description":"Select exchanges that HTTP status code indicates a client error (4XX).","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.StatusCodeClientErrorFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"statusCodeFilter","description":"Select exchanges according to HTTP status code.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.StatusCodeFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"statusCodeRedirectionFilter","description":"Select exchanges that HTTP status code indicates a redirect (3XX).","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.StatusCodeRedirectionFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"statusCodeServerErrorFilter","description":"Select exchanges that HTTP status code indicates a server/intermediary error (5XX).","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.StatusCodeServerErrorFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"statusCodeSuccessFilter","description":"Select exchanges that HTTP status code indicates a successful request (2XX).","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.StatusCodeSuccessFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"absoluteUriFilter","description":"Select exchanges according to URI (scheme, FQDN, path and query). Supports common string search option and regular expression.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.AbsoluteUriFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"agentLabelFilter","description":"Select exchanges according to configured source agent (user agent or process) with a regular string search.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.AgentLabelFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"authorityFilter","description":"Select exchange according to hostname and a port","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.AuthorityFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"deleteFilter","description":"Select exchanges with DELETE method","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.DeleteFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"formRequestFilter","description":"Select request sending \u0027multipart/form-data\u0027 or \u0027application/x-www-form-urlencoded\u0027 body. Filtering is made by inspecting value of \u0060Content-Type\u0060 header","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.FormRequestFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"formUrlEncodedRequestFilter","description":"Select request sending \u0027application/x-www-form-urlencoded\u0027 body. Filtering is made by inspecting value of \u0060Content-Type\u0060 header","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.FormUrlEncodedRequestFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"getFilter","description":"Select exchanges with GET method","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.GetFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"h11TrafficOnlyFilter","description":"Select HTTP/1.1 exchanges only.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.H11TrafficOnlyFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"h2TrafficOnlyFilter","description":"Select H2 exchanges only.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.H2TrafficOnlyFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"hasAnyCookieOnRequestFilter","description":"Select exchanges having any request cookie","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasAnyCookieOnRequestFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"hasAuthorizationBearerFilter","description":"Select exchanges having bearer token in authorization.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasAuthorizationBearerFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"hasAuthorizationFilter","description":"Select exchanges having authorization header.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasAuthorizationFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"hasCookieOnRequestFilter","description":"Exchange having a request cookie with a specific name","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasCookieOnRequestFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"hasRequestBodyFilter","description":"Select request having body.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasRequestBodyFilter","category":"Filter","scope":"responseBodyReceivedFromRemote"},{"title":"hasSetCookieOnResponseFilter","description":"Search for a cookie value present in a \u0060set-cookie\u0060 header response.If cookie name is not defined or empty, the filter will returns any cookie having the value.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasSetCookieOnResponseFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"hostFilter","description":"Select exchanges according to hostname (excluding port). To select authority (combination of host:port), use \u003Cgoto\u003EAuthorityFilter\u003C/goto\u003E.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HostFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"isGrpcFilter","description":"Select gRPC exchanges only. Filtering is made by inspecting value of \u0060Content-Type\u0060 header.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.IsGrpcFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"isSecureFilter","description":"Select secure exchange only (non plain HTTP).","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.IsSecureFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"jsonRequestFilter","description":"Select request sending JSON body. Filtering is made by inspecting value of \u0060Content-Type\u0060 header","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.JsonRequestFilter","category":"Filter","scope":"requestBodyReceivedFromClient"},{"title":"methodFilter","description":"Select exchanges according to request method.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.MethodFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"multipartDataRequestFilter","description":"Select request sending \u0027multipart/form-data\u0027 body. Filtering is made by inspecting value of \u0060Content-Type\u0060 header","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.MultipartDataRequestFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"patchFilter","description":"Select exchanges with PATCH method","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.PatchFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"pathFilter","description":"Select exchanges according to url path. Path includes query string if any. Path must start with \u0060/\u0060","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.PathFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"postFilter","description":"Select POST (request method) only exchanges.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.PostFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"processIdFilter","description":"Select exchanges initiated by a process with the specified process ID. Process tracking must be enabled and the connection must originate from localhost.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.ProcessIdFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"processNameFilter","description":"Select exchanges initiated by processes with the specified names. Process names are matched case-insensitively. On Windows, the .exe extension can be omitted. Process tracking must be enabled and the connection must originate from localhost.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.ProcessNameFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"putFilter","description":"Select exchanges according to request method.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.PutFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"queryStringFilter","description":"Select exchanges containing a specific query string. If \u0060name\u0060 is not defined or empty, the search will be performed on any query string values.The search will pass if at least one value match.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.QueryStringFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"requestHeaderFilter","description":"Select exchanges according to request header values.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.RequestHeaderFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"abortAction","description":"Abort an exchange at the transport level. This action will close connection between fluxzy and client which may lead to depended exchanges to be aborted too.","fullTypeName":"Fluxzy.Rules.Actions.AbortAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"addAuthorizationBasicAction","description":"Add Authorization Basic to the request header.","fullTypeName":"Fluxzy.Rules.Actions.AddAuthorizationBasicAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"addAuthorizationBearerAction","description":"Add Authorization Bearer token to the request header.","fullTypeName":"Fluxzy.Rules.Actions.AddAuthorizationBearerAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"addRequestHeaderAction","description":"Append a request header.","fullTypeName":"Fluxzy.Rules.Actions.AddRequestHeaderAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"addResponseHeaderAction","description":"Append a response header. H2 pseudo header will be ignored.","fullTypeName":"Fluxzy.Rules.Actions.AddResponseHeaderAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"applyCommentAction","description":"Add comment to exchange. Comment has no effect on the stream behaviour.","fullTypeName":"Fluxzy.Rules.Actions.ApplyCommentAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"applyTagAction","description":"Affect a tag to exchange. Tags are meta-information and do not alter the connection.","fullTypeName":"Fluxzy.Rules.Actions.ApplyTagAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"averageThrottleAction","description":"Throttle and simulate bandwidth condition.","fullTypeName":"Fluxzy.Rules.Actions.AverageThrottleAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"changeRequestMethodAction","description":"Alter the method of an exchange.","fullTypeName":"Fluxzy.Rules.Actions.ChangeRequestMethodAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"changeRequestPathAction","description":"Change request uri path. This action alters only the path of the request. Request path includes query string.","fullTypeName":"Fluxzy.Rules.Actions.ChangeRequestPathAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"delayAction","description":"Add a latency to the exchange.","fullTypeName":"Fluxzy.Rules.Actions.DelayAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"deleteRequestHeaderAction","description":"Remove request headers. This action removes \u003Cb\u003Eevery\u003C/b\u003E occurrence of the header from the request.","fullTypeName":"Fluxzy.Rules.Actions.DeleteRequestHeaderAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"deleteResponseHeaderAction","description":"Remove response headers. This action removes \u003Cb\u003Eevery\u003C/b\u003E occurrence of the header from the response.","fullTypeName":"Fluxzy.Rules.Actions.DeleteResponseHeaderAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"fileAppendAction","description":"Write to a file. Captured variable are interpreted.","fullTypeName":"Fluxzy.Rules.Actions.FileAppendAction","category":"Action","scope":"copySibling"},{"title":"forceHttp11Action","description":"Force the connection between fluxzy and remote to be HTTP/1.1. This value is enforced by ALPN settings set during the SSL/Handshake handshake.","fullTypeName":"Fluxzy.Rules.Actions.ForceHttp11Action","category":"Action","scope":"onAuthorityReceived"},{"title":"forceHttp2Action","description":"Forces the connection between fluxzy and remote to be HTTP/2.0. This value is enforced when setting up ALPN settings during SSL/TLS negotiation. \u003Cbr/\u003EThe exchange will break if the remote does not support HTTP/2.0. \u003Cbr/\u003EThis action will be ignored when the communication is clear (h2c not supported).","fullTypeName":"Fluxzy.Rules.Actions.ForceHttp2Action","category":"Action","scope":"onAuthorityReceived"},{"title":"forceRemotePortAction","description":"Ignores the default port used by the current authority and use the provided port instead.","fullTypeName":"Fluxzy.Rules.Actions.ForceRemotePortAction","category":"Action","scope":"onAuthorityReceived"},{"title":"forceTlsVersionAction","description":"Force the usage of a specific TLS version. Values can be chosen among : Tls, Tls11, Tls12, Tls13, Ssl3, Ssl2. \u003Cbr/\u003EForcing the usage of a specific TLS version can break the exchange if the remote does not support the requested protocol.","fullTypeName":"Fluxzy.Rules.Actions.ForceTlsVersionAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"forwardAction","description":"Forward request to a specific URL. This action makes fluxzy act as a reverse proxy. Unlike [SpoofDnsAction](https://www.fluxzy.io/rule/item/spoofDnsAction), host header is automatically set and protocol switch is supported (http to https, http/1.1 to h2, ...). The URL must be an absolute path.","fullTypeName":"Fluxzy.Rules.Actions.ForwardAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"impersonateAction","description":"Impersonate a browser or client by changing the TLS fingerprint, HTTP/2 settings and headers.","fullTypeName":"Fluxzy.Rules.Actions.ImpersonateAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"mountCertificateAuthorityAction","description":"Reply with the default root certificate used by fluxzy","fullTypeName":"Fluxzy.Rules.Actions.MountCertificateAuthorityAction","category":"Action","scope":"dnsSolveDone"},{"title":"noOpAction","description":"An action doing no operation.","fullTypeName":"Fluxzy.Rules.Actions.NoOpAction","category":"Action","scope":"requestBodyReceivedFromClient"},{"title":"removeCacheAction","description":"Remove all cache directive from request and response headers. This will force the clientto ask the latest version of the requested resource.","fullTypeName":"Fluxzy.Rules.Actions.RemoveCacheAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"setClientCertificateAction","description":"Add a client certificate to the exchange. The client certificate will be used for establishing the mTLS authentication if the remote request it. The client certificate can be retrieved from the default store (my) or from a PKCS#12 file (.p12, pfx). \u003Cbr/\u003EThe certificate will not be stored in fluxzy settings and, therefore, must be available at runtime. ","fullTypeName":"Fluxzy.Rules.Actions.SetClientCertificateAction","category":"Action","scope":"onAuthorityReceived"},{"title":"setJa3FingerPrintAction","description":"Set a JA3 fingerprint of ongoing connection.","fullTypeName":"Fluxzy.Rules.Actions.SetJa3FingerPrintAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"setUserAgentAction","description":"Change the User-AgentThis action is used to change the User-Agent header of the request from a list of built-in user-agent values.","fullTypeName":"Fluxzy.Rules.Actions.SetUserAgentAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"setVariableAction","description":"Set a variable or update an existing","fullTypeName":"Fluxzy.Rules.Actions.SetVariableAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"skipRemoteCertificateValidationAction","description":"Skip validating remote certificate. Fluxzy will ignore any validation errors on the server certificate.","fullTypeName":"Fluxzy.Rules.Actions.SkipRemoteCertificateValidationAction","category":"Action","scope":"onAuthorityReceived"},{"title":"skipSslTunnelingAction","description":"Instructs fluxzy to not decrypt the current traffic. The associated filter must be on OnAuthorityReceived scope in order to make this action effective. ","fullTypeName":"Fluxzy.Rules.Actions.SkipSslTunnelingAction","category":"Action","scope":"onAuthorityReceived"},{"title":"spoofDnsAction","description":"Fix statically the remote ip or port disregards to the dns or host resolution of the current running system. Use this action to force the resolution of a hostname to a fixed IP address. ","fullTypeName":"Fluxzy.Rules.Actions.SpoofDnsAction","category":"Action","scope":"onAuthorityReceived"},{"title":"stdErrAction","description":"Write text to standard error. Captured variable are interpreted.","fullTypeName":"Fluxzy.Rules.Actions.StdErrAction","category":"Action","scope":"copySibling"},{"title":"stdOutAction","description":"Write text to standard output. Captured variable are interpreted.","fullTypeName":"Fluxzy.Rules.Actions.StdOutAction","category":"Action","scope":"outOfScope"},{"title":"updateRequestHeaderAction","description":"Update and existing request header. If the header does not exists in the original request, the header will be added. \u003Cbr/\u003EUse {{previous}} keyword to refer to the original value of the header. \u003Cbr/\u003E\u003Cstrong\u003ENote\u003C/strong\u003E Headers that alter the connection behaviour will be ignored.","fullTypeName":"Fluxzy.Rules.Actions.UpdateRequestHeaderAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"updateResponseHeaderAction","description":"Update and existing response header. If the header does not exists in the original response, the header will be added.\u003Cbr/\u003EUse {{previous}} keyword to refer to the original value of the header.\u003Cbr/\u003E\u003Cstrong\u003ENote\u003C/strong\u003E Headers that alter the connection behaviour will be ignored.","fullTypeName":"Fluxzy.Rules.Actions.UpdateResponseHeaderAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"upStreamProxyAction","description":"Use an upstream proxy.","fullTypeName":"Fluxzy.Rules.Actions.UpStreamProxyAction","category":"Action","scope":"onAuthorityReceived"},{"title":"useCertificateAction","description":"Use a specific server certificate. Certificate can be retrieved from user store or from a PKCS12 file","fullTypeName":"Fluxzy.Rules.Actions.UseCertificateAction","category":"Action","scope":"onAuthorityReceived"},{"title":"useDnsOverHttpsAction","description":"Use DoH (DNS over HTTPS) to resolve domain names instead of the default DNS provided by the OS","fullTypeName":"Fluxzy.Rules.Actions.UseDnsOverHttpsAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"addBasicAuthenticationAction","description":"Add a basic authentication (RFC 7617) to incoming exchanges with an username and a password","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.AddBasicAuthenticationAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"applySessionAction","description":"Apply captured session data to requests. Adds cookies from session store and optionally applies stored headers. Works in conjunction with CaptureSessionAction.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.ApplySessionAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"captureSessionAction","description":"Capture session data from responses. Captures Set-Cookie headers and optionally other headers like Authorization. Can also capture cookies from request headers for intercepting ongoing sessions. Stored data can be replayed using ApplySessionAction.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.CaptureSessionAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"clearSessionAction","description":"Clear stored session data for a specific domain or all domains.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.ClearSessionAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"injectHtmlTagAction","description":"This action stream a response body and inject a text after the first specified html tag.This action can be used to inject a html code snippet after opening \u0060\u003Chead\u003E\u0060 tag in any traversing html page.This action supports chunked transfer stream and the following body encodings: gzip, deflate, brotli and lzw.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.InjectHtmlTagAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"mockedResponseAction","description":"Reply with a pre-made response from a raw text or file","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.MockedResponseAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"mountWelcomePageAction","description":"Reply with fluxzy welcome page","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.MountWelcomePageAction","category":"Action","scope":"dnsSolveDone"},{"title":"rejectAction","description":"Block the request and return HTTP 403 Forbidden response. Use this action to explicitly deny access to specific resources. This is a simple blocking action with no configuration required.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.RejectAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"rejectWithMessageAction","description":"Block the request with a custom HTTP error response including a body message. Useful for providing detailed blocking reasons to end users. Supports text/plain, text/html, and application/json content types.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.RejectWithMessageAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"rejectWithStatusCodeAction","description":"Block the request and return a custom HTTP error response. Allows specifying the status code (e.g., 403, 404, 502) to return to the client. The response body will contain the standard reason phrase for the status code.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.RejectWithStatusCodeAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"removeResponseCookieAction","description":"Remove a response cookie by setting the expiration date to a past date.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.RemoveResponseCookieAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"serveDirectoryAction","description":"Serve a folder as a static web site. This action is made for mocking purpose and not production ready for a web site.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.ServeDirectoryAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"setRequestCookieAction","description":"Add a cookie to request. This action is performed by adding/replacing \u0060Cookie\u0060 header in request.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.SetRequestCookieAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"setResponseCookieAction","description":"Add a response cookie. This action is performed by adding \u0060Set-Cookie\u0060 header in response.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.SetResponseCookieAction","category":"Action","scope":"responseHeaderReceivedFromRemote"}] \ No newline at end of file +[{"title":"anyFilter","description":"Select all exchanges","fullTypeName":"Fluxzy.Rules.Filters.AnyFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"commentSearchFilter","description":"Select exchanges by searching a string pattern into the comment property.","fullTypeName":"Fluxzy.Rules.Filters.CommentSearchFilter","category":"Filter","scope":"outOfScope"},{"title":"filterCollection","description":"FilterCollection is a combination of multiple filters with a merging operator (OR / AND).","fullTypeName":"Fluxzy.Rules.Filters.FilterCollection","category":"Filter","scope":"onAuthorityReceived"},{"title":"hasCommentFilter","description":"Select exchanges having comment.","fullTypeName":"Fluxzy.Rules.Filters.HasCommentFilter","category":"Filter","scope":"outOfScope"},{"title":"hasTagFilter","description":"Select exchanges having tag.","fullTypeName":"Fluxzy.Rules.Filters.HasTagFilter","category":"Filter","scope":"outOfScope"},{"title":"ipEgressFilter","description":"Select exchanges according to upstream IP address. Full IP notation is used from IPv6.","fullTypeName":"Fluxzy.Rules.Filters.IpEgressFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"ipIngressFilter","description":"Select exchanges according to client ip address. Full IP notation is used from IPv6.","fullTypeName":"Fluxzy.Rules.Filters.IpIngressFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"isWebSocketFilter","description":"Select websocket exchange.","fullTypeName":"Fluxzy.Rules.Filters.IsWebSocketFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"protobufFilter","description":"Select exchanges having a protobuf request or response body. Filtering is made by inspecting value of \u0060Content-Type\u0060 header on both request and response.","fullTypeName":"Fluxzy.Rules.Filters.ProtobufFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"contentTypeXmlFilter","description":"Select exchanges having XML response body.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.ContentTypeXmlFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"cssStyleFilter","description":"Select exchanges having response content type mime matching css.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.CssStyleFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"fontFilter","description":"Select exchanges having response content type matching a font payload.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.FontFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"htmlResponseFilter","description":"Select exchanges having HTML body. The content-type header is checked to determine if the content body is has text/html hint.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.HtmlResponseFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"imageFilter","description":"Select exchanges having response content type mime matching image.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.ImageFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"jsonResponseFilter","description":"Select exchanges having JSON response body. The content-type header is checked to determine if the content body is a JSON.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.JsonResponseFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"networkErrorFilter","description":"Select exchanges that fails due to network error.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.NetworkErrorFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"protobufResponseFilter","description":"Select exchanges having protobuf response body. The content-type header is checked to determine if the content body is protobuf.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.ProtobufResponseFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"responseHeaderFilter","description":"Select exchanges according to response header values.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.ResponseHeaderFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"statusCodeClientErrorFilter","description":"Select exchanges that HTTP status code indicates a client error (4XX).","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.StatusCodeClientErrorFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"statusCodeFilter","description":"Select exchanges according to HTTP status code.","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.StatusCodeFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"statusCodeRedirectionFilter","description":"Select exchanges that HTTP status code indicates a redirect (3XX).","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.StatusCodeRedirectionFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"statusCodeServerErrorFilter","description":"Select exchanges that HTTP status code indicates a server/intermediary error (5XX).","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.StatusCodeServerErrorFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"statusCodeSuccessFilter","description":"Select exchanges that HTTP status code indicates a successful request (2XX).","fullTypeName":"Fluxzy.Rules.Filters.ResponseFilters.StatusCodeSuccessFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"absoluteUriFilter","description":"Select exchanges according to URI (scheme, FQDN, path and query). Supports common string search option and regular expression.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.AbsoluteUriFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"agentLabelFilter","description":"Select exchanges according to configured source agent (user agent or process) with a regular string search.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.AgentLabelFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"authorityFilter","description":"Select exchange according to hostname and a port","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.AuthorityFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"deleteFilter","description":"Select exchanges with DELETE method","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.DeleteFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"formRequestFilter","description":"Select request sending \u0027multipart/form-data\u0027 or \u0027application/x-www-form-urlencoded\u0027 body. Filtering is made by inspecting value of \u0060Content-Type\u0060 header","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.FormRequestFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"formUrlEncodedRequestFilter","description":"Select request sending \u0027application/x-www-form-urlencoded\u0027 body. Filtering is made by inspecting value of \u0060Content-Type\u0060 header","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.FormUrlEncodedRequestFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"getFilter","description":"Select exchanges with GET method","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.GetFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"h11TrafficOnlyFilter","description":"Select HTTP/1.1 exchanges only.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.H11TrafficOnlyFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"h2TrafficOnlyFilter","description":"Select H2 exchanges only.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.H2TrafficOnlyFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"hasAnyCookieOnRequestFilter","description":"Select exchanges having any request cookie","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasAnyCookieOnRequestFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"hasAuthorizationBearerFilter","description":"Select exchanges having bearer token in authorization.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasAuthorizationBearerFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"hasAuthorizationFilter","description":"Select exchanges having authorization header.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasAuthorizationFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"hasCookieOnRequestFilter","description":"Exchange having a request cookie with a specific name","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasCookieOnRequestFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"hasRequestBodyFilter","description":"Select request having body.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasRequestBodyFilter","category":"Filter","scope":"responseBodyReceivedFromRemote"},{"title":"hasSetCookieOnResponseFilter","description":"Search for a cookie value present in a \u0060set-cookie\u0060 header response.If cookie name is not defined or empty, the filter will returns any cookie having the value.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HasSetCookieOnResponseFilter","category":"Filter","scope":"responseHeaderReceivedFromRemote"},{"title":"hostFilter","description":"Select exchanges according to hostname (excluding port). To select authority (combination of host:port), use \u003Cgoto\u003EAuthorityFilter\u003C/goto\u003E.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.HostFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"isGrpcFilter","description":"Select gRPC exchanges only. Filtering is made by inspecting value of \u0060Content-Type\u0060 header.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.IsGrpcFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"isSecureFilter","description":"Select secure exchange only (non plain HTTP).","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.IsSecureFilter","category":"Filter","scope":"onAuthorityReceived"},{"title":"jsonRequestFilter","description":"Select request sending JSON body. Filtering is made by inspecting value of \u0060Content-Type\u0060 header","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.JsonRequestFilter","category":"Filter","scope":"requestBodyReceivedFromClient"},{"title":"methodFilter","description":"Select exchanges according to request method.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.MethodFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"multipartDataRequestFilter","description":"Select request sending \u0027multipart/form-data\u0027 body. Filtering is made by inspecting value of \u0060Content-Type\u0060 header","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.MultipartDataRequestFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"patchFilter","description":"Select exchanges with PATCH method","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.PatchFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"pathFilter","description":"Select exchanges according to url path. Path includes query string if any. Path must start with \u0060/\u0060","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.PathFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"postFilter","description":"Select POST (request method) only exchanges.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.PostFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"processIdFilter","description":"Select exchanges initiated by a process with the specified process ID. Process tracking must be enabled and the connection must originate from localhost.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.ProcessIdFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"processNameFilter","description":"Select exchanges initiated by processes with the specified names. Process names are matched case-insensitively. On Windows, the .exe extension can be omitted. Process tracking must be enabled and the connection must originate from localhost.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.ProcessNameFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"protobufRequestFilter","description":"Select requests sending a protobuf body. Filtering is made by inspecting value of \u0060Content-Type\u0060 header.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.ProtobufRequestFilter","category":"Filter","scope":"requestBodyReceivedFromClient"},{"title":"putFilter","description":"Select exchanges according to request method.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.PutFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"queryStringFilter","description":"Select exchanges containing a specific query string. If \u0060name\u0060 is not defined or empty, the search will be performed on any query string values.The search will pass if at least one value match.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.QueryStringFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"requestHeaderFilter","description":"Select exchanges according to request header values.","fullTypeName":"Fluxzy.Rules.Filters.RequestFilters.RequestHeaderFilter","category":"Filter","scope":"requestHeaderReceivedFromClient"},{"title":"abortAction","description":"Abort an exchange at the transport level. This action will close connection between fluxzy and client which may lead to depended exchanges to be aborted too.","fullTypeName":"Fluxzy.Rules.Actions.AbortAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"addAuthorizationBasicAction","description":"Add Authorization Basic to the request header.","fullTypeName":"Fluxzy.Rules.Actions.AddAuthorizationBasicAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"addAuthorizationBearerAction","description":"Add Authorization Bearer token to the request header.","fullTypeName":"Fluxzy.Rules.Actions.AddAuthorizationBearerAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"addRequestHeaderAction","description":"Append a request header.","fullTypeName":"Fluxzy.Rules.Actions.AddRequestHeaderAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"addResponseHeaderAction","description":"Append a response header. H2 pseudo header will be ignored.","fullTypeName":"Fluxzy.Rules.Actions.AddResponseHeaderAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"applyCommentAction","description":"Add comment to exchange. Comment has no effect on the stream behaviour.","fullTypeName":"Fluxzy.Rules.Actions.ApplyCommentAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"applyTagAction","description":"Affect a tag to exchange. Tags are meta-information and do not alter the connection.","fullTypeName":"Fluxzy.Rules.Actions.ApplyTagAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"averageThrottleAction","description":"Throttle and simulate bandwidth condition.","fullTypeName":"Fluxzy.Rules.Actions.AverageThrottleAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"changeRequestMethodAction","description":"Alter the method of an exchange.","fullTypeName":"Fluxzy.Rules.Actions.ChangeRequestMethodAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"changeRequestPathAction","description":"Change request uri path. This action alters only the path of the request. Request path includes query string.","fullTypeName":"Fluxzy.Rules.Actions.ChangeRequestPathAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"delayAction","description":"Add a latency to the exchange.","fullTypeName":"Fluxzy.Rules.Actions.DelayAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"deleteRequestHeaderAction","description":"Remove request headers. This action removes \u003Cb\u003Eevery\u003C/b\u003E occurrence of the header from the request.","fullTypeName":"Fluxzy.Rules.Actions.DeleteRequestHeaderAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"deleteResponseHeaderAction","description":"Remove response headers. This action removes \u003Cb\u003Eevery\u003C/b\u003E occurrence of the header from the response.","fullTypeName":"Fluxzy.Rules.Actions.DeleteResponseHeaderAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"fileAppendAction","description":"Write to a file. Captured variable are interpreted.","fullTypeName":"Fluxzy.Rules.Actions.FileAppendAction","category":"Action","scope":"copySibling"},{"title":"forceHttp11Action","description":"Force the connection between fluxzy and remote to be HTTP/1.1. This value is enforced by ALPN settings set during the SSL/Handshake handshake.","fullTypeName":"Fluxzy.Rules.Actions.ForceHttp11Action","category":"Action","scope":"onAuthorityReceived"},{"title":"forceHttp2Action","description":"Forces the connection between fluxzy and remote to be HTTP/2.0. This value is enforced when setting up ALPN settings during SSL/TLS negotiation. \u003Cbr/\u003EThe exchange will break if the remote does not support HTTP/2.0. \u003Cbr/\u003EThis action will be ignored when the communication is clear (h2c not supported).","fullTypeName":"Fluxzy.Rules.Actions.ForceHttp2Action","category":"Action","scope":"onAuthorityReceived"},{"title":"forceRemotePortAction","description":"Ignores the default port used by the current authority and use the provided port instead.","fullTypeName":"Fluxzy.Rules.Actions.ForceRemotePortAction","category":"Action","scope":"onAuthorityReceived"},{"title":"forceTlsVersionAction","description":"Force the usage of a specific TLS version. Values can be chosen among : Tls, Tls11, Tls12, Tls13, Ssl3, Ssl2. \u003Cbr/\u003EForcing the usage of a specific TLS version can break the exchange if the remote does not support the requested protocol.","fullTypeName":"Fluxzy.Rules.Actions.ForceTlsVersionAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"forwardAction","description":"Forward request to a specific URL. This action makes fluxzy act as a reverse proxy. Unlike [SpoofDnsAction](https://www.fluxzy.io/rule/item/spoofDnsAction), host header is automatically set and protocol switch is supported (http to https, http/1.1 to h2, ...). The URL must be an absolute path.","fullTypeName":"Fluxzy.Rules.Actions.ForwardAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"impersonateAction","description":"Impersonate a browser or client by changing the TLS fingerprint, HTTP/2 settings and headers.","fullTypeName":"Fluxzy.Rules.Actions.ImpersonateAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"mountCertificateAuthorityAction","description":"Reply with the default root certificate used by fluxzy","fullTypeName":"Fluxzy.Rules.Actions.MountCertificateAuthorityAction","category":"Action","scope":"dnsSolveDone"},{"title":"noOpAction","description":"An action doing no operation.","fullTypeName":"Fluxzy.Rules.Actions.NoOpAction","category":"Action","scope":"requestBodyReceivedFromClient"},{"title":"removeCacheAction","description":"Remove all cache directive from request and response headers. This will force the clientto ask the latest version of the requested resource.","fullTypeName":"Fluxzy.Rules.Actions.RemoveCacheAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"setClientCertificateAction","description":"Add a client certificate to the exchange. The client certificate will be used for establishing the mTLS authentication if the remote request it. The client certificate can be retrieved from the default store (my) or from a PKCS#12 file (.p12, pfx). \u003Cbr/\u003EThe certificate will not be stored in fluxzy settings and, therefore, must be available at runtime. ","fullTypeName":"Fluxzy.Rules.Actions.SetClientCertificateAction","category":"Action","scope":"onAuthorityReceived"},{"title":"setJa3FingerPrintAction","description":"Set a JA3 fingerprint of ongoing connection.","fullTypeName":"Fluxzy.Rules.Actions.SetJa3FingerPrintAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"setUserAgentAction","description":"Change the User-AgentThis action is used to change the User-Agent header of the request from a list of built-in user-agent values.","fullTypeName":"Fluxzy.Rules.Actions.SetUserAgentAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"setVariableAction","description":"Set a variable or update an existing","fullTypeName":"Fluxzy.Rules.Actions.SetVariableAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"skipRemoteCertificateValidationAction","description":"Skip validating remote certificate. Fluxzy will ignore any validation errors on the server certificate.","fullTypeName":"Fluxzy.Rules.Actions.SkipRemoteCertificateValidationAction","category":"Action","scope":"onAuthorityReceived"},{"title":"skipSslTunnelingAction","description":"Instructs fluxzy to not decrypt the current traffic. The associated filter must be on OnAuthorityReceived scope in order to make this action effective. ","fullTypeName":"Fluxzy.Rules.Actions.SkipSslTunnelingAction","category":"Action","scope":"onAuthorityReceived"},{"title":"spoofDnsAction","description":"Fix statically the remote ip or port disregards to the dns or host resolution of the current running system. Use this action to force the resolution of a hostname to a fixed IP address. ","fullTypeName":"Fluxzy.Rules.Actions.SpoofDnsAction","category":"Action","scope":"onAuthorityReceived"},{"title":"stdErrAction","description":"Write text to standard error. Captured variable are interpreted.","fullTypeName":"Fluxzy.Rules.Actions.StdErrAction","category":"Action","scope":"copySibling"},{"title":"stdOutAction","description":"Write text to standard output. Captured variable are interpreted.","fullTypeName":"Fluxzy.Rules.Actions.StdOutAction","category":"Action","scope":"outOfScope"},{"title":"updateRequestHeaderAction","description":"Update and existing request header. If the header does not exists in the original request, the header will be added. \u003Cbr/\u003EUse {{previous}} keyword to refer to the original value of the header. \u003Cbr/\u003E\u003Cstrong\u003ENote\u003C/strong\u003E Headers that alter the connection behaviour will be ignored.","fullTypeName":"Fluxzy.Rules.Actions.UpdateRequestHeaderAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"updateResponseHeaderAction","description":"Update and existing response header. If the header does not exists in the original response, the header will be added.\u003Cbr/\u003EUse {{previous}} keyword to refer to the original value of the header.\u003Cbr/\u003E\u003Cstrong\u003ENote\u003C/strong\u003E Headers that alter the connection behaviour will be ignored.","fullTypeName":"Fluxzy.Rules.Actions.UpdateResponseHeaderAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"upStreamProxyAction","description":"Use an upstream proxy.","fullTypeName":"Fluxzy.Rules.Actions.UpStreamProxyAction","category":"Action","scope":"onAuthorityReceived"},{"title":"useCertificateAction","description":"Use a specific server certificate. Certificate can be retrieved from user store or from a PKCS12 file","fullTypeName":"Fluxzy.Rules.Actions.UseCertificateAction","category":"Action","scope":"onAuthorityReceived"},{"title":"useDnsOverHttpsAction","description":"Use DoH (DNS over HTTPS) to resolve domain names instead of the default DNS provided by the OS","fullTypeName":"Fluxzy.Rules.Actions.UseDnsOverHttpsAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"addBasicAuthenticationAction","description":"Add a basic authentication (RFC 7617) to incoming exchanges with an username and a password","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.AddBasicAuthenticationAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"applySessionAction","description":"Apply captured session data to requests. Adds cookies from session store and optionally applies stored headers. Works in conjunction with CaptureSessionAction.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.ApplySessionAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"captureSessionAction","description":"Capture session data from responses. Captures Set-Cookie headers and optionally other headers like Authorization. Can also capture cookies from request headers for intercepting ongoing sessions. Stored data can be replayed using ApplySessionAction.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.CaptureSessionAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"clearSessionAction","description":"Clear stored session data for a specific domain or all domains.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.ClearSessionAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"injectHtmlTagAction","description":"This action stream a response body and inject a text after the first specified html tag.This action can be used to inject a html code snippet after opening \u0060\u003Chead\u003E\u0060 tag in any traversing html page.This action supports chunked transfer stream and the following body encodings: gzip, deflate, brotli and lzw.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.InjectHtmlTagAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"mockedResponseAction","description":"Reply with a pre-made response from a raw text or file","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.MockedResponseAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"mountWelcomePageAction","description":"Reply with fluxzy welcome page","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.MountWelcomePageAction","category":"Action","scope":"dnsSolveDone"},{"title":"rejectAction","description":"Block the request and return HTTP 403 Forbidden response. Use this action to explicitly deny access to specific resources. This is a simple blocking action with no configuration required.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.RejectAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"rejectWithMessageAction","description":"Block the request with a custom HTTP error response including a body message. Useful for providing detailed blocking reasons to end users. Supports text/plain, text/html, and application/json content types.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.RejectWithMessageAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"rejectWithStatusCodeAction","description":"Block the request and return a custom HTTP error response. Allows specifying the status code (e.g., 403, 404, 502) to return to the client. The response body will contain the standard reason phrase for the status code.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.RejectWithStatusCodeAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"removeResponseCookieAction","description":"Remove a response cookie by setting the expiration date to a past date.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.RemoveResponseCookieAction","category":"Action","scope":"responseHeaderReceivedFromRemote"},{"title":"serveDirectoryAction","description":"Serve a folder as a static web site. This action is made for mocking purpose and not production ready for a web site.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.ServeDirectoryAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"setRequestCookieAction","description":"Add a cookie to request. This action is performed by adding/replacing \u0060Cookie\u0060 header in request.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.SetRequestCookieAction","category":"Action","scope":"requestHeaderReceivedFromClient"},{"title":"setResponseCookieAction","description":"Add a response cookie. This action is performed by adding \u0060Set-Cookie\u0060 header in response.","fullTypeName":"Fluxzy.Rules.Actions.HighLevelActions.SetResponseCookieAction","category":"Action","scope":"responseHeaderReceivedFromRemote"}] \ No newline at end of file diff --git a/src/Fluxzy.Core/Fluxzy.Core.csproj b/src/Fluxzy.Core/Fluxzy.Core.csproj index a2bea4330..d1185e314 100644 --- a/src/Fluxzy.Core/Fluxzy.Core.csproj +++ b/src/Fluxzy.Core/Fluxzy.Core.csproj @@ -46,7 +46,7 @@ - + diff --git a/src/Fluxzy.Core/Rules/Filters/ProtobufFilter.cs b/src/Fluxzy.Core/Rules/Filters/ProtobufFilter.cs new file mode 100644 index 000000000..551ff61e0 --- /dev/null +++ b/src/Fluxzy.Core/Rules/Filters/ProtobufFilter.cs @@ -0,0 +1,61 @@ +// Copyright 2021 - Haga Rakotoharivelo - https://github.com/haga-rak + +using System.Collections.Generic; +using Fluxzy.Rules.Extensions; +using Fluxzy.Rules.Filters.RequestFilters; +using Fluxzy.Rules.Filters.ResponseFilters; + +namespace Fluxzy.Rules.Filters +{ + /// + /// Select exchanges having a protobuf request or response body. + /// Filtering is made by inspecting value of `Content-Type` header on both request and response. + /// + [FilterMetaData( + LongDescription = + "Select exchanges having a protobuf request or response body. Filtering is made by inspecting value of `Content-Type` header on both request and response." + )] + public class ProtobufFilter : FilterCollection + { + public ProtobufFilter() + : base(new ProtobufRequestFilter(), new ProtobufResponseFilter()) + { + Operation = SelectorCollectionOperation.Or; + } + + public override string GenericName => "Protobuf exchange"; + + public override string AutoGeneratedName { get; } = "Protobuf"; + + public override string ShortName => "protobuf"; + + public override bool PreMadeFilter => true; + + public override string Description => "Protobuf exchanges (request or response)"; + + public override IEnumerable GetExamples() + { + yield return new FilterExample( + "Select exchanges with protobuf request or response body", + new ProtobufFilter()); + + yield return new FilterExample( + "Select exchanges without any protobuf body", + new ProtobufFilter { Inverted = true }); + } + } + + public static class ProtobufFilterExtensions + { + /// + /// When exchange has a protobuf request or response body. + /// Filtering is made by inspecting value of `Content-Type` header on both request and response. + /// + /// + /// + public static IConfigureActionBuilder WhenIsProtobuf(this IConfigureFilterBuilder builder) + { + return builder.When(new ProtobufFilter()); + } + } +} diff --git a/src/Fluxzy.Core/Rules/Filters/RequestFilters/ProtobufRequestFilter.cs b/src/Fluxzy.Core/Rules/Filters/RequestFilters/ProtobufRequestFilter.cs new file mode 100644 index 000000000..4a0f4d40a --- /dev/null +++ b/src/Fluxzy.Core/Rules/Filters/RequestFilters/ProtobufRequestFilter.cs @@ -0,0 +1,58 @@ +// Copyright 2021 - Haga Rakotoharivelo - https://github.com/haga-rak + +using System.Collections.Generic; +using Fluxzy.Core; +using Fluxzy.Rules.Extensions; + +namespace Fluxzy.Rules.Filters.RequestFilters +{ + /// + /// Select requests sending a protobuf body. Filtering is made by inspecting value of `Content-Type` header + /// for `application/x-protobuf` or `application/protobuf`. + /// + [FilterMetaData( + LongDescription = + "Select requests sending a protobuf body. Filtering is made by inspecting value of `Content-Type` header." + )] + public class ProtobufRequestFilter : RequestHeaderFilter + { + public ProtobufRequestFilter() + : base("protobuf", StringSelectorOperation.Contains, "content-type") + { + } + + public override FilterScope FilterScope => FilterScope.RequestBodyReceivedFromClient; + + public override string GenericName => "Has a request body protobuf"; + + public override string AutoGeneratedName { get; } = "Protobuf request body"; + + public override string ShortName => "snt. protobuf"; + + public override bool PreMadeFilter => true; + + public override IEnumerable GetExamples() + { + yield return new FilterExample( + "Select only exchanges with protobuf request body", + new ProtobufRequestFilter()); + + yield return new FilterExample( + "Select exchanges without protobuf request body", + new ProtobufRequestFilter { Inverted = true }); + } + } + + public static class ProtobufRequestFilterExtensions + { + /// + /// When request has a protobuf body. Filtering is made by inspecting value of `Content-Type` header. + /// + /// + /// + public static IConfigureActionBuilder WhenRequestHasProtobufBody(this IConfigureFilterBuilder builder) + { + return builder.When(new ProtobufRequestFilter()); + } + } +} diff --git a/src/Fluxzy.Core/Rules/Filters/ResponseFilters/ProtobufResponseFilter.cs b/src/Fluxzy.Core/Rules/Filters/ResponseFilters/ProtobufResponseFilter.cs new file mode 100644 index 000000000..5bcad91af --- /dev/null +++ b/src/Fluxzy.Core/Rules/Filters/ResponseFilters/ProtobufResponseFilter.cs @@ -0,0 +1,55 @@ +// Copyright 2021 - Haga Rakotoharivelo - https://github.com/haga-rak + +using System.Collections.Generic; +using Fluxzy.Rules.Extensions; + +namespace Fluxzy.Rules.Filters.ResponseFilters +{ + /// + /// Select exchanges having a protobuf response body. Filtering is made by inspecting value of `Content-Type` header + /// for `application/x-protobuf` or `application/protobuf`. + /// + [FilterMetaData( + LongDescription = + "Select exchanges having protobuf response body. The content-type header is checked to determine if the content body is protobuf." + )] + public class ProtobufResponseFilter : ResponseHeaderFilter + { + public ProtobufResponseFilter() + : base("protobuf", StringSelectorOperation.Contains, "Content-Type") + { + } + + public override string AutoGeneratedName { get; } = "Protobuf response only"; + + public override string GenericName => "Protobuf response only"; + + public override string ShortName => "protobuf"; + + public override bool PreMadeFilter => true; + + public override IEnumerable GetExamples() + { + yield return new FilterExample( + "Select only exchanges with protobuf response body", + new ProtobufResponseFilter()); + + yield return new FilterExample( + "Select exchanges without protobuf response body", + new ProtobufResponseFilter { Inverted = true }); + } + } + + public static class ProtobufResponseFilterExtensions + { + /// + /// When response has a protobuf body. Filtering is made by inspecting value of `Content-Type` header. + /// + /// + /// + public static IConfigureActionBuilder WhenResponseHasProtobufBody(this IConfigureFilterBuilder builder) + { + return builder.When(new ProtobufResponseFilter()); + } + } +} diff --git a/test/Fluxzy.Tests/Cli/WithRuleOptionProtobufRequestFilter.cs b/test/Fluxzy.Tests/Cli/WithRuleOptionProtobufRequestFilter.cs new file mode 100644 index 000000000..c44ce9b14 --- /dev/null +++ b/test/Fluxzy.Tests/Cli/WithRuleOptionProtobufRequestFilter.cs @@ -0,0 +1,27 @@ +using System.Net.Http; +using System.Text; +using Fluxzy.Rules.Filters.RequestFilters; + +namespace Fluxzy.Tests.Cli +{ + public class WithRuleOptionProtobufRequestFilter : WithRuleOptionGenericRequestFilters + { + protected override string YamlContent { get; } = $""" + rules: + - filter: + typeKind: {nameof(ProtobufRequestFilter)} + """; + + protected override void ConfigurePass(HttpRequestMessage requestMessage) + { + requestMessage.Content = new StringContent("\x00", Encoding.UTF8, "application/x-protobuf"); + requestMessage.Method = HttpMethod.Post; + } + + protected override void ConfigureBlock(HttpRequestMessage requestMessage) + { + requestMessage.Content = new StringContent("{}", Encoding.UTF8, "application/json"); + requestMessage.Method = HttpMethod.Post; + } + } +} diff --git a/test/Fluxzy.Tests/UnitTests/Rules/Extensions/FilterExtensions.cs b/test/Fluxzy.Tests/UnitTests/Rules/Extensions/FilterExtensions.cs index 94759b4f7..130c2f505 100644 --- a/test/Fluxzy.Tests/UnitTests/Rules/Extensions/FilterExtensions.cs +++ b/test/Fluxzy.Tests/UnitTests/Rules/Extensions/FilterExtensions.cs @@ -172,6 +172,18 @@ public static IEnumerable GenerateNoParamFilterExtension() new object[] { typeof(JsonResponseFilter).FullName!, new Func(builder => builder.WhenResponseHasJsonBody()) }; + yield return + new object[] { typeof(ProtobufRequestFilter).FullName!, + new Func(builder => builder.WhenRequestHasProtobufBody()) }; + + yield return + new object[] { typeof(ProtobufResponseFilter).FullName!, + new Func(builder => builder.WhenResponseHasProtobufBody()) }; + + yield return + new object[] { typeof(ProtobufFilter).FullName!, + new Func(builder => builder.WhenIsProtobuf()) }; + yield return new object[] { typeof(ResponseHeaderFilter).FullName!, new Func(builder => builder.WhenResponseHeaderExists("responseheader")) };