or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

caching.mdcookies.mdforms-multipart.mdhttp-client.mdindex.mdinterceptors.mdnetworking.mdrequests-responses.mdsecurity.mdurls.mdwebsockets.md

interceptors.mddocs/

0

# Interceptors

1

2

Pluggable request and response transformation framework for monitoring, rewriting, and retry logic.

3

4

## Interceptor Interface

5

6

```kotlin { .api }

7

interface Interceptor {

8

fun intercept(chain: Chain): Response

9

10

interface Chain {

11

fun request(): Request

12

fun proceed(request: Request): Response

13

fun connection(): Connection?

14

fun call(): Call

15

fun connectTimeoutMillis(): Int

16

fun withConnectTimeout(timeout: Int, unit: TimeUnit): Chain

17

fun readTimeoutMillis(): Int

18

fun withReadTimeout(timeout: Int, unit: TimeUnit): Chain

19

fun writeTimeoutMillis(): Int

20

fun withWriteTimeout(timeout: Int, unit: TimeUnit): Chain

21

}

22

}

23

```

24

25

## Application vs Network Interceptors

26

27

- **Application Interceptors**: Called once per request, see final redirected response

28

- **Network Interceptors**: Called for each network request, including redirects and retries

29

30

```kotlin

31

val client = OkHttpClient.Builder()

32

.addInterceptor(applicationInterceptor) // Application-level

33

.addNetworkInterceptor(networkInterceptor) // Network-level

34

.build()

35

```

36

37

## Common Interceptor Patterns

38

39

### Logging Interceptor

40

41

```kotlin

42

class LoggingInterceptor : Interceptor {

43

override fun intercept(chain: Interceptor.Chain): Response {

44

val request = chain.request()

45

46

val t1 = System.nanoTime()

47

println("Sending request ${request.url}")

48

49

val response = chain.proceed(request)

50

51

val t2 = System.nanoTime()

52

println("Received response for ${response.request.url} in ${(t2 - t1) / 1e6} ms")

53

54

return response

55

}

56

}

57

```

58

59

### Authentication Interceptor

60

61

```kotlin

62

class AuthInterceptor(private val token: String) : Interceptor {

63

override fun intercept(chain: Interceptor.Chain): Response {

64

val request = chain.request().newBuilder()

65

.addHeader("Authorization", "Bearer $token")

66

.build()

67

return chain.proceed(request)

68

}

69

}

70

```

71

72

### Retry Interceptor

73

74

```kotlin

75

class RetryInterceptor(private val maxRetries: Int = 3) : Interceptor {

76

override fun intercept(chain: Interceptor.Chain): Response {

77

var request = chain.request()

78

var response = chain.proceed(request)

79

var retryCount = 0

80

81

while (!response.isSuccessful && retryCount < maxRetries) {

82

retryCount++

83

response.close()

84

response = chain.proceed(request)

85

}

86

87

return response

88

}

89

}

90

```

91

92

### Cache Override Interceptor

93

94

```kotlin

95

class CacheInterceptor : Interceptor {

96

override fun intercept(chain: Interceptor.Chain): Response {

97

val request = chain.request()

98

99

// Modify request based on network availability

100

val cacheControl = if (isNetworkAvailable()) {

101

CacheControl.Builder()

102

.maxAge(5, TimeUnit.MINUTES)

103

.build()

104

} else {

105

CacheControl.Builder()

106

.onlyIfCached()

107

.maxStale(7, TimeUnit.DAYS)

108

.build()

109

}

110

111

val cacheRequest = request.newBuilder()

112

.cacheControl(cacheControl)

113

.build()

114

115

return chain.proceed(cacheRequest)

116

}

117

}

118

```