or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdconnection-management.mdcontext-resources.mdhandlers.mdindex.mdrequest-logging.mdrequest-response.mdsecurity-ssl.mdserver-core.mdsession-management.mdutility-handlers.md

utility-handlers.mddocs/

0

# Utility Handlers

1

2

Utility handlers provide specialized functionality for common web server needs including GZIP compression, CORS support, statistics collection, error handling, and request processing utilities.

3

4

## GZIP Compression

5

6

### GzipHandler

7

8

Compresses response content using GZIP encoding to reduce bandwidth usage.

9

10

```java { .api }

11

public class GzipHandler extends Handler.Wrapper implements GzipFactory {

12

// Constructors

13

public GzipHandler();

14

15

// Compression configuration

16

public int getMinGzipSize();

17

public void setMinGzipSize(int minGzipSize);

18

public int getCompressionLevel();

19

public void setCompressionLevel(int compressionLevel);

20

21

// Content type filtering

22

public Set<String> getIncludedMimeTypes();

23

public void setIncludedMimeTypes(String... types);

24

public Set<String> getExcludedMimeTypes();

25

public void setExcludedMimeTypes(String... types);

26

public Set<String> getIncludedMethods();

27

public void setIncludedMethods(String... methods);

28

public Set<String> getExcludedMethods();

29

public void setExcludedMethods(String... methods);

30

31

// Path filtering

32

public PathMappings<Boolean> getIncludedPaths();

33

public void addIncludedPaths(String... pathspecs);

34

public PathMappings<Boolean> getExcludedPaths();

35

public void addExcludedPaths(String... pathspecs);

36

37

// User agent filtering

38

public Set<String> getIncludedAgentPatterns();

39

public void setIncludedAgentPatterns(String... patterns);

40

public Set<String> getExcludedAgentPatterns();

41

public void setExcludedAgentPatterns(String... patterns);

42

43

// Deflater configuration

44

public boolean isCheckGzExists();

45

public void setCheckGzExists(boolean checkGzExists);

46

public boolean isSyncFlush();

47

public void setSyncFlush(boolean syncFlush);

48

public int getInflateBufferSize();

49

public void setInflateBufferSize(int size);

50

}

51

```

52

53

### Basic GZIP Configuration

54

55

```java

56

public class GzipConfiguration {

57

58

public void setupGzipHandler(Server server) {

59

// Create GZIP handler

60

GzipHandler gzipHandler = new GzipHandler();

61

62

// Configure minimum size for compression (1KB)

63

gzipHandler.setMinGzipSize(1024);

64

65

// Set compression level (6 = default, good balance of speed/compression)

66

gzipHandler.setCompressionLevel(6);

67

68

// Include text-based content types

69

gzipHandler.setIncludedMimeTypes(

70

"text/html",

71

"text/plain",

72

"text/xml",

73

"text/css",

74

"application/javascript",

75

"application/json",

76

"application/xml"

77

);

78

79

// Exclude already compressed content

80

gzipHandler.setExcludedMimeTypes(

81

"image/jpeg",

82

"image/png",

83

"image/gif",

84

"application/zip",

85

"application/gzip"

86

);

87

88

// Only compress GET and POST requests

89

gzipHandler.setIncludedMethods("GET", "POST");

90

91

// Exclude paths that shouldn't be compressed

92

gzipHandler.addExcludedPaths("/api/binary/*", "/downloads/*");

93

94

// Set application handler as child

95

gzipHandler.setHandler(new ApplicationHandler());

96

97

server.setHandler(gzipHandler);

98

}

99

}

100

```

101

102

## CORS Support

103

104

### CrossOriginHandler

105

106

Handles Cross-Origin Resource Sharing (CORS) for browser security.

107

108

```java { .api }

109

public class CrossOriginHandler extends Handler.Wrapper {

110

// Origin configuration

111

public Set<String> getAllowedOriginPatterns();

112

public void setAllowedOriginPatterns(Set<String> allowedOriginPatterns);

113

public void addAllowedOrigin(String origin);

114

115

// Method configuration

116

public Set<String> getAllowedMethods();

117

public void setAllowedMethods(Set<String> allowedMethods);

118

public void addAllowedMethod(String method);

119

120

// Header configuration

121

public Set<String> getAllowedHeaders();

122

public void setAllowedHeaders(Set<String> allowedHeaders);

123

public void addAllowedHeader(String header);

124

public Set<String> getExposedHeaders();

125

public void setExposedHeaders(Set<String> exposedHeaders);

126

public void addExposedHeader(String header);

127

128

// Preflight configuration

129

public boolean isAllowCredentials();

130

public void setAllowCredentials(boolean allowCredentials);

131

public int getPreflightMaxAge();

132

public void setPreflightMaxAge(int preflightMaxAge);

133

134

// Chain configuration

135

public boolean isChainPreflight();

136

public void setChainPreflight(boolean chainPreflight);

137

}

138

```

139

140

### CORS Configuration Example

141

142

```java

143

public class CORSConfiguration {

144

145

public void setupCORSHandler(Server server) {

146

CrossOriginHandler corsHandler = new CrossOriginHandler();

147

148

// Allow specific origins

149

corsHandler.setAllowedOriginPatterns(Set.of(

150

"https://example.com",

151

"https://*.example.com",

152

"http://localhost:*"

153

));

154

155

// Allow specific HTTP methods

156

corsHandler.setAllowedMethods(Set.of(

157

"GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD"

158

));

159

160

// Allow specific headers

161

corsHandler.setAllowedHeaders(Set.of(

162

"Content-Type",

163

"Authorization",

164

"X-Requested-With",

165

"Accept",

166

"Origin"

167

));

168

169

// Expose custom headers to client

170

corsHandler.setExposedHeaders(Set.of(

171

"X-Total-Count",

172

"X-Page-Count"

173

));

174

175

// Allow credentials (cookies, authorization headers)

176

corsHandler.setAllowCredentials(true);

177

178

// Cache preflight requests for 1 hour

179

corsHandler.setPreflightMaxAge(3600);

180

181

corsHandler.setHandler(new ApiHandler());

182

server.setHandler(corsHandler);

183

}

184

185

public void setupDevelopmentCORS(Server server) {

186

// Permissive CORS for development

187

CrossOriginHandler corsHandler = new CrossOriginHandler();

188

189

corsHandler.setAllowedOriginPatterns(Set.of("*"));

190

corsHandler.setAllowedMethods(Set.of("*"));

191

corsHandler.setAllowedHeaders(Set.of("*"));

192

corsHandler.setAllowCredentials(false); // Can't use * origins with credentials

193

194

corsHandler.setHandler(new DevelopmentHandler());

195

server.setHandler(corsHandler);

196

}

197

}

198

```

199

200

## Statistics Collection

201

202

### StatisticsHandler

203

204

Collects comprehensive request and response statistics.

205

206

```java { .api }

207

public class StatisticsHandler extends EventsHandler {

208

// Request statistics

209

public int getRequests();

210

public int getRequestsActive();

211

public int getRequestsActiveMax();

212

213

// Timing statistics

214

public long getStatsOnMs();

215

public long getRequestTimeTotal();

216

public long getRequestTimeMax();

217

public long getRequestTimeMean();

218

public long getRequestTimeStdDev();

219

220

// Response statistics by status

221

public int getResponses1xx();

222

public int getResponses2xx();

223

public int getResponses3xx();

224

public int getResponses4xx();

225

public int getResponses5xx();

226

227

// Byte statistics

228

public long getBytesReceived();

229

public long getBytesSent();

230

231

// Error statistics

232

public int getErrors();

233

public int getTimeouts();

234

235

// Async statistics

236

public int getAsyncRequests();

237

public int getAsyncRequestsWaiting();

238

public int getAsyncRequestsWaitingMax();

239

240

// Connection statistics

241

public int getConnections();

242

public int getConnectionsOpen();

243

public int getConnectionsOpenMax();

244

public Duration getConnectionsOpenMax();

245

246

// Statistics control

247

public void statsReset();

248

public String toStatsHTML();

249

}

250

```

251

252

### Statistics Usage Example

253

254

```java

255

public class StatisticsConfiguration {

256

257

public void setupStatisticsHandler(Server server) {

258

StatisticsHandler statsHandler = new StatisticsHandler();

259

260

// Set up statistics collection

261

statsHandler.setHandler(new ApplicationHandler());

262

263

// Add statistics reporting endpoint

264

Handler.Sequence rootHandler = new Handler.Sequence();

265

rootHandler.addHandler(new StatsReportingHandler(statsHandler));

266

rootHandler.addHandler(statsHandler);

267

268

server.setHandler(rootHandler);

269

270

// Start periodic statistics logging

271

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

272

scheduler.scheduleAtFixedRate(() -> {

273

logStatistics(statsHandler);

274

}, 60, 60, TimeUnit.SECONDS);

275

}

276

277

private void logStatistics(StatisticsHandler stats) {

278

System.out.println("=== Server Statistics ===");

279

System.out.println("Active Requests: " + stats.getRequestsActive());

280

System.out.println("Total Requests: " + stats.getRequests());

281

System.out.println("2xx Responses: " + stats.getResponses2xx());

282

System.out.println("4xx Responses: " + stats.getResponses4xx());

283

System.out.println("5xx Responses: " + stats.getResponses5xx());

284

System.out.println("Bytes Sent: " + stats.getBytesSent());

285

System.out.println("Mean Response Time: " + stats.getRequestTimeMean() + "ms");

286

System.out.println("Errors: " + stats.getErrors());

287

}

288

}

289

290

// Handler to expose statistics via HTTP

291

public class StatsReportingHandler extends Handler.Abstract {

292

private final StatisticsHandler statisticsHandler;

293

294

public StatsReportingHandler(StatisticsHandler statisticsHandler) {

295

this.statisticsHandler = statisticsHandler;

296

}

297

298

@Override

299

public boolean handle(Request request, Response response, Callback callback)

300

throws Exception {

301

302

if ("/stats".equals(request.getHttpURI().getPath())) {

303

response.setStatus(200);

304

response.getHeaders().put("Content-Type", "application/json");

305

306

String statsJson = createStatsJson(statisticsHandler);

307

response.write(true, ByteBuffer.wrap(statsJson.getBytes()), callback);

308

return true;

309

}

310

311

return false; // Not handled

312

}

313

314

private String createStatsJson(StatisticsHandler stats) {

315

Map<String, Object> statsMap = new HashMap<>();

316

statsMap.put("requests", stats.getRequests());

317

statsMap.put("requestsActive", stats.getRequestsActive());

318

statsMap.put("responses2xx", stats.getResponses2xx());

319

statsMap.put("responses4xx", stats.getResponses4xx());

320

statsMap.put("responses5xx", stats.getResponses5xx());

321

statsMap.put("bytesSent", stats.getBytesSent());

322

statsMap.put("bytesReceived", stats.getBytesReceived());

323

statsMap.put("meanResponseTime", stats.getRequestTimeMean());

324

statsMap.put("maxResponseTime", stats.getRequestTimeMax());

325

statsMap.put("errors", stats.getErrors());

326

statsMap.put("uptime", stats.getStatsOnMs());

327

328

// Convert to JSON (simplified)

329

return toJson(statsMap);

330

}

331

}

332

```

333

334

## Quality of Service (QoS)

335

336

### QoSHandler

337

338

Implements quality of service controls with request limiting and prioritization.

339

340

```java { .api }

341

public class QoSHandler extends ConditionalHandler.Abstract {

342

// Request limiting

343

public int getMaxRequests();

344

public void setMaxRequests(int maxRequests);

345

346

// Suspend configuration

347

public long getMaxSuspend();

348

public void setMaxSuspend(long maxSuspend);

349

350

// Current state

351

public int getRequests();

352

public int getSuspended();

353

354

// Priority configuration

355

public int getPriority(Request request);

356

public void setPriority(Request request, int priority);

357

}

358

```

359

360

### ThreadLimitHandler

361

362

Limits the number of threads processing requests.

363

364

```java { .api }

365

public class ThreadLimitHandler extends ConditionalHandler.Abstract {

366

// Thread limiting

367

public int getThreadLimit();

368

public void setThreadLimit(int threadLimit);

369

370

// Current state

371

public int getThreads();

372

public boolean isForwardedIdleTimeout();

373

public void setForwardedIdleTimeout(boolean forwardedIdleTimeout);

374

}

375

```

376

377

### QoS Configuration Example

378

379

```java

380

public class QoSConfiguration {

381

382

public void setupQoSHandlers(Server server) {

383

// Thread limiting handler

384

ThreadLimitHandler threadLimit = new ThreadLimitHandler();

385

threadLimit.setThreadLimit(50); // Max 50 concurrent processing threads

386

387

// Request limiting handler

388

QoSHandler qosHandler = new QoSHandler() {

389

@Override

390

protected boolean shouldHandle(Request request) {

391

// Apply QoS only to API requests

392

return request.getHttpURI().getPath().startsWith("/api/");

393

}

394

};

395

qosHandler.setMaxRequests(100); // Max 100 concurrent API requests

396

qosHandler.setMaxSuspend(30000); // Wait up to 30 seconds

397

398

// Chain handlers

399

threadLimit.setHandler(qosHandler);

400

qosHandler.setHandler(new ApplicationHandler());

401

402

server.setHandler(threadLimit);

403

}

404

405

public void setupPriorityQoS(Server server) {

406

QoSHandler priorityQoS = new QoSHandler() {

407

@Override

408

public int getPriority(Request request) {

409

// Prioritize authenticated users

410

if (request.getHeaders().get("Authorization") != null) {

411

return 0; // High priority

412

}

413

414

// Lower priority for anonymous users

415

return 1;

416

}

417

};

418

419

priorityQoS.setMaxRequests(50);

420

priorityQoS.setHandler(new ApplicationHandler());

421

server.setHandler(priorityQoS);

422

}

423

}

424

```

425

426

## Error Handling

427

428

### ErrorHandler

429

430

Generates error pages for HTTP error responses.

431

432

```java { .api }

433

public class ErrorHandler implements Request.Handler {

434

// Error page generation

435

public void handle(Request request, Response response, Callback callback) throws Exception;

436

public String getErrorPage(Request request, int code, String message);

437

public void writeErrorPage(Request request, Response response, Callback callback,

438

int code, String message, boolean showStacks);

439

440

// Configuration

441

public boolean isShowStacks();

442

public void setShowStacks(boolean showStacks);

443

public boolean isShowMessageInTitle();

444

public void setShowMessageInTitle(boolean showMessageInTitle);

445

446

// Caching

447

public String getCacheControl();

448

public void setCacheControl(String cacheControl);

449

}

450

```

451

452

### Custom Error Handler

453

454

```java

455

public class CustomErrorHandler extends ErrorHandler {

456

457

@Override

458

public void writeErrorPage(Request request, Response response, Callback callback,

459

int code, String message, boolean showStacks) {

460

461

response.getHeaders().put("Content-Type", "text/html; charset=utf-8");

462

463

String errorPage = generateCustomErrorPage(code, message, request);

464

response.write(true, ByteBuffer.wrap(errorPage.getBytes()), callback);

465

}

466

467

private String generateCustomErrorPage(int code, String message, Request request) {

468

StringBuilder html = new StringBuilder();

469

html.append("<!DOCTYPE html>\n");

470

html.append("<html>\n<head>\n");

471

html.append("<title>Error ").append(code).append("</title>\n");

472

html.append("<style>\n");

473

html.append("body { font-family: Arial, sans-serif; margin: 40px; }\n");

474

html.append(".error-container { max-width: 600px; margin: 0 auto; }\n");

475

html.append(".error-code { font-size: 72px; color: #dc3545; margin: 0; }\n");

476

html.append(".error-message { font-size: 24px; color: #6c757d; margin: 10px 0; }\n");

477

html.append("</style>\n");

478

html.append("</head>\n<body>\n");

479

html.append("<div class='error-container'>\n");

480

html.append("<h1 class='error-code'>").append(code).append("</h1>\n");

481

html.append("<p class='error-message'>").append(escapeHtml(message)).append("</p>\n");

482

483

if (code == 404) {

484

html.append("<p>The requested resource was not found on this server.</p>\n");

485

} else if (code >= 500) {

486

html.append("<p>An internal server error occurred. Please try again later.</p>\n");

487

}

488

489

html.append("<hr>\n");

490

html.append("<p><small>Request ID: ").append(request.getId()).append("</small></p>\n");

491

html.append("</div>\n</body>\n</html>");

492

493

return html.toString();

494

}

495

496

private String escapeHtml(String text) {

497

return text.replace("&", "&amp;")

498

.replace("<", "&lt;")

499

.replace(">", "&gt;")

500

.replace("\"", "&quot;")

501

.replace("'", "&#39;");

502

}

503

}

504

```

505

506

## Size Limiting

507

508

### SizeLimitHandler

509

510

Limits request and response sizes to prevent resource exhaustion.

511

512

```java { .api }

513

public class SizeLimitHandler extends Handler.Wrapper {

514

// Request size limiting

515

public long getRequestLimit();

516

public void setRequestLimit(long requestLimit);

517

518

// Response size limiting

519

public long getResponseLimit();

520

public void setResponseLimit(long responseLimit);

521

522

// Limit exceeded behavior

523

public String getLimitExceededMessage();

524

public void setLimitExceededMessage(String limitExceededMessage);

525

}

526

```

527

528

### Usage Example

529

530

```java

531

public class SizeLimitConfiguration {

532

533

public void setupSizeLimits(Server server) {

534

SizeLimitHandler sizeLimitHandler = new SizeLimitHandler();

535

536

// Limit request size to 10MB

537

sizeLimitHandler.setRequestLimit(10 * 1024 * 1024);

538

539

// Limit response size to 50MB

540

sizeLimitHandler.setResponseLimit(50 * 1024 * 1024);

541

542

// Custom error message

543

sizeLimitHandler.setLimitExceededMessage("Content size limit exceeded");

544

545

sizeLimitHandler.setHandler(new ApplicationHandler());

546

server.setHandler(sizeLimitHandler);

547

}

548

}

549

```

550

551

## Timeout Handling

552

553

### IdleTimeoutHandler

554

555

Sets idle timeout for individual requests.

556

557

```java { .api }

558

public class IdleTimeoutHandler extends Handler.Wrapper {

559

// Timeout configuration

560

public long getIdleTimeout();

561

public void setIdleTimeout(long idleTimeout);

562

563

// Apply timeout conditions

564

public boolean apply(String pathInContext, Request request, Response response);

565

}

566

```

567

568

### DelayedHandler

569

570

Adds artificial delay to request processing for testing or rate limiting.

571

572

```java { .api }

573

public class DelayedHandler extends Handler.Wrapper {

574

// Delay configuration

575

public long getDelayMs();

576

public void setDelayMs(long delayMs);

577

}

578

```

579

580

## Complete Utility Handler Chain

581

582

```java

583

public class UtilityHandlerChain {

584

585

public Handler createUtilityChain() {

586

// Statistics collection (outermost)

587

StatisticsHandler statsHandler = new StatisticsHandler();

588

589

// GZIP compression

590

GzipHandler gzipHandler = new GzipHandler();

591

gzipHandler.setMinGzipSize(1024);

592

gzipHandler.setIncludedMimeTypes("text/html", "text/css", "application/javascript", "application/json");

593

594

// CORS support

595

CrossOriginHandler corsHandler = new CrossOriginHandler();

596

corsHandler.setAllowedOriginPatterns(Set.of("https://*.example.com"));

597

corsHandler.setAllowedMethods(Set.of("GET", "POST", "PUT", "DELETE"));

598

599

// Size limiting

600

SizeLimitHandler sizeLimitHandler = new SizeLimitHandler();

601

sizeLimitHandler.setRequestLimit(10 * 1024 * 1024); // 10MB

602

603

// QoS limiting

604

QoSHandler qosHandler = new QoSHandler();

605

qosHandler.setMaxRequests(200);

606

607

// Application handler

608

Handler applicationHandler = new ApplicationHandler();

609

610

// Chain them together

611

statsHandler.setHandler(gzipHandler);

612

gzipHandler.setHandler(corsHandler);

613

corsHandler.setHandler(sizeLimitHandler);

614

sizeLimitHandler.setHandler(qosHandler);

615

qosHandler.setHandler(applicationHandler);

616

617

return statsHandler;

618

}

619

}

620

```