Skip to content

Commit e28b835

Browse files
authored
Handle slashes in pgw grouping label values. (#491)
Good base64 support was only added in Java 8, we support back to Java 6 so this is a little unclean. Signed-off-by: Brian Brazil <[email protected]>
1 parent 6200135 commit e28b835

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.io.IOException;
66
import java.io.InputStream;
77
import java.io.OutputStreamWriter;
8+
import java.io.UnsupportedEncodingException;
89
import java.net.HttpURLConnection;
910
import java.net.InetAddress;
1011
import java.net.MalformedURLException;
@@ -15,6 +16,7 @@
1516
import java.util.Collections;
1617
import java.util.HashMap;
1718
import java.util.Map;
19+
import javax.xml.bind.DatatypeConverter;
1820

1921
import io.prometheus.client.Collector;
2022
import io.prometheus.client.CollectorRegistry;
@@ -79,7 +81,7 @@ public PushGateway(String address) {
7981
* @param serverBaseURL the base URL and optional context path of the Pushgateway server.
8082
*/
8183
public PushGateway(URL serverBaseURL) {
82-
this.gatewayBaseURL = URI.create(serverBaseURL.toString() + "/metrics/job/")
84+
this.gatewayBaseURL = URI.create(serverBaseURL.toString() + "/metrics/")
8385
.normalize()
8486
.toString();
8587
}
@@ -275,11 +277,20 @@ public void delete(String job, String instance) throws IOException {
275277
}
276278

277279
void doRequest(CollectorRegistry registry, String job, Map<String, String> groupingKey, String method) throws IOException {
278-
String url = gatewayBaseURL + URLEncoder.encode(job, "UTF-8");
280+
String url = gatewayBaseURL;
281+
if (job.contains("/")) {
282+
url += "job@base64/" + base64url(job);
283+
} else {
284+
url += "job/" + URLEncoder.encode(job, "UTF-8");
285+
}
279286

280287
if (groupingKey != null) {
281288
for (Map.Entry<String, String> entry: groupingKey.entrySet()) {
282-
url += "/" + entry.getKey() + "/" + URLEncoder.encode(entry.getValue(), "UTF-8");
289+
if (entry.getValue().contains("/")) {
290+
url += "/" + entry.getKey() + "@base64/" + base64url(entry.getValue());
291+
} else {
292+
url += "/" + entry.getKey() + "/" + URLEncoder.encode(entry.getValue(), "UTF-8");
293+
}
283294
}
284295
}
285296
HttpURLConnection connection = connectionFactory.create(url);
@@ -318,6 +329,15 @@ void doRequest(CollectorRegistry registry, String job, Map<String, String> group
318329
}
319330
}
320331

332+
private static String base64url(String v) {
333+
// Per RFC4648 table 2. We support Java 6, and java.util.Base64 was only added in Java 8,
334+
try {
335+
return DatatypeConverter.printBase64Binary(v.getBytes("UTF-8")).replace("+", "-").replace("/", "_");
336+
} catch (UnsupportedEncodingException e) {
337+
throw new RuntimeException(e); // Unreachable.
338+
}
339+
}
340+
321341
/**
322342
* Returns a grouping key with the instance label set to the machine's IP address.
323343
* <p>

simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public void testInvalidURLThrowsRuntimeException() {
4545
public void testMultipleSlashesAreStrippedFromURL() {
4646
final PushGateway pushGateway = new PushGateway("example.com:1234/context///path//");
4747
Assert.assertEquals(
48-
"http://example.com:1234/context/path/metrics/job/",
48+
"http://example.com:1234/context/path/metrics/",
4949
pushGateway.gatewayBaseURL
5050
);
5151
}
@@ -106,9 +106,9 @@ public void testPushWithGroupingKeyWithSlashes() throws IOException {
106106
mockServerClient.when(
107107
request()
108108
.withMethod("PUT")
109-
.withPath("/metrics/job/a%2Fb/l/v/l2/v%2F2")
109+
.withPath("/metrics/job@base64/YS9i/l/v/l2@base64/75-_Lw==")
110110
).respond(response().withStatusCode(202));
111-
groupingKey.put("l2", "v/2");
111+
groupingKey.put("l2", "\uF7FF/");
112112
pg.push(registry, "a/b", groupingKey);
113113
}
114114

@@ -219,7 +219,7 @@ public void testOldPushWithSlashes() throws IOException {
219219
mockServerClient.when(
220220
request()
221221
.withMethod("PUT")
222-
.withPath("/metrics/job/a%2Fb/instance/c%2Fd")
222+
.withPath("/metrics/job@base64/YS9i/instance@base64/Yy9k")
223223
).respond(response().withStatusCode(202));
224224
pg.push(registry, "a/b", "c/d");
225225
}

0 commit comments

Comments
 (0)