# Match Types Explained

Turbo Rate Limiter offers five different match types for defining which URLs should be rate limited. Each match type serves a specific purpose and is suited to different scenarios. Understanding the differences between these match types will help you create more effective and precise rate limiting filters.

---

## Overview of Match Types

| Match Type | Best For | Performance | Example Pattern | Matches |
|------------|----------|-------------|-----------------|---------|
| Exact | Single URLs | Fastest (O(1)) | `/wp-login.php` | `/wp-login.php` only |
| Starts With | Directory paths | Fast | `/api/` | `/api/users`, `/api/posts` |
| Ends With | File types | Fast | `.xml` | `/feed.xml`, `/sitemap.xml` |
| Contains | Path segments | Moderate | `/wp-admin/` | Any URL containing `/wp-admin/` |
| Regex | Complex patterns | Slowest | `^/api/v\d+/` | `/api/v1/users`, `/api/v2/posts` |

---

## Exact Match

The **Exact** match type is the simplest and most efficient option. It matches a URL only if the entire URI matches your pattern exactly, character for character, including any trailing slashes or query parameters you include.

### When to Use Exact Match

Exact matching is ideal when you want to target a single, specific URL. It's perfect for protecting individual endpoints like login pages, specific API endpoints, or any URL that has a unique path that won't change.

Because exact matching uses a direct hash table lookup (O(1) time complexity), it's the fastest possible matching method. If you know the exact URL you want to protect and it won't vary, always prefer exact matching for the best performance.

### Exact Match Examples

Here are common scenarios where exact matching works well:

**Login Page Protection**
```
Pattern: /wp-login.php
Matches:
  ✅ /wp-login.php
  ❌ /wp-login.php/
  ❌ /wp-login.php?redirect_to=/admin
```

**XML RPC Protection**
```
Pattern: /xmlrpc.php
Matches:
  ✅ /xmlrpc.php
  ❌ /xmlrpc.php?rsd
```

**Specific REST API Endpoint**
```
Pattern: /wp-json/wp/v2/users
Matches:
  ✅ /wp-json/wp/v2/users
  ❌ /wp-json/wp/v2/users/123
```

### Important Notes About Exact Matching

Exact matching is case-sensitive by default. The pattern `/WP-Login.php` would not match `/wp-login.php`. If you need case-insensitive matching, use the Contains or Regex match types instead.

Query parameters are not included in exact matching by default. If you want to match URLs with query parameters, use the Contains match type or the Regex match type with appropriate pattern modifications.

---

## Starts With

The **Starts With** match type matches any URL that begins with your specified pattern. This is particularly useful when you want to protect an entire directory or namespace of URLs with a single filter.

### When to Use Starts With

Use Starts With matching when you want to protect a group of URLs that share a common prefix. This includes protecting entire directories like `/api/`, `/wp-admin/`, or any custom URL namespace you've created for your site.

The matching algorithm processes Starts With filters in order of pattern length, with the longest patterns checked first. This means that if you have overlapping patterns like `/api/` and `/api/v1/`, the more specific `/api/v1/` pattern will be checked first.

### Starts With Examples

**API Endpoint Protection**
```
Pattern: /api/
Matches:
  ✅ /api/users
  ✅ /api/posts
  ✅ /api/v1/users
  ✅ /api/v2/posts
  ❌ /wp-json/api/
```

**Admin Area Protection**
```
Pattern: /wp-admin/
Matches:
  ✅ /wp-admin/
  ✅ /wp-admin/index.php
  ✅ /wp-admin/users.php
  ❌ /wp-admin.php (missing trailing slash)
```

**Custom Namespace Protection**
```
Pattern: /my-custom-app/
Matches:
  ✅ /my-custom-app/
  ✅ /my-custom-app/dashboard
  ✅ /my-custom-app/api/endpoint
```

### Tips for Starts With Matching

Remember that Starts With matching is literal and does not automatically add or remove trailing slashes. Be consistent in your patterns—if your URLs use trailing slashes, include them in your pattern.

For WordPress admin protection, many installations have both `/wp-admin/` with a trailing slash and `/wp-admin` without. Consider creating two filters: one with the trailing slash and one without, or use the Contains match type instead.

---

## Ends With

The **Ends With** match type matches any URL that concludes with your specified pattern. This is particularly useful when you want to target specific file types or URLs that consistently end with a particular extension.

### When to Use Ends With

Ends With matching excels when you want to rate limit access to specific file types across your entire site. For example, if you want to limit how often bots can download XML files like sitemaps or RSS feeds, Ends With matching makes this straightforward.

This match type is also useful for targeting specific URL patterns that always end with a particular path segment, such as `/login`, `/register`, or `/checkout`.

### Ends With Examples

**XML File Protection**
```
Pattern: .xml
Matches:
  ✅ /sitemap.xml
  ✅ /feed.xml
  ✅ /sitemap-index.xml
  ❌ /sitemap.html
```

**Sitemap Protection**
```
Pattern: /sitemap.xml
Matches:
  ✅ /sitemap.xml
  ✅ /sitemap-index.xml
  ❌ /wp-sitemap.xml (WordPress default)
```

**Specific Page Endings**
```
Pattern: /checkout
Matches:
  ✅ /products/checkout
  ✅ /store/checkout
  ❌ /checkout/ (different ending)
```

### Tips for Ends With Matching

The pattern is matched against the end of the entire URL, not just the filename. This means that `.xml` will match any URL ending with those four characters, including URLs that happen to end with those characters but aren't actually XML files.

For more precise file type matching, consider using the Contains match type with a more specific pattern like `.xml` or combine Ends With with other filters to narrow down the matches.

---

## Contains

The **Contains** match type matches any URL that includes your specified pattern anywhere within it. This is the most flexible of the literal match types and is useful when the URLs you want to protect don't share a consistent prefix or suffix.

### When to Use Contains

Use Contains matching when you want to protect URLs that share a common segment but appear in different parts of the URL path. This is particularly useful for matching WordPress-specific URLs that might appear with or without trailing slashes, or for matching URLs that include query parameters.

Contains matching is also the go-to choice when you're not sure of the exact URL structure but know there's a specific string that appears in the URLs you want to protect.

### Contains Examples

**WordPress Admin Protection (Flexible)**
```
Pattern: /wp-admin/
Matches:
  ✅ /wp-admin/
  ✅ /wp-admin/index.php
  ✅ /wp-admin/users.php
  ✅ /?admin=1 (if pretty permalinks aren't used)
```

**Search Query Protection**
```
Pattern: ?s=
Matches:
  ✅ /?s=keyword
  ✅ /search/?s=keyword
  ✅ /?s=another+search
  ❌ /search/keyword (pretty permalinks)
```

**REST API Protection**
```
Pattern: /wp-json/
Matches:
  ✅ /wp-json/wp/v2/posts
  ✅ /wp-json/
  ✅ /?rest_route=/wp/v2/users
```

**Plugin-Specific URLs**
```
Pattern: /my-plugin/
Matches:
  ✅ /my-plugin/settings
  ✅ /wp-admin/admin-ajax.php?action=my_plugin
  ✅ /?page=my-plugin-dashboard
```

### Performance Considerations

Contains matching requires scanning the URL for the pattern, which is slower than exact, starts with, or ends with matching. While this difference is negligible for most sites with a small number of filters, if you have many filters using Contains matching, consider whether a different match type might work.

For example, if you're using Contains `/wp-admin/` to handle both `/wp-admin/` and `/wp-admin`, consider creating two separate filters: one with exact `/wp-admin/` and one with exact `/wp-admin`, rather than relying on Contains.

---

## Regex (Regular Expression)

The **Regex** match type uses regular expressions to match URLs. This provides the most powerful and flexible matching capability but also requires the most care to use correctly.

### When to Use Regex

Use regex matching when your URL patterns are too complex for the literal match types. Common use cases include matching multiple similar URLs with a single pattern, matching URLs with variable segments, or creating patterns that combine multiple conditions.

Regex is also useful when you need case-insensitive matching or when you need to match patterns that include special characters that would be interpreted literally by other match types.

### Regex Examples

**Multiple API Versions**
```
Pattern: ^/api/v[0-9]+/
Matches:
  ✅ /api/v1/users
  ✅ /api/v2/posts
  ✅ /api/v10/comments
  ❌ /api/v/users (non-numeric version)
```

**Case-Insensitive Matching**
```
Pattern: (?i)/wp-login\.php
Matches:
  ✅ /wp-login.php
  ✅ /WP-Login.php
  ✅ /Wp-Login.Php
```

**Multiple Endpoints**
```
Pattern: /wp-json/(wp/v2|my-custom/v1)/
Matches:
  ✅ /wp-json/wp/v2/posts
  ✅ /wp-json/my-custom/v1/users
  ❌ /wp-json/wp/v3/posts
```

**Numeric ID Patterns**
```
Pattern: /wp-json/wp/v2/posts/[0-9]+$
Matches:
  ✅ /wp-json/wp/v2/posts/123
  ✅ /wp-json/wp/v2/posts/456789
  ❌ /wp-json/wp/v2/posts/abc
```

**Query Parameter Matching**
```
Pattern: \?s=
Matches:
  ✅ /?s=test
  ✅ /search/?s=test
  ✅ /index.php?s=test
```

### Regex Syntax Reference

Turbo Rate Limiter uses PHP's PCRE (Perl Compatible Regular Expressions) engine. Here are some common regex metacharacters and patterns you'll find useful:

**Anchors**
- `^` matches the start of the string
- `$` matches the end of the string

**Character Classes**
- `[0-9]` matches any digit
- `[a-z]` matches any lowercase letter
- `[a-zA-Z]` matches any letter
- `\w` matches any word character (alphanumeric plus underscore)
- `.` matches any character (except newline)

**Quantifiers**
- `+` matches one or more of the preceding element
- `*` matches zero or more of the preceding element
- `{n}` matches exactly n occurrences
- `{n,m}` matches between n and m occurrences

**Special Sequences**
- `\.` matches a literal period
- `\d` matches any digit (same as `[0-9]`)
- `\s` matches any whitespace

### Common Mistakes with Regex

**Forgetting to Escape Special Characters**

In regex, many characters have special meaning. If you want to match them literally, you must escape them with a backslash:

```
Correct:   /wp-login\.php
Incorrect: /wp-login.php  (the . matches any character)
```

**Overly Broad Patterns**

Regex can easily match more than you intend. Always test your patterns in Test Mode to verify they match only what you expect:

```
Too broad:  /api.*
This matches: /api/users, /api/v1, /apichange-password

Better:     /api/.*
This matches: /api/users, /api/v1
This does not match: /apichange-password
```

**Not Using Anchors**

Without anchors, your pattern can match anywhere in the URL, which might catch URLs you didn't intend:

```
Without anchors: /wp-admin
This matches: /wp-admin, /something/wp-admin, /wp-admin-extra

With start anchor: ^/wp-admin
This matches: /wp-admin, /wp-admin/
This does not match: /something/wp-admin
```

---

## Choosing the Right Match Type

Selecting the appropriate match type is crucial for creating effective and performant rate limiting filters. Here's a decision guide to help you choose.

### Decision Flow

1. **Do you need to match a single, specific URL?**
   - Yes → Use **Exact Match**
   - No → Continue

2. **Do all URLs you want to protect share a common prefix?**
   - Yes → Use **Starts With**
   - No → Continue

3. **Do all URLs you want to protect share a common suffix?**
   - Yes → Use **Ends With**
   - No → Continue

4. **Do the URLs share a common segment but in different positions?**
   - Yes → Use **Contains**
   - No → Continue

5. **Do you need complex pattern matching with variables or conditions?**
   - Yes → Use **Regex**
   - No → Use **Contains** as a fallback

### Performance Considerations

If performance is critical and you have many filters, consider the following hierarchy:

1. **Exact Match**: Fastest, use for single URLs
2. **Starts With / Ends With**: Fast, use for directories and file types
3. **Contains**: Moderate, use for flexible matching
4. **Regex**: Slowest, use only when necessary

---

## Combining Multiple Filters

Sometimes a single match type isn't sufficient. You can create multiple filters for the same resource to handle different URL variations.

### Example: Comprehensive Login Protection

Rather than relying on a single filter, create multiple filters to cover different login URL variations:

```
Filter 1 (Exact): /wp-login.php
Filter 2 (Exact): /wp-login.php/
Filter 3 (Contains): ?action=login
Filter 4 (Contains): ?log= (for older WP versions)
```

### Example: API Version Protection

To protect multiple API versions comprehensively:

```
Filter 1 (Regex): ^/api/v[0-9]+/.*
Filter 2 (Contains): rest_route=
```

---

## Testing Your Match Types

Always use Test Mode to verify your filters match the correct URLs before enabling them in production.

### Test Mode Best Practices

1. Visit URLs that should match your filter and verify they appear in the test results
2. Visit URLs that should NOT match and verify they don't appear
3. Test edge cases like URLs with trailing slashes, query parameters, and unusual characters
4. Test from different network locations if possible (different IP addresses)

---

## Related Documentation

- **[Getting Started Guide](getting-started.md)**: Overview of the plugin and its features
- **[Rate Limiting Best Practices](best-practices.md)**: Strategies for effective rate limiting
- **[FAQ](faq.md)**: Find answers to common questions

---

*Last updated for Turbo Rate Limiter v1.0.0*
