From d1918a206886942bd0e0beeccf3a7a8867680d60 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Mon, 2 Mar 2015 16:43:28 -0500 Subject: [PATCH 1/2] Add symbolic names for content types --- .../main/java/com/typesafe/config/impl/Parseable.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/config/src/main/java/com/typesafe/config/impl/Parseable.java b/config/src/main/java/com/typesafe/config/impl/Parseable.java index 6b377632..5f301aa1 100644 --- a/config/src/main/java/com/typesafe/config/impl/Parseable.java +++ b/config/src/main/java/com/typesafe/config/impl/Parseable.java @@ -417,6 +417,10 @@ public abstract class Parseable implements ConfigParseable { return new ParseableString(input, options); } + private static final String jsonContentType = "application/json"; + private static final String propertiesContentType = "text/x-java-properties"; + private static final String hoconContentType = "application/hocon"; + private static class ParseableURL extends Parseable { final protected URL input; private String contentType = null; @@ -462,11 +466,11 @@ public abstract class Parseable implements ConfigParseable { @Override ConfigSyntax contentType() { if (contentType != null) { - if (contentType.equals("application/json")) + if (contentType.equals(jsonContentType)) return ConfigSyntax.JSON; - else if (contentType.equals("text/x-java-properties")) + else if (contentType.equals(propertiesContentType)) return ConfigSyntax.PROPERTIES; - else if (contentType.equals("application/hocon")) + else if (contentType.equals(hoconContentType)) return ConfigSyntax.CONF; else { if (ConfigImpl.traceLoadsEnabled()) From d4125f217b1a1a388c0f0abc23ec6f548ea0c06e Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Mon, 2 Mar 2015 16:54:50 -0500 Subject: [PATCH 2/2] Set Accept header on URL connections This fixes #182 in theory, though test coverage is nonexistent. --- .../com/typesafe/config/impl/Parseable.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/config/src/main/java/com/typesafe/config/impl/Parseable.java b/config/src/main/java/com/typesafe/config/impl/Parseable.java index 5f301aa1..616ffaa1 100644 --- a/config/src/main/java/com/typesafe/config/impl/Parseable.java +++ b/config/src/main/java/com/typesafe/config/impl/Parseable.java @@ -100,6 +100,10 @@ public abstract class Parseable implements ConfigParseable { // to support the "allow missing" feature. protected abstract Reader reader() throws IOException; + protected Reader reader(ConfigParseOptions options) throws IOException { + return reader(); + } + protected static void trace(String message) { if (ConfigImpl.traceLoadsEnabled()) { ConfigImpl.trace(message); @@ -195,7 +199,7 @@ public abstract class Parseable implements ConfigParseable { // options.getAllowMissing() protected AbstractConfigValue rawParseValue(ConfigOrigin origin, ConfigParseOptions finalOptions) throws IOException { - Reader reader = reader(); + Reader reader = reader(finalOptions); // after reader() we will have loaded the Content-Type. ConfigSyntax contentType = contentType(); @@ -437,9 +441,38 @@ public abstract class Parseable implements ConfigParseable { @Override protected Reader reader() throws IOException { + throw new ConfigException.BugOrBroken("reader() without options should not be called on ParseableURL"); + } + + private static String acceptContentType(ConfigParseOptions options) { + if (options.getSyntax() == null) + return null; + + switch (options.getSyntax()) { + case JSON: + return jsonContentType; + case CONF: + return hoconContentType; + case PROPERTIES: + return propertiesContentType; + } + + // not sure this is reachable but javac thinks it is + return null; + } + + @Override + protected Reader reader(ConfigParseOptions options) throws IOException { if (ConfigImpl.traceLoadsEnabled()) trace("Loading config from a URL: " + input.toExternalForm()); URLConnection connection = input.openConnection(); + + // allow server to serve multiple types from one URL + String acceptContent = acceptContentType(options); + if (acceptContent != null) { + connection.setRequestProperty("Accept", acceptContent); + } + connection.connect(); // save content type for later