or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdconnection-pooling.mdcontent-management.mdhttp-operations.mdindex.mdproxy-configuration.mdrequest-configuration.mdresponse-processing.md

proxy-configuration.mddocs/

0

# Proxy Configuration

1

2

The proxy configuration capability provides comprehensive proxy support including HTTP, SOCKS4, and SOCKS5 proxies with authentication, per-destination configuration, and automatic proxy selection based on target addresses.

3

4

## ProxyConfiguration Class

5

6

The central proxy configuration management system.

7

8

```java { .api }

9

public class ProxyConfiguration {

10

public ProxyConfiguration();

11

12

// Proxy management

13

public void addProxy(Proxy proxy);

14

public boolean removeProxy(Proxy proxy);

15

public List<Proxy> getProxies();

16

17

// Proxy selection

18

public Proxy match(Origin origin);

19

20

// Nested Proxy base class

21

public static abstract class Proxy {

22

public Proxy(Origin.Address address, boolean secure);

23

public Proxy(Origin.Address address, boolean secure, Set<String> includedAddresses, Set<String> excludedAddresses);

24

25

public Origin.Address getAddress();

26

public boolean isSecure();

27

public Set<String> getIncludedAddresses();

28

public Set<String> getExcludedAddresses();

29

public URI getURI();

30

31

public boolean matches(Origin origin);

32

33

// Factory methods

34

public static Proxy create(String host, int port);

35

public static Proxy create(String host, int port, boolean secure);

36

public static Proxy create(Origin.Address address, boolean secure);

37

}

38

}

39

```

40

41

## HTTP Proxy

42

43

Standard HTTP proxy configuration for HTTP and HTTPS connections.

44

45

### HttpProxy Class

46

47

```java { .api }

48

public class HttpProxy extends ProxyConfiguration.Proxy {

49

public HttpProxy(String host, int port);

50

public HttpProxy(Origin.Address address, boolean secure);

51

public HttpProxy(Origin.Address address, boolean secure, Set<String> includedAddresses, Set<String> excludedAddresses);

52

}

53

```

54

55

### Usage Examples

56

57

```java

58

// Basic HTTP proxy

59

HttpProxy httpProxy = new HttpProxy("proxy.company.com", 8080);

60

client.getProxyConfiguration().addProxy(httpProxy);

61

62

// HTTPS proxy (secure proxy connection)

63

HttpProxy httpsProxy = new HttpProxy("secure-proxy.company.com", 8443);

64

client.getProxyConfiguration().addProxy(httpsProxy);

65

66

// HTTP proxy with address restrictions

67

Set<String> includedHosts = Set.of("*.example.com", "api.partner.com");

68

Set<String> excludedHosts = Set.of("localhost", "127.0.0.1", "*.internal.com");

69

70

HttpProxy restrictedProxy = new HttpProxy(

71

new Origin.Address("proxy.company.com", 8080),

72

false, // not secure

73

includedHosts,

74

excludedHosts

75

);

76

77

client.getProxyConfiguration().addProxy(restrictedProxy);

78

79

// Make request through proxy

80

ContentResponse response = client.GET("https://external-api.example.com/data");

81

```

82

83

### HTTP Proxy with Authentication

84

85

```java

86

// Configure HTTP proxy

87

HttpProxy proxy = new HttpProxy("authenticated-proxy.company.com", 8080);

88

client.getProxyConfiguration().addProxy(proxy);

89

90

// Add proxy authentication

91

URI proxyUri = URI.create("http://authenticated-proxy.company.com:8080");

92

BasicAuthentication proxyAuth = new BasicAuthentication(proxyUri, "Proxy", "proxyuser", "proxypass");

93

client.getAuthenticationStore().addAuthentication(proxyAuth);

94

95

// Requests will automatically use proxy with authentication

96

ContentResponse response = client.GET("https://api.example.com/data");

97

```

98

99

## SOCKS Proxies

100

101

Support for SOCKS4 and SOCKS5 proxy protocols.

102

103

### Socks4Proxy Class

104

105

```java { .api }

106

public class Socks4Proxy extends ProxyConfiguration.Proxy {

107

public Socks4Proxy(String host, int port);

108

public Socks4Proxy(Origin.Address address, boolean secure);

109

}

110

```

111

112

### Socks5Proxy Class

113

114

```java { .api }

115

public class Socks5Proxy extends ProxyConfiguration.Proxy {

116

public Socks5Proxy(String host, int port);

117

public Socks5Proxy(Origin.Address address, boolean secure);

118

}

119

```

120

121

### Usage Examples

122

123

```java

124

// SOCKS4 proxy

125

Socks4Proxy socks4Proxy = new Socks4Proxy("socks4.proxy.com", 1080);

126

client.getProxyConfiguration().addProxy(socks4Proxy);

127

128

// SOCKS5 proxy

129

Socks5Proxy socks5Proxy = new Socks5Proxy("socks5.proxy.com", 1080);

130

client.getProxyConfiguration().addProxy(socks5Proxy);

131

132

// SOCKS5 proxy with authentication

133

Socks5Proxy authSocks5 = new Socks5Proxy("auth-socks5.proxy.com", 1080);

134

client.getProxyConfiguration().addProxy(authSocks5);

135

136

// Add SOCKS authentication (username/password)

137

URI socksUri = URI.create("socks5://auth-socks5.proxy.com:1080");

138

BasicAuthentication socksAuth = new BasicAuthentication(socksUri, null, "socksuser", "sockspass");

139

client.getAuthenticationStore().addAuthentication(socksAuth);

140

141

// Make request through SOCKS proxy

142

ContentResponse response = client.GET("https://restricted.example.com/data");

143

```

144

145

## Multiple Proxy Configuration

146

147

Configure multiple proxies with automatic selection based on target addresses.

148

149

### Proxy Selection Logic

150

151

```java

152

ProxyConfiguration proxyConfig = client.getProxyConfiguration();

153

154

// Corporate HTTP proxy for internal services

155

Set<String> internalHosts = Set.of("*.company.com", "*.internal.net");

156

HttpProxy corporateProxy = new HttpProxy(

157

new Origin.Address("internal-proxy.company.com", 8080),

158

false,

159

internalHosts,

160

Collections.emptySet()

161

);

162

proxyConfig.addProxy(corporateProxy);

163

164

// SOCKS proxy for external services

165

Set<String> externalHosts = Set.of("*");

166

Set<String> excludeInternal = Set.of("*.company.com", "*.internal.net", "localhost", "127.0.0.1");

167

Socks5Proxy externalProxy = new Socks5Proxy(

168

new Origin.Address("external-socks.company.com", 1080),

169

false

170

);

171

// Configure exclusions for external proxy

172

HttpProxy externalHttpProxy = new HttpProxy(

173

new Origin.Address("external-socks.company.com", 1080),

174

false,

175

externalHosts,

176

excludeInternal

177

);

178

proxyConfig.addProxy(externalHttpProxy);

179

180

// Direct connection for local services

181

Set<String> directHosts = Set.of("localhost", "127.0.0.1", "*.local");

182

// No proxy needed - requests to these hosts will bypass proxy

183

```

184

185

### Conditional Proxy Usage

186

187

```java

188

public class ConditionalProxyClient {

189

private final HttpClient client;

190

private final ProxyConfiguration originalProxyConfig;

191

192

public ConditionalProxyClient() throws Exception {

193

this.client = new HttpClient();

194

this.originalProxyConfig = client.getProxyConfiguration();

195

client.start();

196

}

197

198

public ContentResponse requestWithProxy(String url, ProxyConfiguration.Proxy proxy) throws Exception {

199

ProxyConfiguration tempConfig = new ProxyConfiguration();

200

tempConfig.addProxy(proxy);

201

202

// Temporarily use specific proxy

203

ProxyConfiguration originalConfig = client.getProxyConfiguration();

204

205

try {

206

// Note: In actual usage, you'd need to create a new client with the proxy

207

// as proxy configuration is typically set at client creation time

208

return client.GET(url);

209

} finally {

210

// Restore original configuration

211

}

212

}

213

214

public ContentResponse requestDirect(String url) throws Exception {

215

// Remove all proxies for direct connection

216

ProxyConfiguration noProxyConfig = new ProxyConfiguration();

217

218

// Create temporary client without proxy

219

HttpClient directClient = new HttpClient();

220

directClient.start();

221

222

try {

223

return directClient.GET(url);

224

} finally {

225

directClient.stop();

226

}

227

}

228

}

229

```

230

231

## Proxy Authentication

232

233

Configure authentication for proxy servers.

234

235

### Basic Proxy Authentication

236

237

```java

238

// HTTP proxy with basic authentication

239

HttpProxy proxy = new HttpProxy("auth-proxy.company.com", 8080);

240

client.getProxyConfiguration().addProxy(proxy);

241

242

// Add proxy authentication

243

URI proxyUri = URI.create("http://auth-proxy.company.com:8080");

244

BasicAuthentication proxyAuth = new BasicAuthentication(

245

proxyUri,

246

"Corporate Proxy",

247

"domain\\username",

248

"password"

249

);

250

client.getAuthenticationStore().addAuthentication(proxyAuth);

251

```

252

253

### NTLM Proxy Authentication

254

255

```java

256

// For NTLM authentication, you may need custom authentication implementation

257

public class NTLMProxyAuthentication implements Authentication {

258

private final URI proxyUri;

259

private final String domain;

260

private final String username;

261

private final String password;

262

263

public NTLMProxyAuthentication(URI proxyUri, String domain, String username, String password) {

264

this.proxyUri = proxyUri;

265

this.domain = domain;

266

this.username = username;

267

this.password = password;

268

}

269

270

@Override

271

public String getType() {

272

return "NTLM";

273

}

274

275

@Override

276

public boolean matches(String type, URI uri, String realm) {

277

return "NTLM".equalsIgnoreCase(type) && proxyUri.equals(uri);

278

}

279

280

@Override

281

public AuthenticationResult authenticate(Request request, ContentResponse response,

282

HeaderInfo headerInfo, Context context) {

283

// Implement NTLM authentication logic

284

// This typically involves multiple challenge/response exchanges

285

String ntlmMessage = createNTLMResponse(headerInfo.getParameters());

286

return AuthenticationResult.from(context.getURI(), context.getRealm(), "Proxy-Authorization", ntlmMessage);

287

}

288

289

private String createNTLMResponse(Map<String, String> challenge) {

290

// Implement NTLM message creation

291

// This would typically use a library like JCIFS

292

return "NTLM " + base64EncodedNTLMMessage;

293

}

294

}

295

```

296

297

## Advanced Proxy Configuration

298

299

### Dynamic Proxy Selection

300

301

```java

302

public class DynamicProxySelector {

303

private final List<ProxyConfiguration.Proxy> proxies;

304

private final Map<String, ProxyConfiguration.Proxy> domainProxies;

305

306

public DynamicProxySelector() {

307

this.proxies = new ArrayList<>();

308

this.domainProxies = new HashMap<>();

309

310

// Configure domain-specific proxies

311

domainProxies.put("api.partner1.com", new HttpProxy("partner1-proxy.com", 8080));

312

domainProxies.put("api.partner2.com", new Socks5Proxy("partner2-socks.com", 1080));

313

314

// Default corporate proxy

315

proxies.add(new HttpProxy("corporate-proxy.company.com", 8080));

316

}

317

318

public ProxyConfiguration.Proxy selectProxy(URI uri) {

319

String host = uri.getHost();

320

321

// Check for domain-specific proxy

322

ProxyConfiguration.Proxy domainProxy = domainProxies.get(host);

323

if (domainProxy != null) {

324

return domainProxy;

325

}

326

327

// Check for wildcard domain matches

328

for (Map.Entry<String, ProxyConfiguration.Proxy> entry : domainProxies.entrySet()) {

329

if (host.endsWith(entry.getKey().substring(1))) { // Remove * from *.domain.com

330

return entry.getValue();

331

}

332

}

333

334

// Return default proxy

335

return proxies.get(0);

336

}

337

}

338

```

339

340

### Proxy Health Checking

341

342

```java

343

public class ProxyHealthChecker {

344

private final HttpClient testClient;

345

private final Map<ProxyConfiguration.Proxy, Boolean> proxyHealth;

346

347

public ProxyHealthChecker() throws Exception {

348

this.testClient = new HttpClient();

349

this.testClient.setConnectTimeout(5000);

350

this.testClient.setIdleTimeout(10000);

351

this.testClient.start();

352

this.proxyHealth = new ConcurrentHashMap<>();

353

}

354

355

public boolean isProxyHealthy(ProxyConfiguration.Proxy proxy) {

356

return proxyHealth.computeIfAbsent(proxy, this::checkProxyHealth);

357

}

358

359

private boolean checkProxyHealth(ProxyConfiguration.Proxy proxy) {

360

try {

361

// Create temporary client with this proxy

362

HttpClient proxyTestClient = new HttpClient();

363

ProxyConfiguration testProxyConfig = new ProxyConfiguration();

364

testProxyConfig.addProxy(proxy);

365

// Set proxy configuration on test client

366

367

proxyTestClient.start();

368

369

try {

370

// Test proxy with a simple request

371

ContentResponse response = proxyTestClient.GET("http://httpbin.org/ip");

372

return response.getStatus() == 200;

373

} finally {

374

proxyTestClient.stop();

375

}

376

} catch (Exception e) {

377

return false;

378

}

379

}

380

381

public void scheduleHealthChecks(ScheduledExecutorService scheduler) {

382

scheduler.scheduleAtFixedRate(() -> {

383

proxyHealth.keySet().forEach(proxy -> {

384

boolean healthy = checkProxyHealth(proxy);

385

proxyHealth.put(proxy, healthy);

386

if (!healthy) {

387

System.err.println("Proxy unhealthy: " + proxy.getAddress());

388

}

389

});

390

}, 0, 60, TimeUnit.SECONDS);

391

}

392

}

393

```

394

395

## Proxy Bypass and Direct Connections

396

397

Configure proxy bypass for specific destinations.

398

399

### No Proxy Configuration

400

401

```java

402

// Configure proxy but exclude certain hosts

403

Set<String> noProxyHosts = Set.of(

404

"localhost",

405

"127.0.0.1",

406

"*.local",

407

"*.company.com",

408

"internal-api.example.com"

409

);

410

411

HttpProxy proxy = new HttpProxy(

412

new Origin.Address("proxy.company.com", 8080),

413

false,

414

Collections.singleton("*"), // Include all hosts by default

415

noProxyHosts // Exclude these hosts from proxy

416

);

417

418

client.getProxyConfiguration().addProxy(proxy);

419

420

// Requests to excluded hosts will bypass proxy

421

ContentResponse directResponse = client.GET("https://internal-api.company.com/data");

422

ContentResponse proxiedResponse = client.GET("https://external-api.example.com/data");

423

```

424

425

### Environment-Based Proxy Configuration

426

427

```java

428

public class EnvironmentProxyConfig {

429

public static void configureFromEnvironment(HttpClient client) {

430

// Read proxy configuration from environment variables

431

String httpProxy = System.getenv("HTTP_PROXY");

432

String httpsProxy = System.getenv("HTTPS_PROXY");

433

String noProxy = System.getenv("NO_PROXY");

434

435

ProxyConfiguration proxyConfig = client.getProxyConfiguration();

436

437

if (httpProxy != null) {

438

URI proxyUri = URI.create(httpProxy);

439

HttpProxy proxy = new HttpProxy(proxyUri.getHost(), proxyUri.getPort());

440

441

// Configure no-proxy hosts if specified

442

if (noProxy != null) {

443

Set<String> noProxyHosts = Set.of(noProxy.split(","));

444

proxy = new HttpProxy(

445

new Origin.Address(proxyUri.getHost(), proxyUri.getPort()),

446

false,

447

Collections.singleton("*"),

448

noProxyHosts

449

);

450

}

451

452

proxyConfig.addProxy(proxy);

453

454

// Configure proxy authentication if present in URI

455

String userInfo = proxyUri.getUserInfo();

456

if (userInfo != null) {

457

String[] credentials = userInfo.split(":");

458

if (credentials.length == 2) {

459

BasicAuthentication proxyAuth = new BasicAuthentication(

460

proxyUri,

461

null,

462

credentials[0],

463

credentials[1]

464

);

465

client.getAuthenticationStore().addAuthentication(proxyAuth);

466

}

467

}

468

}

469

}

470

}

471

472

// Usage

473

EnvironmentProxyConfig.configureFromEnvironment(client);

474

```

475

476

## Troubleshooting Proxy Issues

477

478

### Proxy Connection Debugging

479

480

```java

481

public class ProxyDebugger {

482

public static void debugProxyConnection(HttpClient client, String testUrl) {

483

ProxyConfiguration proxyConfig = client.getProxyConfiguration();

484

485

System.out.println("Configured proxies:");

486

for (ProxyConfiguration.Proxy proxy : proxyConfig.getProxies()) {

487

System.out.println(" " + proxy.getClass().getSimpleName() +

488

" - " + proxy.getAddress() +

489

" (secure: " + proxy.isSecure() + ")");

490

System.out.println(" Included: " + proxy.getIncludedAddresses());

491

System.out.println(" Excluded: " + proxy.getExcludedAddresses());

492

}

493

494

// Test proxy selection for target URL

495

try {

496

URI uri = URI.create(testUrl);

497

Origin origin = new Origin("https", uri.getHost(), uri.getPort());

498

ProxyConfiguration.Proxy selectedProxy = proxyConfig.match(origin);

499

500

if (selectedProxy != null) {

501

System.out.println("Selected proxy for " + testUrl + ": " + selectedProxy.getAddress());

502

} else {

503

System.out.println("No proxy selected for " + testUrl + " (direct connection)");

504

}

505

} catch (Exception e) {

506

System.err.println("Error testing proxy selection: " + e.getMessage());

507

}

508

}

509

}

510

```

511

512

### Proxy Error Handling

513

514

```java

515

client.newRequest("https://api.example.com/data")

516

.send(result -> {

517

if (result.isFailed()) {

518

Throwable failure = result.getFailure();

519

520

if (failure instanceof ConnectException) {

521

System.err.println("Failed to connect to proxy server");

522

} else if (failure instanceof HttpRequestException) {

523

HttpRequestException httpEx = (HttpRequestException) failure;

524

System.err.println("Proxy request failed: " + httpEx.getMessage());

525

} else if (failure.getMessage().contains("407")) {

526

System.err.println("Proxy authentication required");

527

} else {

528

System.err.println("Proxy-related error: " + failure.getMessage());

529

}

530

}

531

});

532

```