or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

conditions.mdconfiguration.mdcontrol.mddecompression.mdencoding.mdindex.md

decompression.mddocs/

0

# Request Decompression

1

2

The Compression plugin automatically decompresses incoming request bodies that have been compressed with supported algorithms. It handles `Content-Encoding` headers and tracks which decoders were applied.

3

4

## Decompression Process

5

6

When the plugin receives a request with a `Content-Encoding` header:

7

8

1. Parses the encoding value(s) from the header

9

2. Matches available decoders with the specified encodings

10

3. Applies decoders in reverse order (last encoding applied is first to be removed)

11

4. Updates or removes the `Content-Encoding` header

12

5. Tracks applied decoders for inspection

13

14

## Decoder Tracking

15

16

```kotlin { .api }

17

val ApplicationRequest.appliedDecoders: List<String>

18

```

19

20

Access the list of decoder names that were used to decompress the request body:

21

22

```kotlin

23

routing {

24

post("/upload") {

25

val decoders = call.request.appliedDecoders

26

if (decoders.isNotEmpty()) {

27

println("Request was decompressed using: ${decoders.joinToString(", ")}")

28

}

29

30

val body = call.receiveText()

31

// Process decompressed body...

32

call.respond("Received")

33

}

34

}

35

```

36

37

## Supported Decompression Algorithms

38

39

The plugin uses the same `ContentEncoder` implementations for both compression and decompression:

40

41

- **gzip** - Handles gzip-compressed request bodies

42

- **deflate** - Handles deflate-compressed request bodies

43

- **identity** - Pass-through for uncompressed content

44

45

## Header Management

46

47

### Complete Decompression

48

49

When all encodings can be decompressed, the plugin:

50

- Removes the `Content-Encoding` header entirely

51

- May remove or adjust the `Content-Length` header

52

- Adds `Transfer-Encoding: chunked` if needed

53

54

```

55

Request headers before decompression:

56

Content-Encoding: gzip

57

Content-Length: 1024

58

59

Request headers after decompression:

60

Transfer-Encoding: chunked

61

(Content-Encoding and Content-Length removed)

62

```

63

64

### Partial Decompression

65

66

When only some encodings can be decompressed, the plugin:

67

- Updates the `Content-Encoding` header with remaining encodings

68

- Tracks which decoders were successfully applied

69

70

```

71

Request headers before decompression:

72

Content-Encoding: gzip, custom-encoding

73

74

Request headers after decompression:

75

Content-Encoding: custom-encoding

76

(gzip removed, custom-encoding remains)

77

```

78

79

## Decompression Control

80

81

### Operation Mode

82

83

Control decompression behavior via the plugin's operation mode:

84

85

```kotlin

86

install(Compression) {

87

mode = CompressionConfig.Mode.DecompressRequest // Only decompress requests

88

mode = CompressionConfig.Mode.CompressResponse // No decompression

89

mode = CompressionConfig.Mode.All // Both compress and decompress (default)

90

}

91

```

92

93

### Suppression

94

95

Disable decompression for specific requests:

96

97

```kotlin { .api }

98

fun ApplicationCall.suppressDecompression()

99

val ApplicationCall.isDecompressionSuppressed: Boolean

100

```

101

102

```kotlin

103

routing {

104

post("/raw-upload") {

105

// Keep request body compressed

106

call.suppressDecompression()

107

108

// Receive raw compressed bytes

109

val compressedBody = call.receive<ByteArray>()

110

// Handle compressed data directly...

111

}

112

113

post("/check-suppressed") {

114

if (call.isDecompressionSuppressed) {

115

// Handle suppressed case

116

} else {

117

// Normal decompression will occur

118

val decompressedText = call.receiveText()

119

}

120

}

121

}

122

```

123

124

## Error Handling

125

126

The plugin handles various decompression scenarios gracefully:

127

128

### Missing Content-Encoding

129

Requests without `Content-Encoding` headers are processed normally without decompression attempts.

130

131

### Unsupported Encodings

132

When encountering unknown encodings:

133

- Supported encodings are still processed

134

- Unsupported encodings remain in the `Content-Encoding` header

135

- The request continues processing with partial decompression

136

137

### Malformed Compressed Data

138

Decompression errors are propagated as exceptions that can be handled by error handling mechanisms.

139

140

## Usage Examples

141

142

### Basic Decompression

143

144

```kotlin

145

install(Compression) // Enables decompression by default

146

147

routing {

148

post("/api/data") {

149

// Automatically decompressed if client sent compressed request

150

val data = call.receive<MyDataClass>()

151

call.respond("Processed ${data}")

152

}

153

}

154

```

155

156

### Conditional Processing

157

158

```kotlin

159

routing {

160

post("/upload") {

161

val wasCompressed = call.request.appliedDecoders.isNotEmpty()

162

val contentLength = call.request.headers[HttpHeaders.ContentLength]?.toLongOrNull()

163

164

when {

165

wasCompressed -> {

166

logger.info("Received compressed upload (${call.request.appliedDecoders})")

167

}

168

contentLength != null && contentLength > 1024 * 1024 -> {

169

logger.warn("Large uncompressed upload: $contentLength bytes")

170

}

171

}

172

173

val content = call.receiveText()

174

// Process content...

175

}

176

}

177

```

178

179

### Custom Decoder Integration

180

181

```kotlin

182

install(Compression) {

183

// Add custom decoder alongside built-in ones

184

encoder(MyCustomEncoder) {

185

// Custom encoder handles both compression and decompression

186

}

187

}

188

```