Skip to content

A Caddy plugin that matches HTTP requests based on cron expressions

License

Notifications You must be signed in to change notification settings

steffenbusch/caddy-cron-matcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cron Matcher Caddy Plugin

The Cron Matcher plugin for Caddy allows you to match HTTP requests based on cron expressions. It enables you to define time windows during which certain routes or handlers should be active. This plugin is useful for scheduling maintenance windows, rate limiting during peak hours, or any time-based request handling logic. By leveraging cron expressions, you can precisely control when specific request matchers are active, integrating flexible scheduling into your Caddy configurations.

Go Report Card

Features

This plugin introduces a new matcher that can be used within Caddy configurations:

  • cron matcher: Matches requests based on time windows defined by cron expressions.

Key Capabilities

  • Time-Based Request Matching: Activate or deactivate request handlers based on precise time schedules.
  • Flexible Scheduling: Use cron expressions to define complex schedules, including specific times, ranges, and intervals.
  • Dynamic Control: Enable features like maintenance modes, time-limited promotions, or access restrictions during specific hours.
  • Multiple Schedule Support: Combine multiple cron expressions to create OR-based matching.

Building

To build Caddy with this module, use xcaddy:

$ xcaddy build --with github.com/steffenbusch/caddy-cron-matcher

Caddyfile Configuration

The cron matcher requires two cron expressions:

  • enable_at: Specifies when the matcher should start matching requests.
  • disable_at: Specifies when the matcher should stop matching requests.

Both expressions must be valid cron expressions and are required. Multiple cron matchers within a named matcher will be OR'ed together.

Note on Time Matching Behavior: The CronMatcher considers now as inclusive when it aligns exactly with the enable_at time. This means that if the current time precisely matches the enable_at expression, it is treated as valid and within the active matching window. The disable_at time marks the end of the range and is not included in matches.

Syntax

@timedRequest cron <enable_at> <disable_at>

Multiple entries can be defined like this:

@timedRequest {
    cron <enable_at> <disable_at>
    cron <enable_at_2> <disable_at_2>
}

Examples

Example 1: Active Between 10:00 and 11:00 Daily

@timedRequest cron "0 10 * * *" "0 11 * * *"

handle @timedRequest {
    respond "This route is active between 10:00 and 11:00."
}

handle {
    respond "This route is active outside of 10:00 to 11:00."
}

Example 2: Maintenance Mode on Sundays

@maintenanceMode cron "0 0 * * SUN" "0 0 * * MON"

handle @maintenanceMode {
    respond "Maintenance mode is active."
}

handle {
    reverse_proxy localhost:8080
}

In this example, the maintenance mode is activated every Sunday at 00:00 and deactivated on Monday at 00:00.

Example 3: Multiple OR'ed Cron Schedules for Complex Maintenance

@maintenance {
    cron "45 22 * * 1-5" "15 23 * * 1-5"
    cron "15 23 * * 0,6" "45 23 * * 0,6"
}

handle @maintenance {
    respond "It's in Maintenance"
}

handle {
    respond "No Maintenance"
}

In this example, the route matches any of the defined time windows. Maintenance is active from 22:45 to 23:15 on weekdays and from 23:15 to 23:45 on weekends.

Example 4: Special Promotion During Business Hours

@businessHours cron "0 9 * * 1-5" "0 17 * * 1-5"

handle @businessHours {
    respond "Welcome! Enjoy our special business hours promotion."
}

handle {
    reverse_proxy localhost:8080
}

In this example, a promotional message is displayed during business hours from 09:00 to 17:00, Monday through Friday. Outside of these hours, requests are proxied to the backend application. This setup is ideal for displaying special offers or notices during operating hours.

Error Handling

  • Both enable_at and disable_at are required: If either is missing, Caddy will fail to start, and an error will be logged.
  • Invalid Cron Expressions: If an invalid cron expression is provided, Caddy will fail to start, and an error indicating the invalid format will be logged.

Notes

  • Time Zone Considerations: Cron expressions are evaluated based on the server's local time zone. Ensure that your server's time zone is configured correctly to match your intended schedule.
  • Cron Expression Format: The cron expressions follow the standard format:
* * * * *
│ │ │ │ │
│ │ │ │ └─ Day of the week (0-6 or SUN-SAT)
│ │ │ └─── Month (1-12 or JAN-DEC)
│ │ └───── Day of the month (1-31)
│ └─────── Hour (0-23)
└───────── Minute (0-59)

Advanced Cron Expressions

While the commonly used 5-segment cron format (<minute> <hour> <day> <month> <weekday>) is supported, the underlying library (Gronx) provides extended functionality with a 6-segment style that includes <year>. This format allows for more precise scheduling:

  • A complete cron expression consists of 7 segments: <second> <minute> <hour> <day> <month> <weekday> <year>.
  • For a 6-segment expression, if the 6th segment matches <year> (e.g., at least 4 digits), it is interpreted as <minute> <hour> <day> <month> <weekday> <year>. A default value of 0 is used for <second>.

Additionally, Gronx supports advanced modifiers for the <day> and <weekday> segments:

  • L (Last):
    • In the <day> segment, L represents the last day of the month (e.g., L could mean February 29th in a leap year).
    • In the <weekday> segment, L refers to the last occurrence of a specific weekday in a month (e.g., 2L means the last Tuesday of the month).
  • W (Weekday):
    • For <day>, W specifies the closest weekday (Monday to Friday) to a given day (e.g., 10W means the closest weekday to the 10th of the month).
  • # (Nth weekday):
    • In the <weekday> segment, # denotes the nth occurrence of a specific day in a month (e.g., 1#2 means the second Monday of the month).

For a complete overview of these features, refer to the Gronx README.

Advanced Cron Expressions in Action

These features enable precise and complex scheduling, such as Oracle's Critical Patch Updates that occur on the third Tuesday of January, April, July, and October. Below is an example demonstrating how to configure this in Caddy:

@criticalPatchTuesday cron "0 0 * 1,4,7,10 2#3" "30 23 * 1,4,7,10 2#3"

handle @criticalPatchTuesday {
    respond "Oracle Critical Patch Update in progress: Third Tuesday of January, April, July, and October."
}

handle {
    reverse_proxy localhost:8080
}

Step-by-Step Breakdown of the Example:

  1. "0 0 * 1,4,7,10 2#3":

    • 1,4,7,10: Matches the months January, April, July, and October.
    • 2#3: Matches the third Tuesday (weekday 2 for Tuesday and #3 for the third occurrence of that day in the month).
    • The day field (*) is ignored because the 2#3 modifier already specifies the exact match.
  2. "30 23 * 1,4,7,10 2#3":

    • Ends the match at 23:30 on the same day.

License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.

Acknowledgements

  • Caddy for providing a powerful and extensible web server.
  • Gronx for cron expression parsing and time calculations, used under the MIT License.

About

A Caddy plugin that matches HTTP requests based on cron expressions

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages