### Conversion Examples Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/standard_utility_functions.md Illustrative examples demonstrating the usage of string and number conversion functions in VCL. ```APIDOC ### Basic string to number conversion ```vcl declare local var.num_string STRING; declare local var.num_int INTEGER; declare local var.num_float FLOAT; set var.num_string = "42"; # Convert string to integer set var.num_int = std.atoi(var.num_string); # Convert string to float set var.num_float = std.atof(var.num_string); # Now we can perform arithmetic operations set var.num_int = var.num_int + 10; # 52 set var.num_float = var.num_float * 1.5; # 63.0 log "Integer: " + var.num_int; log "Float: " + var.num_float; ``` ### Advanced string to number conversion ```vcl declare local var.hex_string STRING; declare local var.hex_value INTEGER; declare local var.binary_string STRING; declare local var.binary_value INTEGER; set var.hex_string = "1A"; set var.binary_string = "1010"; # Convert hexadecimal string to integer (base 16) set var.hex_value = std.strtol(var.hex_string, 16); # Convert binary string to integer (base 2) set var.binary_value = std.strtol(var.binary_string, 2); # var.hex_value is 26 (decimal value of 1A in hex) # var.binary_value is 10 (decimal value of 1010 in binary) log "Hex value: " + var.hex_value; log "Binary value: " + var.binary_value; ``` ### Number to string conversion ```vcl declare local var.number INTEGER; declare local var.number_string STRING; set var.number = 42; # Convert integer to string set var.number_string = std.itoa(var.number); # Now we can concatenate with other strings set var.number_string = "The answer is " + var.number_string; log var.number_string; ``` ### Custom base conversion ```vcl declare local var.decimal INTEGER; declare local var.base36 STRING; set var.decimal = 12345; # Convert to base 36 (0-9, a-z) set var.base36 = std.itoa_charset(var.decimal, "0123456789abcdefghijklmnopqrstuvwxyz"); log "Decimal: " + var.decimal; log "Base 36: " + var.base36; ``` ### Handling query parameters ```vcl declare local var.page_param STRING; declare local var.page INTEGER; declare local var.limit_param STRING; declare local var.limit INTEGER; # Get pagination parameters from query string set var.page_param = querystring.get(req.url, "page"); set var.limit_param = querystring.get(req.url, "limit"); # Convert to integers with default values if (var.page_param == "") { set var.page = 1; # Default page } else { set var.page = std.atoi(var.page_param); # Ensure page is at least 1 if (var.page < 1) { set var.page = 1; } } if (var.limit_param == "") { set var.limit = 20; # Default limit } else { set var.limit = std.atoi(var.limit_param); # Ensure limit is between 1 and 100 if (var.limit < 1) { set var.limit = 1; } else if (var.limit > 100) { set var.limit = 100; } } # Set normalized pagination parameters set req.http.X-Page = var.page; set req.http.X-Limit = var.limit; ``` ### Time conversion ```vcl declare local var.timestamp INTEGER; declare local var.time TIME; # Unix timestamp (seconds since epoch) set var.timestamp = 1609459200; # 2021-01-01 00:00:00 UTC # Convert to TIME type set var.time = std.integer2time(var.timestamp); ``` ``` -------------------------------- ### HMAC Generation Examples Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/digest_functions.md Examples demonstrating how to use HMAC functions for basic generation, request authentication, and base64 encoding. ```APIDOC ## Examples ### Basic HMAC generation ```vcl declare local var.message STRING; declare local var.key STRING; declare local var.hmac_md5 STRING; declare local var.hmac_sha1 STRING; declare local var.hmac_sha256 STRING; set var.message = "Message to authenticate"; set var.key = "SecretKey123"; # Generate HMACs using different algorithms set var.hmac_md5 = digest.hmac_md5(var.key, var.message); set var.hmac_sha1 = digest.hmac_sha1(var.key, var.message); set var.hmac_sha256 = digest.hmac_sha256(var.key, var.message); # Set headers with the HMAC values set req.http.X-HMAC-MD5 = var.hmac_md5; set req.http.X-HMAC-SHA1 = var.hmac_sha1; set req.http.X-HMAC-SHA256 = var.hmac_sha256; ``` ### Request authentication with HMAC This example demonstrates how to authenticate API requests using HMAC: ```vcl declare local var.request_path STRING; declare local var.request_timestamp STRING; declare local var.request_body STRING; declare local var.api_key STRING; declare local var.expected_signature STRING; declare local var.calculated_signature STRING; # Get request details set var.request_path = req.url.path; set var.request_timestamp = req.http.X-Timestamp; set var.request_body = req.body; set var.api_key = table.lookup(my_api_keys, req.http.X-API-Key-ID); set var.expected_signature = req.http.X-Signature; # Create the string to sign declare local var.string_to_sign STRING; set var.string_to_sign = var.request_path + var.request_timestamp + var.request_body; # Calculate the signature set var.calculated_signature = digest.hmac_sha256(var.api_key, var.string_to_sign); # Verify the signature if (digest.secure_is_equal(var.calculated_signature, var.expected_signature)) { # Signature is valid set req.http.X-Auth-Valid = "true"; } else { # Signature is invalid set req.http.X-Auth-Valid = "false"; error 401 "Invalid signature"; } ``` ### HMAC with base64 encoding This example demonstrates how to generate base64-encoded HMACs: ```vcl declare local var.hmac_sha256_base64 STRING; declare local var.hmac_sha512_base64 STRING; set var.hmac_sha256_base64 = digest.hmac_sha256_base64(var.key, var.message); set var.hmac_sha512_base64 = digest.hmac_sha512_base64(var.key, var.message); # Base64-encoded HMACs are often used in HTTP headers set req.http.X-HMAC-SHA256-Base64 = var.hmac_sha256_base64; set req.http.X-HMAC-SHA512-Base64 = var.hmac_sha512_base64; ``` ``` -------------------------------- ### AWS Signature Generation Example Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/digest_functions.md Example VCL code demonstrating how to generate an AWS signature using SHA-256 hashing and HMAC. ```APIDOC ## AWS Signature Generation Example ### Description This VCL snippet demonstrates the process of generating an AWS signature, including hashing the canonical request, creating the string to sign, and calculating the final signature. ### Method N/A (VCL Script) ### Endpoint N/A (VCL Script) ### Parameters This snippet uses several variables that are assumed to be pre-defined: - `var.aws_canonical_request`: The canonical request string. - `var.aws_date`: The current date in a specific format. - `var.aws_region`: The AWS region. - `var.aws_service`: The AWS service. - `var.aws_secret_key`: The AWS secret access key. - `var.aws_access_key`: The AWS access key ID. ### Request Example ```vcl # Hash the canonical request set var.aws_request_hash = digest.hash_sha256(var.aws_canonical_request); # Create string to sign set var.aws_string_to_sign = "AWS4-HMAC-SHA256" + "\n" + var.aws_date + "\n" + substr(var.aws_date, 0, 8) + "/" + var.aws_region + "/" + var.aws_service + "/aws4_request" + "\n" + var.aws_request_hash; # Calculate the signature set var.aws_signature = digest.awsv4_hmac( var.aws_secret_key, substr(var.aws_date, 0, 8), var.aws_region, var.aws_service, var.aws_string_to_sign ); # Set the Authorization header set req.http.Authorization = "AWS4-HMAC-SHA256 " + "Credential=" + var.aws_access_key + "/" + substr(var.aws_date, 0, 8) + "/" + var.aws_region + "/" + var.aws_service + "/aws4_request, " + "SignedHeaders=host;x-amz-content-sha256;x-amz-date, " + "Signature=" + var.aws_signature; ``` ### Response N/A (This snippet modifies request headers, it does not directly return a response body.) ``` -------------------------------- ### Rounding and Logging Example Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/math_functions.md Demonstrates the use of math.ceil and math.floor for rounding prices to the nearest dollar. Includes logging of original and rounded values. ```vcl set var.ceiling_price = math.ceil(var.price); # 20.0 # Floor to nearest dollar (always round down) set var.floor_price = math.floor(var.price); # 19.0 # Log the results log "Original price: " + var.price; log "Rounded price (2 decimals): " + var.rounded_price; log "Ceiling price (nearest dollar): " + var.ceiling_price; log "Floor price (nearest dollar): " + var.floor_price; ``` -------------------------------- ### Security Checks and Multi-Service Architecture Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/fastly_specific_functions.md Examples demonstrating how to check for trusted services, manage multi-service architectures with service chaining, and implement authentication and authorization. ```APIDOC ## Check if the request came from the trusted service ### Description This VCL snippet checks if the incoming request originated from a trusted service ID and sets an appropriate HTTP header. ### Method N/A (VCL configuration) ### Endpoint N/A (VCL configuration) ### Request Body N/A ### Response Sets `req.http.X-Trusted-Service` header to "true" or "false". ### Example ```vcl set var.is_from_trusted_service = fastly.ff.last_hop_was_serviceid(var.trusted_service_id); if (var.is_from_trusted_service) { set req.http.X-Trusted-Service = "true"; } else { set req.http.X-Trusted-Service = "false"; if (req.url ~ "^/admin/") { error 403 "Access denied"; } } ``` ## Multi-service architecture with service chaining ### Description This example demonstrates how to implement a multi-service architecture by checking the service chain. It verifies if requests come through an authentication service or an API gateway, setting appropriate status headers and enforcing access controls. ### Method N/A (VCL configuration) ### Endpoint N/A (VCL configuration) ### Request Body N/A ### Response Sets `req.http.X-Auth-Status` header to "verified", "bypassed", or "unknown". May return errors (401, 403) for unauthorized access. ### Example ```vcl declare local var.auth_service_id STRING; declare local var.api_gateway_id STRING; set var.auth_service_id = "a1b2c3d4e5f6g7h8i9j0"; set var.api_gateway_id = "z9y8x7w6v5u4t3s2r1q0"; if (fastly.ff.last_hop_was_serviceid(var.auth_service_id)) { set req.http.X-Auth-Status = "verified"; } else if (fastly.ff.last_hop_was_serviceid(var.api_gateway_id)) { set req.http.X-Auth-Status = "bypassed"; if (req.url !~ "^/public/") { error 401 "Authentication required"; } } else { set req.http.X-Auth-Status = "unknown"; if (req.url !~ "^/public/") { error 403 "Direct access not allowed"; } } ``` ``` -------------------------------- ### Time Conversion and Calculation Examples Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/time_functions.md Examples demonstrating how to convert hexadecimal timestamps to time objects, calculate the difference between times, and check if a timestamp is in the future. ```APIDOC ## Convert hex to time ### Description Converts a hexadecimal timestamp string to a VCL TIME object. ### Method N/A (VCL function) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```vcl set var.event_time = time.hex_to_time(0, var.event_hex_time); ``` ### Response #### Success Response (200) N/A (VCL function) #### Response Example N/A ``` ```APIDOC ## Calculate time since event ### Description Calculates the duration between the current time and a specified event time. ### Method N/A (VCL function) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```vcl set var.time_since_event = time.sub(now, var.event_time); ``` ### Response #### Success Response (200) N/A (VCL function) #### Response Example N/A ``` ```APIDOC ## Checking if a hex timestamp is in the future ### Description Converts a hexadecimal timestamp to a TIME object and checks if it is after the current time. ### Method N/A (VCL function) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```vcl declare local var.future_hex_time STRING; declare local var.future_time TIME; declare local var.is_future BOOL; # Set a hexadecimal future time set var.future_hex_time = "FFFFFFFF"; # Convert hex to time set var.future_time = time.hex_to_time(0, var.future_hex_time); # Check if the time is in the future set var.is_future = time.is_after(var.future_time, now); # Log the result log "Is the timestamp in the future? " + if(var.is_future, "Yes", "No"); ``` ### Response #### Success Response (200) N/A (VCL function) #### Response Example N/A ``` ```APIDOC ## Converting multiple hex timestamps ### Description Demonstrates converting multiple hexadecimal timestamps to TIME objects and comparing them. ### Method N/A (VCL function) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```vcl declare local var.created_hex STRING; declare local var.updated_hex STRING; declare local var.created_time TIME; declare local var.updated_time TIME; # Set hexadecimal timestamps set var.created_hex = "5F700000"; set var.updated_hex = "5F800000"; # Convert hex to time set var.created_time = time.hex_to_time(0, var.created_hex); set var.updated_time = time.hex_to_time(0, var.updated_hex); # Log the results log "Created: " + strftime({"%Y-%m-%d %H:%M:%S"}, var.created_time); log "Updated: " + strftime({"%Y-%m-%d %H:%M:%S"}, var.updated_time); # Check which is more recent if (time.is_after(var.updated_time, var.created_time)) { log "Item has been updated since creation"; } ``` ### Response #### Success Response (200) N/A (VCL function) #### Response Example N/A ``` -------------------------------- ### Content-Based Routing Example Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/04-backend-configuration.md Routes requests to different backends based on URL path prefixes, enabling granular content delivery. ```vcl sub vcl_recv { # Route requests based on path if (req.url ~ "^/api/v1/") { set req.backend = F_api_v1; } else if (req.url ~ "^/api/v2/") { set req.backend = F_api_v2; } else if (req.url ~ "^/images/") { set req.backend = F_image_server; } else if (req.url ~ "^/videos/") { set req.backend = F_video_server; } else { set req.backend = F_default; } } ``` -------------------------------- ### Multiple Experiments with the Same User Base Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/random_functions.md This example shows how to run multiple experiments concurrently, ensuring users are consistently assigned to experiment groups. ```APIDOC ## Multiple Experiments with the Same User Base ### Description This example demonstrates how to run multiple experiments with the same user base, ensuring consistent assignment. ### Method N/A (VCL Snippet) ### Endpoint N/A (VCL Snippet) ### Request Body N/A ### Response N/A ### Code Example ```vcl declare local var.exp1_seed INTEGER; declare local var.exp2_seed INTEGER; declare local var.in_exp1 BOOL; declare local var.in_exp2 BOOL; # Create distinct seeds for each experiment by offsetting the user seed set var.exp1_seed = var.user_seed; set var.exp1_seed += 1; set var.exp2_seed = var.user_seed; set var.exp2_seed += 2; # Determine if the user is in each experiment set var.in_exp1 = randombool_seeded(1, 2, var.exp1_seed); set var.in_exp2 = randombool_seeded(1, 2, var.exp2_seed); # Set headers based on experiment participation set req.http.X-Header-Version = if(var.in_exp1, "new", "current"); set req.http.X-Footer-Version = if(var.in_exp2, "new", "current"); ``` ``` -------------------------------- ### Metric Threshold Lookup Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/table_functions.md This example shows how to look up a metric threshold from a table and set it in an HTTP header. ```APIDOC ## Metric Threshold Lookup ### Description Looks up the threshold for a given metric from the `metric_thresholds` table and sets it in the `X-Metric-Threshold` header. ### Method N/A (VCL Snippet) ### Endpoint N/A (VCL Snippet) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```vcl # Assume var.metric_name is set elsewhere set var.threshold = table.lookup_float(metric_thresholds, var.metric_name, 0.5); set req.http.X-Metric-Threshold = var.threshold; ``` ### Response #### Success Response (200) N/A (VCL Snippet modifies request headers) #### Response Example N/A ``` -------------------------------- ### Path-Specific Settings Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/table_functions.md This example shows how to extract the first segment of a URL path and apply specific settings, such as enabling or disabling caching, based on a lookup in a table. ```APIDOC ## Path-Specific Settings ### Description Extracts the first path segment from the request URL. It then checks a `path_settings` table to determine if caching is enabled for that segment. If caching is disabled, it sets the `X-Cache-Enabled` header to `false`. ### Method N/A (VCL Snippet) ### Endpoint N/A ### Parameters #### Query Parameters - **N/A** #### Request Body N/A ### Response N/A ### Code Example ```vcl declare local var.path_segment STRING; declare local var.cache_enabled BOOL; # Extract the first path segment if (req.url.path ~ "^/([^/]+)") { set var.path_segment = re.group.1; # Check if caching is enabled for this path set var.cache_enabled = table.lookup_bool(path_settings, var.path_segment + ":cache", true); if (!var.cache_enabled) { # Disable caching for this path set req.http.X-Cache-Enabled = "false"; } } ``` ``` -------------------------------- ### A/B Testing with Feature Flags Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/random_functions.md This example demonstrates how to enable a new feature for a percentage of users using seeded random boolean generation. ```APIDOC ## A/B Testing with Feature Flags ### Description This example demonstrates how to enable a new feature for a percentage of users using seeded random boolean generation. ### Method N/A (VCL Snippet) ### Endpoint N/A (VCL Snippet) ### Request Body N/A ### Response N/A ### Code Example ```vcl # Create a seed that offsets the user seed for this specific experiment set var.feature_seed = var.user_seed; set var.feature_seed += 100; # Enable the feature for 10% of users set var.feature_enabled = randombool_seeded(1, 10, var.feature_seed); if (var.feature_enabled) { # Enable the new feature set req.http.X-UI-Version = "new"; } else { # Use the existing feature set req.http.X-UI-Version = "current"; } ``` ``` -------------------------------- ### Restart Request for A/B Testing Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/miscellaneous_functions.md Restart the request to try an alternative URL for A/B testing purposes. This example redirects requests for `/feature/` to `/beta-feature/` on a 404. ```vcl if (req.restarts == 0 && resp.status == 404 && req.url.path ~ "^/feature/") { # Try the alternative URL set req.url = regsub(req.url.path, "^/feature/", "/beta-feature/"); restart; } ``` -------------------------------- ### Conditional Backend Selection by URL Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/miscellaneous_functions.md Select different backends based on URL patterns. This example routes API requests to specific backends. ```vcl if (req.url ~ "^/api/") { # Process API requests differently set req.backend = F_api_backend; if (req.url ~ "^/api/v1/") { # Use a specific backend for API v1 set req.backend = F_api_v1_backend; } # Skip the rest of vcl_recv return(lookup); } ``` -------------------------------- ### Basic Trigonometric Functions Example Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/math_functions.md Calculates and logs the sine, cosine, and tangent of a given angle in radians. Requires angle to be in radians for calculations. ```vcl declare local var.angle_degrees FLOAT; declare local var.angle_radians FLOAT; declare local var.sin_result FLOAT; declare local var.cos_result FLOAT; declare local var.tan_result FLOAT; # 45 degrees in radians (π/4) set var.angle_degrees = 45.0; set var.angle_radians = 0.7853981633974483; # Calculate trigonometric values set var.sin_result = math.sin(var.angle_radians); # ~0.7071 set var.cos_result = math.cos(var.angle_radians); # ~0.7071 set var.tan_result = math.tan(var.angle_radians); # ~1.0 # Log the results log "Angle in degrees: " + var.angle_degrees; log "Angle in radians: " + var.angle_radians; log "Sine: " + var.sin_result; log "Cosine: " + var.cos_result; log "Tangent: " + var.tan_result; ``` -------------------------------- ### Check if Maintenance Window Has Started in VCL Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/time_functions.md Determine if a scheduled maintenance period has begun by comparing the current time with the maintenance start time. This snippet assumes `var.maintenance_start` is set to the future maintenance start time. ```vcl declare local var.maintenance_start TIME; declare local var.maintenance_started BOOL; # Set maintenance start time to 1 hour from now set var.maintenance_start = time.add(now, 1h); # Check if maintenance has started set var.maintenance_started = time.is_after(now, var.maintenance_start); # Log the result log "Has maintenance started? " + if(var.maintenance_started, "Yes", "No"); # Should be "No" ``` -------------------------------- ### Build Query String Step-by-Step Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/query_string_functions.md Demonstrates building a query string by adding parameters sequentially using `querystring.add`. ```vcl set var.built_qs = ""; set var.built_qs = querystring.add(var.built_qs, "product", "laptop"); set var.built_qs = querystring.add(var.built_qs, "brand", "acme"); set var.built_qs = querystring.add(var.built_qs, "price", "500-1000"); # var.built_qs is now "product=laptop&brand=acme&price=500-1000" log "Built query string: " + var.built_qs; ``` -------------------------------- ### Sequential processing with goto in VCL Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/miscellaneous_functions.md This example demonstrates sequential processing logic within VCL, where 'goto' is not explicitly used for branching but the code flows sequentially. It includes validation steps for request method and URL path. ```vcl declare local var.status STRING; set var.status = "unknown"; # Validate the request method if (req.method != "GET" && req.method != "POST") { set var.status = "invalid_method"; } else if (req.url.path !~ "^/api/") { # Validate the URL set var.status = "invalid_path"; } else { # If we get here, the request is valid set var.status = "valid"; } set req.http.X-Validation-Status = var.status; ``` -------------------------------- ### Combining Early Hints with HTTP/2 Server Push Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/fastly_specific_functions.md Demonstrates using both Early Hints and HTTP/2 Server Push concurrently. Early Hints are sent to all browsers, while Server Push can be used for more specific resource delivery strategies. ```vcl # Send Early Hints for all browsers early_hints( "; rel=preload; as=style", "; rel=preload; as=script" ); ``` -------------------------------- ### Check if Current Time is Within a Time Window in VCL Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/time_functions.md Verify if the current time falls within a specified time window defined by a start and end time. This requires checking if the current time is after the start time and not after the end time. ```vcl declare local var.window_start TIME; declare local var.window_end TIME; declare local var.in_window BOOL; # Set time window set var.window_start = time.add(now, -1h); # 1 hour ago set var.window_end = time.add(now, 1h); # 1 hour from now # Check if current time is in the window (after start AND before end) set var.in_window = false; if (time.is_after(now, var.window_start)) { if (!time.is_after(now, var.window_end)) { set var.in_window = true; } } # Log the result log "Is current time in the window? " + if(var.in_window, "Yes", "No"); # Should be "Yes" ``` -------------------------------- ### Basic Token Checking Example Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/waf_functions.md Demonstrates how to check the number of remaining tokens in a rate limit bucket associated with a client IP. This can be used for informational purposes or more complex logic. ```vcl declare local var.ip_allowed BOOL; declare local var.tokens_remaining INTEGER; ``` -------------------------------- ### Content Negotiation with accept.media_lookup Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/accept_header_functions.md Demonstrates how to use the `accept.media_lookup` function to determine the best matching media type from an Accept header. ```APIDOC ## Content Negotiation with accept.media_lookup ### Description This function helps in selecting the most appropriate media type from a list of available types based on the client's `Accept` header. It supports fallback to a default media type if no direct match is found. ### Function Signature ```vcl STRING accept.media_lookup(STRING available_media_types, STRING default_media_type, STRING media_type_patterns, STRING accept_header) ``` ### Parameters #### Parameters - **available_media_types** (STRING) - Required - Colon-separated list of media types available for the resource. - **default_media_type** (STRING) - Required - Fallback media type if no match is found. - **media_type_patterns** (STRING) - Required - Colon-separated list of media types corresponding to media type patterns. - **accept_header** (STRING) - Required - The Accept header value to parse. ### Return Value The best matching media type from the available list, or the default if no match. ### RFC Compliance Conforms to RFC 7231, Section 5.3.2 ### Examples #### Content type negotiation This example selects the best media type match from the Accept header: ```vcl declare local var.selected_media_type STRING; set var.selected_media_type = accept.media_lookup( "application/json:application/xml:text/html:text/plain", # Available media types "application/json", # Default media type "application/json:application/xml:text/html:text/plain", # Media type patterns req.http.Accept ); ``` #### API version content negotiation This example demonstrates how to handle API versioning through content negotiation: ```vcl if (req.url ~ "^/api/") { declare local var.api_media_types STRING; set var.api_media_types = "application/vnd.company.api.v2+json:" + "application/vnd.company.api.v1+json:" + "application/json"; set var.selected_media_type = accept.media_lookup( var.api_media_types, "application/json", # Default to latest version var.api_media_types, # Media type patterns req.http.Accept ); # Set API version based on selected media type if (var.selected_media_type == "application/vnd.company.api.v2+json") { set req.http.X-API-Version = "v2"; } else if (var.selected_media_type == "application/vnd.company.api.v1+json") { set req.http.X-API-Version = "v1"; } else { set req.http.X-API-Version = "v2"; # Default to latest } } ``` #### Format-based URL rewriting This example shows how to rewrite URLs based on preferred format: ```vcl if (req.url !~ "\.(json|xml|html|txt)$") { if (var.selected_media_type == "application/json") { set req.url = req.url + ".json"; } else if (var.selected_media_type == "application/xml") { set req.url = req.url + ".xml"; } else if (var.selected_media_type == "text/html") { set req.url = req.url + ".html"; } else if (var.selected_media_type == "text/plain") { set req.url = req.url + ".txt"; } } ``` ``` -------------------------------- ### Logging API Requests Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/waf_functions.md Logs all requests to endpoints starting with /api/. ```APIDOC ## Logging API Requests ### Description Logs all requests to endpoints starting with /api/. ### Method N/A (VCL Snippet) ### Endpoint N/A ### Parameters None ### Request Example None ### Response None ### Error Handling None ``` -------------------------------- ### Trigonometric Functions Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/math_functions.md Provides an overview and examples for standard and inverse trigonometric functions. ```APIDOC ## Trigonometric Functions ### Description This group of functions handles standard trigonometric operations like sine, cosine, and tangent, as well as their inverse counterparts. ### Functions - **math.sin(FLOAT x)**: Calculates the sine of an angle in radians. - **math.cos(FLOAT x)**: Calculates the cosine of an angle in radians. - **math.tan(FLOAT x)**: Calculates the tangent of an angle in radians. - **math.asin(FLOAT x)**: Calculates the arcsine (inverse sine) of a value between -1 and 1. - **math.acos(FLOAT x)**: Calculates the arccosine (inverse cosine) of a value between -1 and 1. - **math.atan(FLOAT x)**: Calculates the arctangent (inverse tangent) of a value. - **math.atan2(FLOAT y, FLOAT x)**: Calculates the arctangent of y/x, using the signs of both arguments to determine the quadrant. ### Parameters - **x** (FLOAT): The angle in radians or the value for inverse functions. - **y** (FLOAT): The y-coordinate for `math.atan2`. ### Return Value - For `math.sin`, `math.cos`, `math.tan`, `math.asin`, `math.acos`, `math.atan`, `math.atan2`: The result in radians. ### Example ```vcl declare local var.angle_radians FLOAT; declare local var.sin_result FLOAT; set var.angle_radians = 0.7853981633974483; # PI/4 radians set var.sin_result = math.sin(var.angle_radians); # ~0.7071 log "Sine of PI/4: " + var.sin_result; ``` ``` -------------------------------- ### Generate Hashes with Different Algorithms Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/digest_functions.md Demonstrates generating MD5, SHA-1, SHA-256, and SHA-512 hashes for a given string and setting them as HTTP headers. ```vcl declare local var.input STRING; declare local var.hash_md5 STRING; declare local var.hash_sha1 STRING; declare local var.hash_sha256 STRING; declare local var.hash_sha512 STRING; set var.input = "Fastly VCL Example"; # Generate hashes using different algorithms set var.hash_md5 = digest.hash_md5(var.input); set var.hash_sha1 = digest.hash_sha1(var.input); set var.hash_sha256 = digest.hash_sha256(var.input); set var.hash_sha512 = digest.hash_sha512(var.input); # Set headers with the hash values for demonstration set req.http.X-Hash-MD5 = var.hash_md5; set req.http.X-Hash-SHA1 = var.hash_sha1; set req.http.X-Hash-SHA256 = var.hash_sha256; set req.http.X-Hash-SHA512 = var.hash_sha512; ``` -------------------------------- ### table.contains Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/table_functions.md Provides an example of using `table.contains` to check for the existence of a key within a table. ```APIDOC ## table.contains ### Description Checks if a specified key exists within a given table. Returns TRUE if the key is found, and FALSE otherwise. ### Method Not Applicable (VCL Function) ### Endpoint Not Applicable (VCL Function) ### Parameters - **table_name** (TABLE) - The table to check (a table identifier, not a string) - **key** (STRING) - The key to check for ### Request Body None ### Request Example #### Basic key existence check ```vcl declare local var.api_key STRING; declare local var.key_exists BOOL; # Assume var.api_key is set elsewhere # set var.api_key = "some_api_key"; # Check if the API key exists in the 'allowed_keys' table set var.key_exists = table.contains(allowed_keys, var.api_key); if (!var.key_exists) { # Handle the case where the key does not exist return(synth(403, "Forbidden")); } ``` ### Response #### Success Response (200) None (Returns a boolean value) #### Response Example None ``` -------------------------------- ### Input Validation Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/table_functions.md Example of how to validate input fields against regular expressions stored in a table. ```APIDOC ## Input Validation ### Description Validates input field values against predefined regular expression patterns stored in a table. ### Method Not Applicable (VCL Snippet) ### Endpoint Not Applicable (VCL Snippet) ### Parameters None ### Request Body None ### Request Example ```vcl declare local var.field_name STRING; declare local var.validation_pattern REGEX; set var.field_name = "email"; # Look up the validation pattern for this field set var.validation_pattern = table.lookup_regex(validation_patterns, var.field_name); # Check if the field value matches the validation pattern if (req.http.X-Field-Value !~ var.validation_pattern) { set req.http.X-Validation-Error = "true"; } ``` ### Response #### Success Response (200) None (Modifies request headers) #### Response Example None ``` -------------------------------- ### Basic Early Hints Usage Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/fastly_specific_functions.md Sends an HTTP 103 Early Hints response with Link headers for critical resources like CSS, JavaScript, and fonts. This example targets HTML pages and sends multiple resources in a single call. ```vcl # Only send Early Hints for HTML pages if (req.url.ext == "html" || req.url == "/" || req.url !~ ".[a-z]+$") { # Send Early Hints for critical CSS, JavaScript, and fonts together early_hints( "; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=font; crossorigin" ); } ``` -------------------------------- ### h2.push Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/fastly_specific_functions.md Provides examples for using the `h2.push` function to trigger HTTP/2 server pushes. ```APIDOC ## h2.push ### Description Triggers an HTTP/2 server push of the asset at the specified path. It can optionally take a content type hint. ### Method N/A (VCL configuration) ### Endpoint N/A (VCL configuration) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Return Value None ### Examples #### Basic HTTP/2 server push This example demonstrates how to push critical assets to the client for different URLs. ```vcl # Only push if the client supports HTTP/2 if (fastly_info.is_h2 && !req.http.Fastly-FF) { # Push critical assets for the homepage if (req.url == "/" || req.url == "/index.html") { h2.push("/css/main.css"); h2.push("/js/main.js"); h2.push("/images/logo.png"); } # Push critical assets for the product page if (req.url ~ "^/products/[^/]+$") { h2.push("/css/product.css"); h2.push("/js/product.js"); h2.push("/js/reviews.js"); } } ``` #### Conditional HTTP/2 server push based on client capabilities This example demonstrates more sophisticated push strategies (the example is incomplete in the source text). ```vcl ``` -------------------------------- ### Prefix and Suffix Checking Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/standard_utility_functions.md Functions to check if a string starts or ends with a specific prefix or suffix. ```APIDOC ## std.prefixof (Example Usage) ### Description Checks if a string starts with a specified prefix. ### Example Usage ```vcl declare local var.url STRING; declare local var.has_api_prefix BOOL; set var.url = "/api/users.json"; # Check if URL starts with "/api/" set var.has_api_prefix = std.prefixof("/api/", var.url); if (var.has_api_prefix) { log "URL has API prefix"; } ``` ## std.suffixof (Example Usage) ### Description Checks if a string ends with a specified suffix. ### Example Usage ```vcl declare local var.url STRING; declare local var.has_json_suffix BOOL; set var.url = "/api/users.json"; # Check if URL ends with ".json" set var.has_json_suffix = std.suffixof(".json", var.url); if (var.has_json_suffix) { log "URL has JSON suffix"; } ``` ``` -------------------------------- ### Process and Normalize Query Parameters Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/standard_utility_functions.md This example demonstrates how to extract query parameters like 'page' and 'limit' using querystring.get, convert them to integers with std.atoi, and apply validation rules to ensure they fall within acceptable ranges. ```vcl declare local var.page_param STRING; declare local var.page INTEGER; declare local var.limit_param STRING; declare local var.limit INTEGER; # Get pagination parameters from query string set var.page_param = querystring.get(req.url, "page"); set var.limit_param = querystring.get(req.url, "limit"); # Convert to integers with default values if (var.page_param == "") { set var.page = 1; # Default page } else { set var.page = std.atoi(var.page_param); # Ensure page is at least 1 if (var.page < 1) { set var.page = 1; } } if (var.limit_param == "") { set var.limit = 20; # Default limit } else { set var.limit = std.atoi(var.limit_param); # Ensure limit is between 1 and 100 if (var.limit < 1) { set var.limit = 1; } else if (var.limit > 100) { set var.limit = 100; } } # Set normalized pagination parameters set req.http.X-Page = var.page; set req.http.X-Limit = var.limit; ``` -------------------------------- ### VCL Comments Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/03-vcl-basics.md VCL supports single-line comments starting with // and multi-line comments enclosed in /* */. ```vcl // This is a single-line comment ``` ```vcl /* This is a multi-line comment */ ``` -------------------------------- ### Configure Basic Backend Parameters in VCL Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/04-backend-configuration.md Define a backend with common parameters including host, port, SSL settings, and timeouts. `.ssl` should be true for HTTPS. Timeouts like `.connect_timeout`, `.first_byte_timeout`, and `.between_bytes_timeout` can be adjusted for performance. ```vcl backend F_my_origin { .host = "www.example.com"; .port = "443"; .ssl = true; .ssl_cert_hostname = "www.example.com"; .ssl_sni_hostname = "www.example.com"; .ssl_check_cert = always; .min_tls_version = "TLSv1.2"; .max_tls_version = "TLSv1.3"; .connect_timeout = 1s; .first_byte_timeout = 15s; .between_bytes_timeout = 10s; } ``` -------------------------------- ### uuid.is_version3 Source: https://github.com/jedisct1/fastly-vcl-examples/blob/main/vcl-functions/uuid_functions.md Checks if a given string is a valid UUID version 3. Includes examples for validation. ```APIDOC ## uuid.is_version3 ### Description Checks if a string is a valid UUID version 3. ### Method N/A (VCL Function) ### Endpoint N/A (VCL Function) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Parameters - **uuid** (STRING) - The string to check. ### Return Value - TRUE if the string is a valid UUID version 3 - FALSE otherwise ### Request Example N/A ### Response N/A ### Examples #### Basic UUID version 3 validation ```vcl declare local var.uuid STRING; declare local var.is_v3 BOOL; # Set a UUID to validate set var.uuid = "6fa459ea-ee8a-3ca4-894e-db77e160355e"; # Example UUID v3 # Check if the UUID is version 3 set var.is_v3 = uuid.is_version3(var.uuid); # Log the result log "UUID: " + var.uuid; log "Is version 3: " + if(var.is_v3, "Yes", "No"); ``` #### Validating a generated UUID version 3 ```vcl declare local var.namespace STRING; declare local var.name STRING; declare local var.generated_uuid STRING; declare local var.generated_is_v3 BOOL; # Set namespace and name set var.namespace = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; # DNS namespace set var.name = "example.com"; # Generate a UUID version 3 set var.generated_uuid = uuid.version3(var.namespace, var.name); # Check if the generated UUID is version 3 set var.generated_is_v3 = uuid.is_version3(var.generated_uuid); # Log the result log "Generated UUID: " + var.generated_uuid; log "Is version 3: " + if(var.generated_is_v3, "Yes", "No"); ``` #### Validating a UUID version 4 (should be false) ```vcl declare local var.uuid_v4 STRING; declare local var.is_v4_v3 BOOL; # Generate a UUID version 4 set var.uuid_v4 = uuid.version4(); # Check if the UUID version 4 is version 3 set var.is_v4_v3 = uuid.is_version3(var.uuid_v4); # Log the result log "UUID v4: " + var.uuid_v4; log "Is version 3: " + if(var.is_v4_v3, "Yes", "No"); # Should be "No" ``` #### Validating a UUID from a header ```vcl declare local var.header_uuid STRING; declare local var.header_is_v3 BOOL; # Get a UUID from a header set var.header_uuid = req.http.X-Request-ID; # Check if the header UUID is version 3 set var.header_is_v3 = uuid.is_version3(var.header_uuid); # Log the result log "Header UUID: " + var.header_uuid; log "Is version 3: " + if(var.header_is_v3, "Yes", "No"); ``` ```