### Valid Configuration Examples Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Examples of correctly formatted regex patterns for Rename and Rewrite rules. ```yaml # Rename with valid patterns - type: "Rename" header: "X-.*" # Matches X-anything value: "X-New" - type: "Rename" header: "X-(Old\|Legacy)" # Matches X-Old or X-Legacy value: "X-New" # Rewrite with valid patterns - type: "RewriteValueRule" header: "X-.*" value: "\\d+" # Matches digits valueReplace: "NUM" - type: "RewriteValueRule" header: "X-.*" value: "(\\w+)-(\\d+)" # Capture word and number valueReplace: "$2-$1" # Swap them ``` -------------------------------- ### Start Development Environment Source: https://github.com/tommoulard/htransformation/blob/main/README.md Use Docker Compose to spin up the development environment. ```bash $ docker compose up ``` -------------------------------- ### Example YAML configuration for rules Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/types.md Example configurations for various rule types including Set, Delete, Join, Rename, and Rewrite. ```yaml # Set rule - Name: "Add-Custom-Header" Type: "Set" Header: "X-Custom" Value: "CustomValue" SetOnResponse: false # Delete rule - Name: "Remove-Server" Type: "Del" Header: "Server" SetOnResponse: true # Join rule - Name: "Combine-Values" Type: "Join" Header: "X-Items" Values: - "item1" - "^Other-Header" Sep: "," HeaderPrefix: "^" # Rename rule - Name: "Rename-Old" Type: "Rename" Header: "Old-Header" Value: "New-Header" # Rewrite rule - Name: "Replace-Pattern" Type: "RewriteValueRule" Header: "X-.*" Value: "old-(.*)" ValueReplace: "new-$1" ``` -------------------------------- ### Traefik Plugin Configuration Example Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/headers-transformation.md Example configuration for defining header transformation rules within a Traefik plugin setup. ```yaml // As a Traefik plugin, this is typically instantiated via New() and automatically invoked for each request // The handler is called automatically by the HTTP server // Usage in Traefik configuration: // plugins: // htransformation: // moduleName: github.com/tomMoulard/htransformation // rules: // - name: "Set Custom Header" // header: "X-Custom" // value: "CustomValue" // type: "Set" ``` -------------------------------- ### Example initialization errors Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/README.md Displays common error messages returned during rule initialization. ```text invalid rule type: MyRuleName missing required fields: IncompleteRule invalid regexp: BadPattern ``` -------------------------------- ### Initialize Set Handler Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/set-handler.md Example of initializing a new Set handler with a rule configuration. ```go rule := types.Rule{ Name: "Set-Cache-Control", Type: types.Set, Header: "Cache-Control", Value: "max-age=3600", } handler, err := set.New(rule) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Configure and Create Join Handler Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/join-handler.md Example showing the definition of a Join rule and the subsequent handler initialization. ```go rule := types.Rule{ Name: "Join-Cache-Control", Type: types.Join, Header: "Cache-Control", Values: []string{"public", "max-age=3600"}, Sep: ", ", } handler, err := join.New(rule) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Traefik Configuration Example Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/set-handler.md Example YAML configuration for using the Set handler within a Traefik middleware plugin. ```yaml # Traefik configuration http: middlewares: my-header-transformation: plugin: htransformation: rules: - name: "Set-Custom-Request-Header" type: "Set" header: "X-Client-Version" value: "1.0.0" - name: "Set-Response-Cache" type: "Set" header: "Cache-Control" value: "public, max-age=3600" setOnResponse: true routers: my-router: rule: "Host(`example.com`)" middlewares: - my-header-transformation service: my-service ``` -------------------------------- ### Join Handler Implementation Example Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/join-handler.md Demonstrates configuring a Join rule with a HeaderPrefix to dynamically fetch values from request headers. ```go rule := types.Rule{ Name: "Join-With-Header-Reference", Type: types.Join, Header: "X-Forwarded-For", Values: []string{ "Foo", "^CF-Connecting-IP", // ^ is the HeaderPrefix }, Sep: ", ", HeaderPrefix: "^", SetOnResponse: false, } handler, _ := join.New(rule) // Request headers: // X-Forwarded-For: 1.1.1.1 // CF-Connecting-IP: 2.2.2.2 // After join: // X-Forwarded-For: 1.1.1.1, Foo, 2.2.2.2 handler.Handle(responseWriter, request) ``` -------------------------------- ### Initialize Delete Handler Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/delete-handler.md Example of creating a new Delete handler using a rule configuration. ```go rule := types.Rule{ Name: "Delete-Cache-Control", Type: types.Delete, Header: "Cache-Control", } handler, err := deleter.New(rule) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Apply Header Deletion Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/delete-handler.md Example demonstrating how to remove headers from either the request or the response. ```go // Request header deletion rule := types.Rule{ Name: "Remove-X-Powered-By", Type: types.Delete, Header: "X-Powered-By", SetOnResponse: false, } handler, _ := deleter.New(rule) handler.Handle(responseWriter, request) // "X-Powered-By" header is now removed from request // Response header deletion ruleResp := types.Rule{ Name: "Remove-Server", Type: types.Delete, Header: "Server", SetOnResponse: true, } handlerResp, _ := deleter.New(ruleResp) handlerResp.Handle(responseWriter, request) // "Server" header is now removed from response ``` -------------------------------- ### Configure Rules in YAML Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Example configurations for various rules to avoid missing field errors. ```yaml - type: "Set" header: "X-Header" # Required - cannot be empty value: "value" name: "MySetRule" ``` ```yaml - type: "Join" header: "X-Header" values: # Required - cannot be empty - "value1" sep: "," # Required - cannot be empty name: "MyJoinRule" ``` ```yaml - type: "Rename" header: "X-Old" value: "X-New" # Required - cannot be empty name: "MyRenameRule" ``` ```yaml - type: "RewriteValueRule" header: "X-Header" value: "pattern" valueReplace: "replacement" # Required - cannot be empty name: "MyRewriteRule" ``` -------------------------------- ### Correct Rule Type Configuration Examples Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Valid YAML configurations for supported rule types. ```yaml - type: "Set" header: "X-Custom" value: "value" - type: "Del" header: "X-Remove" - type: "Join" header: "X-Items" values: ["item1"] sep: "," - type: "Rename" header: "X-Old" value: "X-New" - type: "RewriteValueRule" header: "X-Pattern" value: "old" valueReplace: "new" ``` -------------------------------- ### Configure and Instantiate Rename Handler Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/rename-handler.md Example showing how to define a rule and initialize the handler, including error handling for invalid regex patterns. ```go rule := types.Rule{ Name: "Rename-Cache-Header", Type: types.Rename, Header: "X-Cache-.*", // Matches X-Cache-Age, X-Cache-Status, etc. Value: "X-App-Cache", } handler, err := rename.New(rule) if err != nil { log.Fatal("Invalid regex pattern:", err) } ``` -------------------------------- ### Set HTTP Header Usage Example Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/header-utilities.md Demonstrates setting both standard headers and the special Host header, which is handled case-insensitively. ```go req, _ := http.NewRequest("GET", "http://example.com", nil) // Set a regular header header.Set(req, "X-Custom-Header", "MyValue") // req.Header["X-Custom-Header"] = ["MyValue"] // Set the Host header header.Set(req, "Host", "newhost.com") // req.Host = "newhost.com" // Case-insensitive Host header matching header.Set(req, "host", "anotherhost.com") // req.Host = "anotherhost.com" ``` -------------------------------- ### Handle Header Transformation Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/set-handler.md Signature and usage examples for applying header transformations to requests or responses. ```go func (s *Set) Handle(rw http.ResponseWriter, req *http.Request) ``` ```go // Request header transformation rule := types.Rule{ Name: "Set-X-Request-ID", Type: types.Set, Header: "X-Request-ID", Value: "abc-123", SetOnResponse: false, } handler, _ := set.New(rule) handler.Handle(responseWriter, request) // request.Header now has "X-Request-ID: abc-123" // Response header transformation ruleResp := types.Rule{ Name: "Set-Cache", Type: types.Set, Header: "Cache-Control", Value: "no-cache", SetOnResponse: true, } handlerResp, _ := set.New(ruleResp) handlerResp.Handle(responseWriter, request) // responseWriter headers now have "Cache-Control: no-cache" ``` -------------------------------- ### Configure and Create Rewrite Handler Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/rewrite-handler.md Example demonstrating the creation of a Rewrite handler with specific regex patterns for header matching and value replacement. ```go rule := types.Rule{ Name: "Rewrite-Header-Values", Type: types.RewriteValueRule, Header: "X-Custom-.*", Value: "old-(.*)", ValueReplace: "new-$1", } handler, err := rewrite.New(rule) if err != nil { log.Fatal("Invalid regex pattern:", err) } ``` -------------------------------- ### Traefik Configuration Example Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/join-handler.md Shows how to define Join middleware in a Traefik configuration file with both static and dynamic header values. ```yaml # Traefik configuration http: middlewares: join-headers: plugin: htransformation: rules: # Simple join without header references - name: "Join-Cache-Control" type: "Join" header: "Cache-Control" values: - "public" - "max-age=3600" sep: ", " # Join with header references - name: "Join-Forwarded-For" type: "Join" header: "X-Forwarded-For" headerPrefix: "^" values: - "Custom-Value" - "^CF-Connecting-IP" sep: "," routers: my-router: rule: "Host(`example.com`)" middlewares: - join-headers service: my-service ``` -------------------------------- ### Standard HTTP Request Example Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md A standard HTTP request that does not require connection hijacking. ```http GET / HTTP/1.1 Host: example.com ``` -------------------------------- ### Rename Header Rule Source: https://github.com/tommoulard/htransformation/blob/main/README.md Configuration examples for renaming headers using regex patterns. ```yaml - Rule: Name: 'Header rename' Header: 'Cache-Control' Value: 'NewHeader' Type: 'Rename' ``` ```yaml # Old header: Cache-Control: gzip, deflate # New header: NewHeader: gzip, deflate ``` ```yaml - Rule: Name: 'Header Renaming' Header: 'X-Traefik-*' Value: 'X-Traefik-merged' Type: 'Rename' ``` ```yaml # Old header: X-Traefik-uuid: 0 X-Traefik-date: mer. 21 oct. 2020 11:57:39 CEST # New header: X-Traefik-merged: 0 # A value from old headers ``` -------------------------------- ### Invalid Configuration Examples Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md YAML configurations that trigger ErrInvalidRegexp due to malformed regex patterns. ```yaml - type: "Rename" header: "[invalid" # Error: unclosed character class value: "X-New" name: "BadRename" # Causes: invalid regexp: BadRename ``` ```yaml - type: "RewriteValueRule" header: "X-Header" value: "(unclosed" # Error: unclosed group valueReplace: "new" name: "BadRewrite" # Causes: invalid regexp: BadRewrite ``` -------------------------------- ### Multi-Value Header Processing Example Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/rewrite-handler.md Demonstrates how individual values in a multi-value header are processed independently when a pattern matches. ```text Original header: X-Custom: value1 X-Custom: value2 If pattern matches both values: After rewrite: X-Custom: new_value1 X-Custom: new_value2 ``` -------------------------------- ### Traefik Middleware Configuration Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/QUICK_REFERENCE.md Example configuration for enabling the htransformation plugin within a Traefik environment. ```yaml # docker-compose or Traefik config providers: file: filename: /path/to/traefik.yml plugins: htransformation: moduleName: github.com/tomMoulard/htransformation version: v1 http: middlewares: my-headers: plugin: htransformation: rules: - type: "Set" header: "X-Custom" value: "value" routers: my-router: rule: "Host(`example.com`)" middlewares: - my-headers service: my-service ``` -------------------------------- ### Invalid Rule Type Configuration Examples Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Examples of YAML configurations that will trigger the ErrInvalidRuleType error due to incorrect casing or unsupported values. ```yaml - type: "delete" # Wrong case (should be "Del") - type: "DELETE" # Wrong case - type: "Remove" # Unsupported type name - type: "SetHeader" # Unsupported variation - type: "Rewrite" # Wrong (should be "RewriteValueRule") - type: "" # Empty type ``` -------------------------------- ### Configure Traefik Middleware Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/README.md Example YAML configuration for defining header transformation rules within Traefik. ```yaml http: middlewares: my-transformations: plugin: htransformation: rules: # Add authentication header - name: "Add-Auth" type: "Set" header: "Authorization" value: "Bearer my-token" setOnResponse: false # Remove sensitive response headers - name: "Remove-Server" type: "Del" header: "Server" setOnResponse: true - name: "Remove-X-Powered-By" type: "Del" header: "X-Powered-By" setOnResponse: true # Rename headers - name: "Rename-Old" type: "Rename" header: "X-Old-Name" value: "X-New-Name" # Add cache headers - name: "Cache-Static" type: "Join" header: "Cache-Control" values: - "public" - "max-age=31536000" sep: ", " setOnResponse: true # Rewrite header values - name: "Sanitize-UA" type: "RewriteValueRule" header: "User-Agent" value: "Mozilla/(.*)" valueReplace: "Mozilla/REDACTED" routers: my-service: rule: "Host(`example.com`)" middlewares: - my-transformations service: my-backend ``` -------------------------------- ### WebSocket Upgrade Request Example Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md HTTP request headers that trigger a connection upgrade, potentially leading to this error if hijacking is unsupported. ```http GET / HTTP/1.1 Host: example.com Upgrade: websocket Connection: Upgrade ``` -------------------------------- ### Example Error Message Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md The resulting error message format when a rule name is provided. ```text missing required fields: MyRuleName ``` -------------------------------- ### Trigger ErrNotHTTPHijacker in Hijack method Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Example implementation showing how the error is returned when the underlying response writer lacks Hijacker support. ```go func (wrw *wrappedResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { hijacker, ok := wrw.rw.(http.Hijacker) if !ok { return nil, nil, types.ErrNotHTTPHijacker } // ... } ``` -------------------------------- ### Define header transformation rules in YAML Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/QUICK_REFERENCE.md Configuration examples for various header transformation operations including Set, Del, Join, Rename, and RewriteValueRule. ```yaml # Set: Create or replace a header - type: "Set" header: "X-Custom" value: "MyValue" # Delete: Remove a header - type: "Del" header: "Server" # Join: Concatenate values to existing header - type: "Join" header: "Cache-Control" values: ["public", "max-age=3600"] sep: ", " # Rename: Rename a header using regex - type: "Rename" header: "X-Old-.*" value: "X-New" # Rewrite: Replace values using regex with capture groups - type: "RewriteValueRule" header: "X-.*" value: "old-(.*)" valueReplace: "new-$1" ``` -------------------------------- ### Configure htransformation in Traefik Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Example YAML configuration for using htransformation within a Traefik router. ```yaml # In Traefik, htransformation works with all middleware: http: middlewares: htransformation: plugin: htransformation: rules: - type: "Set" header: "X-Custom" value: "value" routers: websocket-router: rule: "Host(`ws.example.com`)" middlewares: - htransformation # Safe for WebSocket upgrades service: websocket-service ``` -------------------------------- ### Validate Handler Usage Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/delete-handler.md Example of calling the validation method, which always returns nil for the Delete handler. ```go handler, _ := deleter.New(rule) if err := handler.Validate(); err != nil { log.Printf("Validation error: %v", err) } // For Delete, this will always return nil ``` -------------------------------- ### Multiple Matches Within Single Value Example Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/rewrite-handler.md Shows how the handler replaces all occurrences of a pattern within a single header value. ```text Header: X-Items: old_1; old_2; old_3 Pattern: old_(\d+) Replace: new_$1 Result: X-Items: new_1; new_2; new_3 ``` -------------------------------- ### Rename Handler Traefik Configuration Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/rename-handler.md Example configuration for the Rename handler within a Traefik middleware definition, demonstrating both exact and regex-based header renaming. ```yaml # Traefik configuration http: middlewares: rename-headers: plugin: htransformation: rules: - name: "Rename-Old-To-New" type: "Rename" header: "X-Old-Header" value: "X-New-Header" - name: "Merge-Traefik-Headers" type: "Rename" header: "X-Traefik-.*" value: "X-Traefik-Info" routers: my-router: rule: "Host(`example.com`)" middlewares: - rename-headers service: my-service ``` -------------------------------- ### Populate Configuration and Initialize Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/headers-transformation.md Shows how to create a new configuration, append rules, and pass it to the New constructor. ```go config := CreateConfig() config.Rules = append(config.Rules, types.Rule{ Name: "Set-Custom-Header", Type: types.Set, Header: "X-Custom-Header", Value: "CustomValue", }) handler, err := New(context.Background(), nextHandler, config, "my-transformation") ``` -------------------------------- ### Configure and Instantiate Middleware Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/headers-transformation.md Demonstrates setting up a configuration with multiple rules and initializing the middleware handler. ```go config := &Config{ Rules: []types.Rule{ { Name: "Set-Custom-Header", Type: types.Set, Header: "X-My-Header", Value: "MyValue", }, { Name: "Delete-Cache-Control", Type: types.Delete, Header: "Cache-Control", SetOnResponse: true, }, }, } handler, err := New(context.Background(), nextHandler, config, "my-transformation") if err != nil { log.Fatal("Failed to create middleware:", err) } // Use handler as http.Handler in your router http.Handle("/", handler) ``` -------------------------------- ### Validation Error Messages Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/configuration.md Examples of error messages generated when rule validation fails. ```text Error: invalid rule type: unsupported-type: (rule name: "My-Rule") Error: missing required fields: (rule name: "Incomplete-Rule") Error: invalid regexp: invalid regex pattern: (rule name: "Bad-Pattern") ``` -------------------------------- ### Create Configuration Instance Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/headers-transformation.md Defines the signature for the CreateConfig function used to initialize an empty configuration. ```go func CreateConfig() *Config ``` -------------------------------- ### Project Documentation File Structure Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/MANIFEST.md Displays the directory tree for the project's documentation files located in /workspace/home/output/. ```text /workspace/home/output/ ├── INDEX.md (Master navigation) ├── README.md (Overview) ├── QUICK_REFERENCE.md (Cheat sheet) ├── types.md (Type reference) ├── configuration.md (Config guide) ├── errors.md (Error reference) ├── MANIFEST.md (This file) └── api-reference/ (API documentation) ├── headers-transformation.md ├── set-handler.md ├── delete-handler.md ├── join-handler.md ├── rename-handler.md ├── rewrite-handler.md └── header-utilities.md ``` -------------------------------- ### Demonstrate HTTP Header Normalization Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/header-utilities.md Shows how Go's http.Header normalizes header names, causing subsequent sets to overwrite previous values regardless of casing. ```go req, _ := http.NewRequest("GET", "http://example.com", nil) header.Set(req, "content-type", "text/html") header.Set(req, "Content-Type", "application/json") // Overwrites previous // Both refer to the same header due to Go's normalization fmt.Println(req.Header.Get("Content-Type")) // application/json fmt.Println(req.Header.Get("CONTENT-TYPE")) // application/json ``` -------------------------------- ### Trigger ErrInvalidRegexp in Rename Handler Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Example of how the Rename handler triggers the error when the header regex fails to compile. ```go func New(rule types.Rule) (types.Handler, error) { re, err := regexp.Compile(rule.Header) if err != nil { return nil, fmt.Errorf("%w: %s", types.ErrInvalidRegexp, rule.Name) } // ... } ``` -------------------------------- ### New Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/headers-transformation.md Creates and initializes a new HeadersTransformation middleware handler with the provided configuration. ```APIDOC ## func New(context.Context, http.Handler, *Config, string) (http.Handler, error) ### Description Creates and initializes a new `HeadersTransformation` middleware handler. It validates all rules and creates appropriate handlers for each rule type. ### Parameters - **_** (context.Context) - Required - Context for the plugin lifecycle (unused) - **next** (http.Handler) - Required - The next HTTP handler in the middleware chain - **config** (*Config) - Required - Configuration containing rules to apply - **name** (string) - Required - The name of the middleware instance ### Returns - **http.Handler** - The initialized middleware handler - **error** - Error if rule configuration is invalid or a handler cannot be created ``` -------------------------------- ### Initialize Middleware Constructor Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/README.md Used by Traefik during plugin loading to instantiate the middleware. ```go func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error) ``` -------------------------------- ### Constructor Signature Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/set-handler.md Defines the signature for creating a new Set handler instance. ```go func New(rule types.Rule) (types.Handler, error) ``` -------------------------------- ### Initialize HeadersTransformation Middleware Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/headers-transformation.md Defines the signature for the New constructor function used to create a middleware handler. ```go func New(_ context.Context, next http.Handler, config *Config, name string) (http.Handler, error) ``` -------------------------------- ### Trigger ErrInvalidRegexp in Rewrite Handler Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Example of how the Rewrite handler triggers the error when either the header or value regex fails to compile. ```go func New(rule types.Rule) (types.Handler, error) { reg, err := regexp.Compile(rule.Header) if err != nil { return nil, fmt.Errorf("%w: %s: %q", types.ErrInvalidRegexp, rule.Name, rule.Header) } reg, err = regexp.Compile(rule.Value) if err != nil { return nil, fmt.Errorf("%w: %s: %q", types.ErrInvalidRegexp, rule.Name, rule.Value) } // ... } ``` -------------------------------- ### CreateConfig Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/headers-transformation.md Creates a new empty Config instance for populating with rules. ```APIDOC ## func CreateConfig() *Config ### Description Creates a new empty `Config` instance for populating with rules. ### Returns - ***Config** - A new config with an empty rules slice ``` -------------------------------- ### Implement Handler Usage Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/types.md Handlers are instantiated via specific constructor functions and require validation before execution. ```go rule := types.Rule{...} // Set handler setHandler, _ := set.New(rule) if err := setHandler.Validate(); err != nil { return err } setHandler.Handle(responseWriter, request) // Delete handler delHandler, _ := deleter.New(rule) if err := delHandler.Validate(); err != nil { return err } delHandler.Handle(responseWriter, request) ``` -------------------------------- ### Sequential Rule Evaluation Source: https://github.com/tommoulard/htransformation/blob/main/README.md Demonstrates how multiple rules are processed in the order they are defined. ```yaml - Rule: Name: 'Header addition' Header: 'X-Custom-2' Value: 'True' Type: 'Set' - Rule: Name: 'Header deletion' Header: 'X-Custom-2' Type: 'Del' - Rule: Name: 'Header join' Header: 'X-Custom-2' Value: 'False' Type: 'Set' ``` -------------------------------- ### Perform Case-Insensitive Host Header Matching Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/header-utilities.md Uses strings.EqualFold to ensure Host header comparisons are case-insensitive. ```go strings.EqualFold(header, "Host") // true for "Host", "host", "HOST", etc. ``` -------------------------------- ### Verify Header Transformations with curl Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/QUICK_REFERENCE.md Use these curl commands to validate that Set, Delete, and Join rules are correctly applied to HTTP headers. ```bash # Test a Set rule curl -H "Host: example.com" http://traefik-address/ # Check: Response has X-Custom header # Test a Delete rule curl -H "Host: example.com" http://traefik-address/ # Check: Server header not in response # Test a Join rule curl -H "Host: example.com" http://traefik-address/ # Check: Cache-Control has appended values ``` -------------------------------- ### Implement HTTP Handler Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/README.md Processes incoming requests and applies header transformations to both requests and responses. ```go func (u *HeadersTransformation) ServeHTTP(rw http.ResponseWriter, req *http.Request) ``` -------------------------------- ### Header Forwarding with Prefix Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/QUICK_REFERENCE.md Joins header values with a specified separator and prefix. ```yaml - type: "Join" header: "X-Forwarded-For" headerPrefix: "^" values: - "^CF-Connecting-IP" sep: "," ``` -------------------------------- ### Define Rule Execution Order Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/configuration.md Rules are processed sequentially in the order they appear in the configuration file. ```yaml rules: - name: "First-Rule" # Executed first - name: "Second-Rule" # Executed after first - name: "Third-Rule" # Executed after second ``` -------------------------------- ### Implement Hijacker in Custom ResponseWriter Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Pattern for ensuring a custom response writer supports the http.Hijacker interface. ```go type MyResponseWriter struct { http.ResponseWriter // ... custom fields } // Implement http.Hijacker func (w *MyResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { hijacker, ok := w.ResponseWriter.(http.Hijacker) if !ok { return nil, nil, fmt.Errorf("hijacker not supported") } return hijacker.Hijack() } ``` -------------------------------- ### Multi-Value Header Transformation Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/rename-handler.md Demonstration of how the Rename handler preserves multiple values when renaming a header. ```text Original: X-Tag: value1 Original: X-Tag: value2 After rename to X-Tags: X-Tags: value1 X-Tags: value2 ``` -------------------------------- ### Configure Request Tracing Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/README.md Set static request IDs or join multiple headers to create trace identifiers. ```yaml - type: "Set" header: "X-Request-ID" value: "req-123" - type: "Join" header: "X-Trace-ID" values: - "^X-Traefik-Request-ID" sep: "-" headerPrefix: "^" ``` -------------------------------- ### Handle Header Rewriting Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/rewrite-handler.md Applies header value transformations to requests or responses based on the configured regex patterns. ```go func (r *Rewrite) Handle(rw http.ResponseWriter, req *http.Request) ``` ```go // Simple value rewrite rule := types.Rule{ Name: "Rewrite-Content-Type", Type: types.RewriteValueRule, Header: "Content-Type", Value: "text/(.*)", ValueReplace: "application/$1", SetOnResponse: false, } handler, _ := rewrite.New(rule) // Before: // Content-Type: text/plain // After: // Content-Type: application/plain handler.Handle(responseWriter, request) ``` -------------------------------- ### Configure Response Header Rule Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/configuration.md Sets a response header by setting setOnResponse to true. ```yaml - name: "Add-Security-Headers" type: "Set" header: "X-Content-Type-Options" value: "nosniff" setOnResponse: true # Applies to response ``` -------------------------------- ### Handler.Handle Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/README.md The Handle method is the primary entry point for processing HTTP requests and responses within the library. ```APIDOC ## Handle(rw http.ResponseWriter, req *http.Request) ### Description Processes an HTTP request and response using the configured transformation rules. ### Parameters - **rw** (http.ResponseWriter) - Required - The response writer to send the response. - **req** (*http.Request) - Required - The incoming HTTP request to be transformed. ``` -------------------------------- ### Cache Control Configuration Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/QUICK_REFERENCE.md Sets cache-control headers for static assets. ```yaml - type: "Set" header: "Cache-Control" value: "public, max-age=31536000" setOnResponse: true name: "Cache-Static" ``` -------------------------------- ### Define Plugin Configuration Structure Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/headers-transformation.md The Config struct defines the slice of transformation rules applied by the plugin. ```go type Config struct { Rules []types.Rule } ``` -------------------------------- ### ServeHTTP Method Signature Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/headers-transformation.md Method signature for processing HTTP requests and responses within the middleware chain. ```go func (u *HeadersTransformation) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) ``` -------------------------------- ### Validate Rewrite Configuration Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/rewrite-handler.md Checks if the handler configuration contains all required fields, specifically ensuring ValueReplace is not empty. ```go func (r *Rewrite) Validate() error ``` ```go handler, _ := rewrite.New(rule) if err := handler.Validate(); err != nil { log.Printf("Invalid configuration: %v", err) } ``` -------------------------------- ### Handle Header Deletion Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/delete-handler.md Signature for the handle method. ```go func (d *Deleter) Handle(rw http.ResponseWriter, req *http.Request) ``` -------------------------------- ### Validate Handler Configuration Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/delete-handler.md Signature for the validation method. ```go func (d *Deleter) Validate() error ``` -------------------------------- ### Handle Header Concatenation Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/join-handler.md Applies the join logic to request or response headers based on the handler configuration. ```go func (j *Join) Handle(rw http.ResponseWriter, req *http.Request) ``` ```go // Basic join rule := types.Rule{ Name: "Join-Cache-Values", Type: types.Join, Header: "Cache-Control", Values: []string{"public", "max-age=3600"}, Sep: ", ", SetOnResponse: false, } handler, _ := join.New(rule) // Request headers: Cache-Control: no-cache // After join: Cache-Control: no-cache, public, max-age=3600 handler.Handle(responseWriter, request) ``` -------------------------------- ### Define Rule configuration structure Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/types.md Configuration structure for a single header transformation rule, including fields for header matching and transformation logic. ```go type Rule struct { Header string `yaml:"Header"` HeaderPrefix string `yaml:"HeaderPrefix"` Name string `yaml:"Name"` Regexp *regexp.Regexp `yaml:"-"` Sep string `yaml:"Sep"` Type RuleType `yaml:"Type"` Value string `yaml:"Value"` ValueReplace string `yaml:"ValueReplace"` Values []string `yaml:"Values"` SetOnResponse bool `yaml:"SetOnResponse"` } ``` -------------------------------- ### Project Directory Structure Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/INDEX.md Overview of the htransformation package and module organization. ```text github.com/tomMoulard/htransformation/ ├── htransformation.go │ ├── HeadersTransformation [headers-transformation.md] │ ├── Config [types.md] │ └── wrappedResponseWriter (internal) │ ├── pkg/ │ ├── types/ │ │ └── types.go │ │ ├── RuleType [types.md] │ │ ├── Rule [types.md] │ │ ├── Handler [types.md] │ │ └── Errors [errors.md] │ │ │ ├── handler/ │ │ ├── set/set.go [set-handler.md] │ │ ├── deleter/delete.go [delete-handler.md] │ │ ├── join/join.go [join-handler.md] │ │ ├── rename/rename.go [rename-handler.md] │ │ └── rewrite/rewrite.go [rewrite-handler.md] │ │ │ └── utils/ │ └── header/ │ ├── set.go [header-utilities.md] │ ├── add.go [header-utilities.md] │ └── delete.go [header-utilities.md] ``` -------------------------------- ### Configure Set Rule Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/INDEX.md Defines a rule to create or replace a specific header with a static value. ```yaml - type: "Set" header: "X-Custom" value: "MyValue" ``` -------------------------------- ### Set Header Rule Source: https://github.com/tommoulard/htransformation/blob/main/README.md Configuration to create or replace a header value. ```yaml - Rule: Name: 'Set Cache-Control' Header: 'Cache-Control' Value: 'Foo' Type: 'Set' ``` ```yaml # New header: Cache-Control: Foo ``` -------------------------------- ### Join Rule Configuration Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/QUICK_REFERENCE.md Defines a rule to join multiple header values with a separator. ```yaml type: "Join" header: string # Required: Header name values: []string # Required: Values to join sep: string # Required: Separator headerPrefix: string # Optional: Prefix for header refs name: string # Optional: Rule name setOnResponse: bool # Optional: Default false ``` -------------------------------- ### Configure Cache Headers Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/configuration.md Define Cache-Control headers for static assets and API responses to manage browser and proxy caching. ```yaml rules: - name: "Cache-Static-Assets" type: "Set" header: "Cache-Control" value: "public, max-age=31536000" setOnResponse: true - name: "Cache-API-Responses" type: "Set" header: "Cache-Control" value: "private, max-age=3600" setOnResponse: true ``` -------------------------------- ### Validate Handler Configurations Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Validation logic for different handlers that return ErrMissingRequiredFields when required fields are empty. ```go func (s *Set) Validate() error { if s.rule.Header == "" { return types.ErrMissingRequiredFields } return nil } ``` ```go func (j *Join) Validate() error { if len(j.rule.Values) == 0 || j.rule.Sep == "" { return types.ErrMissingRequiredFields } return nil } ``` ```go func (r *Rename) Validate() error { if r.rule.Value == "" { return types.ErrMissingRequiredFields } return nil } ``` ```go func (r *Rewrite) Validate() error { if r.rule.ValueReplace == "" { return types.ErrMissingRequiredFields } return nil } ``` -------------------------------- ### Handle Header Renaming Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/rename-handler.md Applies header renaming based on a regex pattern to either the request or response. ```go func (r *Rename) Handle(rw http.ResponseWriter, req *http.Request) ``` ```go // Request header renaming rule := types.Rule{ Name: "Rename-All-X-Traefik", Type: types.Rename, Header: "X-Traefik-.*", // Matches X-Traefik-uuid, X-Traefik-date, etc. Value: "X-Traefik-merged", SetOnResponse: false, } handler, _ := rename.New(rule) handler.Handle(responseWriter, request) // Before: // X-Traefik-uuid: abc123 // X-Traefik-date: 2024-01-01 // X-Other-Header: unchanged // After: // X-Traefik-merged: abc123 // X-Traefik-merged: 2024-01-01 // X-Other-Header: unchanged ``` -------------------------------- ### Configure Request Header Rule Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/configuration.md Sets a request header by setting setOnResponse to false. ```yaml - name: "Add-Auth-Header" type: "Set" header: "Authorization" value: "Bearer token123" setOnResponse: false # Applies to request ``` -------------------------------- ### Set Cache Control Headers Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/README.md Configure cache-control policies for static assets using the Set type. ```yaml - type: "Set" header: "Cache-Control" value: "public, max-age=31536000" setOnResponse: true name: "Cache-Static-Assets" ``` -------------------------------- ### Set Rule Configuration Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/QUICK_REFERENCE.md Defines a rule to set a specific header value. ```yaml type: "Set" header: string # Required: Header name value: string # Required: Header value name: string # Optional: Rule name setOnResponse: bool # Optional: Default false ``` -------------------------------- ### Define ErrMissingRequiredFields Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md The base error definition for missing configuration fields. ```go var ErrMissingRequiredFields = errors.New("missing required fields") ``` -------------------------------- ### Join Header Rule Source: https://github.com/tommoulard/htransformation/blob/main/README.md Configuration to concatenate values into an existing header, optionally using header prefixes. ```yaml - Rule: Name: 'Header join' Header: 'Cache-Control' Sep: ',' Values: - 'Foo' - 'Bar' Type: 'Join' ``` ```yaml # Old header: Cache-Control: gzip, deflate # Joined header: Cache-Control: gzip, deflate,Foo,Bar ``` ```yaml - Rule: Name: 'Header set' Header: 'X-Forwarded-For' HeaderPrefix: "^" Sep: ',' Values: - 'Foo' - '^CF-Connecting-IP' Type: 'Join' ``` ```yaml # Old header: X-Forwarded-For: 1.1.1.1 CF-Connecting-IP: 2.2.2.2 # New headers: X-Forwarded-For: 1.1.1.1,Foo,2.2.2.2 CF-Connecting-IP: 2.2.2.2 ``` -------------------------------- ### Migrate API Version Headers Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/README.md Rename headers or rewrite values to facilitate API version transitions. ```yaml - type: "Rename" header: "X-API-v1" value: "X-API-v2" - type: "RewriteValueRule" header: "Content-Type" value: "application/v1\\+json" valueReplace: "application/v2+json" ``` -------------------------------- ### Migrate API Headers Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/configuration.md Rename or rewrite header values to support API version transitions. ```yaml rules: - name: "Rename-Old-API-Headers" type: "Rename" header: "X-API-v1-.*" value: "X-API-v2" - name: "Update-Content-Type" type: "RewriteValueRule" header: "Content-Type" value: "application/v1\\+json" valueReplace: "application/v2+json" ``` -------------------------------- ### Configure htransformation in TOML Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/configuration.md Defines static configuration for the htransformation plugin using TOML syntax for header rule definitions. ```toml [http.middlewares.htransformation.plugin.htransformation] [[http.middlewares.htransformation.plugin.htransformation.rules]] name = "Set-Custom-Header" type = "Set" header = "X-Custom" value = "CustomValue" setOnResponse = false [[http.middlewares.htransformation.plugin.htransformation.rules]] name = "Delete-Cache" type = "Del" header = "Cache-Control" setOnResponse = true [[http.middlewares.htransformation.plugin.htransformation.rules]] name = "Join-Headers" type = "Join" header = "X-Items" sep = "," values = ["item1", "item2"] ``` -------------------------------- ### Define RuleType constants Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/README.md Enumerates the supported transformation types for header manipulation. ```go type RuleType string const ( Set RuleType = "Set" Join RuleType = "Join" Delete RuleType = "Del" Rename RuleType = "Rename" RewriteValueRule RuleType = "RewriteValueRule" ) ``` -------------------------------- ### Wrap Error with Context Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Wraps the validation error with the rule name during plugin initialization. ```go return nil, fmt.Errorf("%w: %s", err, rule.Name) ``` -------------------------------- ### Define Rule structure Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/README.md Represents the configuration schema for a transformation rule. ```go type Rule struct { Header string // Header name or regex pattern HeaderPrefix string // Prefix for header references Name string // Rule name for debugging Sep string // Separator for Join Type RuleType // Rule type Value string // New value or pattern ValueReplace string // Replacement for Rewrite Values []string // Values for Join SetOnResponse bool // Apply to response instead of request } ``` -------------------------------- ### Add Security Headers Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/QUICK_REFERENCE.md Configuration to inject security-related headers into responses. ```yaml - type: "Set" header: "X-Content-Type-Options" value: "nosniff" setOnResponse: true - type: "Set" header: "X-Frame-Options" value: "DENY" setOnResponse: true ``` -------------------------------- ### Handle missing header in Go Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/join-handler.md The handler returns early if the target header is not present in the request. ```go val, ok := req.Header[j.rule.Header] if !ok { return // Returns early, no header is created } ``` -------------------------------- ### Validate Join Handler Configuration Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/join-handler.md Checks that the handler configuration contains required fields, specifically ensuring Values and Sep are populated. ```go func (j *Join) Validate() error ``` ```go handler, _ := join.New(rule) if err := handler.Validate(); err != nil { log.Printf("Validation failed: %v", err) } ``` -------------------------------- ### Wrap Error with Context Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/errors.md Implementation of error wrapping to include the rule name in the error message. ```go return nil, fmt.Errorf("%w: %s", types.ErrInvalidRuleType, rule.Name) ``` -------------------------------- ### Go Package Imports Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/QUICK_REFERENCE.md Required imports for utilizing htransformation handlers and types in a Go project. ```go import ( "net/http" "github.com/tomMoulard/htransformation" "github.com/tomMoulard/htransformation/pkg/handler/deleter" "github.com/tomMoulard/htransformation/pkg/handler/join" "github.com/tomMoulard/htransformation/pkg/handler/rename" "github.com/tomMoulard/htransformation/pkg/handler/rewrite" "github.com/tomMoulard/htransformation/pkg/handler/set" "github.com/tomMoulard/htransformation/pkg/types" "github.com/tomMoulard/htransformation/pkg/utils/header" ) ``` -------------------------------- ### Set HTTP Header Function Signature Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/api-reference/header-utilities.md Defines the function signature for setting or replacing HTTP header values. ```go func Set(req *http.Request, header string, value string) ``` -------------------------------- ### Capture Group Swap Rule Source: https://github.com/tommoulard/htransformation/blob/main/_autodocs/QUICK_REFERENCE.md Reorders header values using regex capture groups. ```yaml - type: "RewriteValueRule" header: "X-Date" value: "(\d{4})-(\d{2})-(\d{2})" # YYYY-MM-DD valueReplace: "$3/$2/$1" # DD/MM/YYYY ```