forked from open-telemetry/opentelemetry-java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BaggageCodec.java
88 lines (80 loc) · 2.97 KB
/
BaggageCodec.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.baggage.propagation;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* Note: This class is based on code from Apache Commons Codec. It is comprised of code from these
* classes:
*
* <ul>
* <li><a
* href="https://github.com/apache/commons-codec/blob/482df6cabfb288acb6ab3e4a732fdb93aecfa7c2/src/main/java/org/apache/commons/codec/net/URLCodec.java">org.apache.commons.codec.net.URLCodec</a>
* <li><a
* href="https://github.com/apache/commons-codec/blob/482df6cabfb288acb6ab3e4a732fdb93aecfa7c2/src/main/java/org/apache/commons/codec/net/Utils.java">org.apache.commons.codec.net.Utils</a>
* </ul>
*
* <p>Implements baggage-octet decoding in accordance with th <a
* href="https://w3c.github.io/baggage/#definition">Baggage header content</a> specification. All
* US-ASCII characters excluding CTLs, whitespace, DQUOTE, comma, semicolon and backslash are
* encoded in `www-form-urlencoded` encoding scheme.
*/
class BaggageCodec {
private static final byte ESCAPE_CHAR = '%';
private static final int RADIX = 16;
private BaggageCodec() {}
/**
* Decodes an array of URL safe 7-bit characters into an array of original bytes. Escaped
* characters are converted back to their original representation.
*
* @param bytes array of URL safe characters
* @return array of original bytes
*/
private static byte[] decode(byte[] bytes) {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
for (int i = 0; i < bytes.length; i++) {
int b = bytes[i];
if (b == ESCAPE_CHAR) {
try {
int u = digit16(bytes[++i]);
int l = digit16(bytes[++i]);
buffer.write((char) ((u << 4) + l));
} catch (ArrayIndexOutOfBoundsException e) { // FIXME
throw new IllegalArgumentException("Invalid URL encoding: ", e);
}
} else {
buffer.write(b);
}
}
return buffer.toByteArray();
}
/**
* Decodes an array of URL safe 7-bit characters into an array of original bytes. Escaped
* characters are converted back to their original representation.
*
* @param value string of URL safe characters
* @param charset encoding of given string
* @return decoded value
*/
static String decode(String value, Charset charset) {
byte[] bytes = decode(value.getBytes(StandardCharsets.US_ASCII));
return new String(bytes, charset);
}
/**
* Returns the numeric value of the character {@code b} in radix 16.
*
* @param b The byte to be converted.
* @return The numeric value represented by the character in radix 16.
*/
private static int digit16(byte b) {
int i = Character.digit((char) b, RADIX);
if (i == -1) {
throw new IllegalArgumentException( // FIXME
"Invalid URL encoding: not a valid digit (radix " + RADIX + "): " + b);
}
return i;
}
}