or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

base-filtering.mdcors-filter.mddos-protection.mdheader-management.mdindex.mdquality-of-service.mdserver-sent-events.md

base-filtering.mddocs/

0

# Base Filtering Patterns

1

2

Abstract base class for filters that need path, MIME type, or HTTP method-based filtering capabilities. The IncludeExcludeBasedFilter provides a foundation for creating custom filters with flexible request matching criteria.

3

4

## Capabilities

5

6

### IncludeExcludeBasedFilter

7

8

Abstract base class providing common filtering patterns for servlet filters.

9

10

```java { .api }

11

/**

12

* Abstract base filter for include/exclude filtering based on paths, MIME types, and HTTP methods.

13

* Provides common functionality for filters that need to selectively process requests.

14

*/

15

public abstract class IncludeExcludeBasedFilter implements Filter {

16

/**

17

* Initialize the filter with include/exclude configuration parameters

18

* @param filterConfig Filter configuration containing include/exclude parameters

19

* @throws ServletException if configuration is invalid

20

*/

21

public void init(FilterConfig filterConfig) throws ServletException;

22

23

/**

24

* Clean up filter resources

25

*/

26

public void destroy();

27

28

/**

29

* Get string representation of the filter configuration

30

* @return String describing the include/exclude patterns

31

*/

32

public String toString();

33

34

/**

35

* Determine if the request should be filtered based on configured patterns

36

* @param httpRequest The HTTP request

37

* @param httpResponse The HTTP response

38

* @return true if the request should be processed by this filter

39

*/

40

protected boolean shouldFilter(HttpServletRequest httpRequest, HttpServletResponse httpResponse);

41

42

/**

43

* Guess the MIME type of the response for filtering decisions

44

* @param httpRequest The HTTP request

45

* @param httpResponse The HTTP response

46

* @return The guessed MIME type or null if cannot be determined

47

*/

48

protected String guessMimeType(HttpServletRequest httpRequest, HttpServletResponse httpResponse);

49

}

50

```

51

52

## Configuration Parameters

53

54

### Path Filtering

55

56

**includedPaths**: Comma-separated list of path specifications to include

57

**excludedPaths**: Comma-separated list of path specifications to exclude

58

59

Path specifications support three formats:

60

- **Regex patterns**: Start with `^` (e.g., `^/api/v\d+/.*`)

61

- **Servlet patterns**: Start with `/` for exact or prefix matching (e.g., `/admin/*`, `/api/users`)

62

- **Suffix patterns**: Start with `*.` for extension matching (e.g., `*.jsp`, `*.html`)

63

64

### MIME Type Filtering

65

66

**includedMimeTypes**: Comma-separated list of MIME types to include

67

**excludedMimeTypes**: Comma-separated list of MIME types to exclude

68

69

MIME type patterns support:

70

- **Exact matching**: `text/html`, `application/json`

71

- **Wildcard matching**: `text/*`, `image/*`, `application/*`

72

73

### HTTP Method Filtering

74

75

**includedHttpMethods**: Comma-separated list of HTTP methods to include

76

**excludedHttpMethods**: Comma-separated list of HTTP methods to exclude

77

78

Standard HTTP methods: `GET`, `POST`, `PUT`, `DELETE`, `HEAD`, `OPTIONS`, `PATCH`, `TRACE`

79

80

## Usage Examples

81

82

### Custom Security Filter

83

84

```java

85

import org.eclipse.jetty.ee10.servlets.IncludeExcludeBasedFilter;

86

import jakarta.servlet.*;

87

import jakarta.servlet.http.HttpServletRequest;

88

import jakarta.servlet.http.HttpServletResponse;

89

90

/**

91

* Custom security filter that adds security headers to specific paths

92

*/

93

public class SecurityHeaderFilter extends IncludeExcludeBasedFilter {

94

@Override

95

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

96

throws IOException, ServletException {

97

98

HttpServletRequest httpRequest = (HttpServletRequest) request;

99

HttpServletResponse httpResponse = (HttpServletResponse) response;

100

101

// Check if this request should be filtered

102

if (shouldFilter(httpRequest, httpResponse)) {

103

// Add security headers

104

httpResponse.setHeader("X-Frame-Options", "DENY");

105

httpResponse.setHeader("X-Content-Type-Options", "nosniff");

106

httpResponse.setHeader("X-XSS-Protection", "1; mode=block");

107

}

108

109

// Continue with the filter chain

110

chain.doFilter(request, response);

111

}

112

}

113

```

114

115

**Configuration**:

116

```xml

117

<filter>

118

<filter-name>SecurityHeaderFilter</filter-name>

119

<filter-class>com.example.SecurityHeaderFilter</filter-class>

120

<!-- Only apply to HTML pages -->

121

<init-param>

122

<param-name>includedMimeTypes</param-name>

123

<param-value>text/html</param-value>

124

</init-param>

125

<!-- Skip admin pages (they have their own security) -->

126

<init-param>

127

<param-name>excludedPaths</param-name>

128

<param-value>/admin/*</param-value>

129

</init-param>

130

</filter>

131

```

132

133

### Custom Logging Filter

134

135

```java

136

/**

137

* Logging filter that logs specific types of requests

138

*/

139

public class ApiLogFilter extends IncludeExcludeBasedFilter {

140

private static final Logger logger = LoggerFactory.getLogger(ApiLogFilter.class);

141

142

@Override

143

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

144

throws IOException, ServletException {

145

146

HttpServletRequest httpRequest = (HttpServletRequest) request;

147

HttpServletResponse httpResponse = (HttpServletResponse) response;

148

149

long startTime = System.currentTimeMillis();

150

151

try {

152

chain.doFilter(request, response);

153

} finally {

154

// Log if this request should be filtered

155

if (shouldFilter(httpRequest, httpResponse)) {

156

long duration = System.currentTimeMillis() - startTime;

157

logger.info("API Request: {} {} - Status: {} - Duration: {}ms",

158

httpRequest.getMethod(),

159

httpRequest.getRequestURI(),

160

httpResponse.getStatus(),

161

duration);

162

}

163

}

164

}

165

}

166

```

167

168

**Configuration**:

169

```xml

170

<filter>

171

<filter-name>ApiLogFilter</filter-name>

172

<filter-class>com.example.ApiLogFilter</filter-class>

173

<!-- Only log API endpoints -->

174

<init-param>

175

<param-name>includedPaths</param-name>

176

<param-value>/api/*</param-value>

177

</init-param>

178

<!-- Only log POST, PUT, DELETE (not GET) -->

179

<init-param>

180

<param-name>includedHttpMethods</param-name>

181

<param-value>POST,PUT,DELETE</param-value>

182

</init-param>

183

</filter>

184

```

185

186

### Custom Compression Filter

187

188

```java

189

/**

190

* Simple compression filter that compresses specific content types

191

*/

192

public class CompressionFilter extends IncludeExcludeBasedFilter {

193

@Override

194

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

195

throws IOException, ServletException {

196

197

HttpServletRequest httpRequest = (HttpServletRequest) request;

198

HttpServletResponse httpResponse = (HttpServletResponse) response;

199

200

// Check if client accepts gzip

201

String acceptEncoding = httpRequest.getHeader("Accept-Encoding");

202

boolean clientSupportsGzip = acceptEncoding != null &&

203

acceptEncoding.toLowerCase().contains("gzip");

204

205

if (clientSupportsGzip && shouldFilter(httpRequest, httpResponse)) {

206

// Wrap response with compression

207

GzipResponseWrapper wrappedResponse = new GzipResponseWrapper(httpResponse);

208

chain.doFilter(request, wrappedResponse);

209

wrappedResponse.finish();

210

} else {

211

chain.doFilter(request, response);

212

}

213

}

214

}

215

```

216

217

**Configuration**:

218

```xml

219

<filter>

220

<filter-name>CompressionFilter</filter-name>

221

<filter-class>com.example.CompressionFilter</filter-class>

222

<!-- Compress text content -->

223

<init-param>

224

<param-name>includedMimeTypes</param-name>

225

<param-value>text/html,text/css,text/javascript,application/json,application/xml</param-value>

226

</init-param>

227

<!-- Don't compress images -->

228

<init-param>

229

<param-name>excludedMimeTypes</param-name>

230

<param-value>image/*</param-value>

231

</init-param>

232

<!-- Only compress larger files -->

233

<init-param>

234

<param-name>excludedPaths</param-name>

235

<param-value>*.ico,/favicon.ico</param-value>

236

</init-param>

237

</filter>

238

```

239

240

### Custom Authentication Filter

241

242

```java

243

/**

244

* Authentication filter that checks tokens for specific endpoints

245

*/

246

public class TokenAuthFilter extends IncludeExcludeBasedFilter {

247

@Override

248

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

249

throws IOException, ServletException {

250

251

HttpServletRequest httpRequest = (HttpServletRequest) request;

252

HttpServletResponse httpResponse = (HttpServletResponse) response;

253

254

if (shouldFilter(httpRequest, httpResponse)) {

255

String authHeader = httpRequest.getHeader("Authorization");

256

257

if (authHeader == null || !authHeader.startsWith("Bearer ")) {

258

httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,

259

"Missing or invalid authorization header");

260

return;

261

}

262

263

String token = authHeader.substring(7);

264

if (!validateToken(token)) {

265

httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,

266

"Invalid token");

267

return;

268

}

269

}

270

271

chain.doFilter(request, response);

272

}

273

274

private boolean validateToken(String token) {

275

// Implementation-specific token validation

276

return TokenService.isValid(token);

277

}

278

}

279

```

280

281

**Configuration**:

282

```xml

283

<filter>

284

<filter-name>TokenAuthFilter</filter-name>

285

<filter-class>com.example.TokenAuthFilter</filter-class>

286

<!-- Only protect API endpoints -->

287

<init-param>

288

<param-name>includedPaths</param-name>

289

<param-value>/api/*</param-value>

290

</init-param>

291

<!-- Skip authentication endpoints -->

292

<init-param>

293

<param-name>excludedPaths</param-name>

294

<param-value>/api/auth/*,/api/public/*</param-value>

295

</init-param>

296

<!-- Only for operations that modify data -->

297

<init-param>

298

<param-name>includedHttpMethods</param-name>

299

<param-value>POST,PUT,DELETE,PATCH</param-value>

300

</init-param>

301

</filter>

302

```

303

304

## Path Specification Patterns

305

306

### Exact Match

307

```

308

/admin/users

309

```

310

Matches only the exact path `/admin/users`.

311

312

### Prefix Match

313

```

314

/api/*

315

```

316

Matches any path starting with `/api/` including:

317

- `/api/users`

318

- `/api/products/123`

319

- `/api/v1/search`

320

321

### Suffix Match

322

```

323

*.jsp

324

*.html

325

*.css

326

```

327

Matches any path ending with the specified extension.

328

329

### Regex Match

330

```

331

^/user/\d+$

332

^/api/v\d+/.*

333

```

334

Matches paths using regular expression patterns. Must start with `^`.

335

336

## MIME Type Patterns

337

338

### Exact MIME Type

339

```

340

text/html

341

application/json

342

application/pdf

343

```

344

345

### Wildcard MIME Type

346

```

347

text/* # All text types

348

image/* # All image types

349

application/* # All application types

350

```

351

352

### Multiple MIME Types

353

```

354

text/html,text/css,text/javascript

355

```

356

357

## Advanced Configuration Examples

358

359

### Complex Path Filtering

360

361

```xml

362

<filter>

363

<filter-name>ComplexPathFilter</filter-name>

364

<filter-class>com.example.MyFilter</filter-class>

365

<!-- Include API and admin paths -->

366

<init-param>

367

<param-name>includedPaths</param-name>

368

<param-value>/api/*,/admin/*</param-value>

369

</init-param>

370

<!-- Exclude specific admin and API paths -->

371

<init-param>

372

<param-name>excludedPaths</param-name>

373

<param-value>/admin/login,/api/health,/api/public/*</param-value>

374

</init-param>

375

</filter>

376

```

377

378

### Content-Type Based Filtering

379

380

```xml

381

<filter>

382

<filter-name>ContentTypeFilter</filter-name>

383

<filter-class>com.example.MyFilter</filter-class>

384

<!-- Include JSON and XML responses -->

385

<init-param>

386

<param-name>includedMimeTypes</param-name>

387

<param-value>application/json,application/xml,text/xml</param-value>

388

</init-param>

389

<!-- Exclude binary content -->

390

<init-param>

391

<param-name>excludedMimeTypes</param-name>

392

<param-value>image/*,video/*,application/octet-stream</param-value>

393

</init-param>

394

</filter>

395

```

396

397

### Method-Specific Filtering

398

399

```xml

400

<filter>

401

<filter-name>WriteOperationFilter</filter-name>

402

<filter-class>com.example.MyFilter</filter-class>

403

<!-- Only filter write operations -->

404

<init-param>

405

<param-name>includedHttpMethods</param-name>

406

<param-value>POST,PUT,DELETE,PATCH</param-value>

407

</init-param>

408

<!-- Skip OPTIONS (preflight) -->

409

<init-param>

410

<param-name>excludedHttpMethods</param-name>

411

<param-value>OPTIONS</param-value>

412

</init-param>

413

</filter>

414

```

415

416

### Combined Filtering Strategy

417

418

```xml

419

<filter>

420

<filter-name>CombinedFilter</filter-name>

421

<filter-class>com.example.MyFilter</filter-class>

422

<!-- Filter API endpoints -->

423

<init-param>

424

<param-name>includedPaths</param-name>

425

<param-value>/api/*</param-value>

426

</init-param>

427

<!-- Only JSON responses -->

428

<init-param>

429

<param-name>includedMimeTypes</param-name>

430

<param-value>application/json</param-value>

431

</init-param>

432

<!-- Only write operations -->

433

<init-param>

434

<param-name>includedHttpMethods</param-name>

435

<param-value>POST,PUT,DELETE</param-value>

436

</init-param>

437

<!-- Skip health checks -->

438

<init-param>

439

<param-name>excludedPaths</param-name>

440

<param-value>/api/health,/api/status</param-value>

441

</init-param>

442

</filter>

443

```

444

445

## Implementation Guidelines

446

447

### Filter Logic Pattern

448

```java

449

@Override

450

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

451

throws IOException, ServletException {

452

453

HttpServletRequest httpRequest = (HttpServletRequest) request;

454

HttpServletResponse httpResponse = (HttpServletResponse) response;

455

456

// Check if this request should be processed

457

if (shouldFilter(httpRequest, httpResponse)) {

458

// Apply your filter logic here

459

processRequest(httpRequest, httpResponse);

460

}

461

462

// Always continue the chain

463

chain.doFilter(request, response);

464

}

465

```

466

467

### MIME Type Detection

468

The base class provides MIME type detection through:

469

- Response content type (if already set)

470

- Request URI extension mapping

471

- Servlet context MIME type mapping

472

473

### Performance Considerations

474

- Path matching is cached for performance

475

- MIME type detection may require response buffering

476

- Use specific patterns rather than broad wildcards when possible

477

478

## Common Use Cases

479

480

### Content Processing

481

Apply transformations only to specific content types (HTML, JSON, XML).

482

483

### Security Filters

484

Add security headers or authentication checks to sensitive paths.

485

486

### Performance Monitoring

487

Log or monitor specific API endpoints or operations.

488

489

### Content Compression

490

Compress responses for text-based content types.

491

492

### Caching Headers

493

Add cache control headers to static resources or API responses.