diff --git a/bubble-server/src/main/java/bubble/main/http/BubbleHttpEntityOptions.java b/bubble-server/src/main/java/bubble/main/http/BubbleHttpEntityOptions.java index 2b0963c8..bc5ee396 100644 --- a/bubble-server/src/main/java/bubble/main/http/BubbleHttpEntityOptions.java +++ b/bubble-server/src/main/java/bubble/main/http/BubbleHttpEntityOptions.java @@ -15,6 +15,7 @@ import java.io.InputStream; import static org.cobbzilla.util.daemon.ZillaRuntime.*; import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON; +import static org.cobbzilla.util.http.HttpContentTypes.MULTIPART_FORM_DATA; import static org.cobbzilla.util.json.JsonUtil.*; @Slf4j @@ -22,12 +23,14 @@ public class BubbleHttpEntityOptions extends BubbleHttpOptions { public String getRequestJson() { final String data = readStdin(); - // does the JSON contain any comments? scrub them before sending... - if (data.contains("//") || data.contains("/*")) { - try { - return json(json(data, JsonNode.class, FULL_MAPPER_ALLOW_COMMENTS), COMPACT_MAPPER); - } catch (Exception e) { - log.warn("getRequestJson: error scrubbing comments from JSON, sending as-is: " + shortError(e)); + if (getContentType().equals(APPLICATION_JSON)) { + // does the JSON contain any comments? scrub them before sending... + if (data.contains("//") || data.contains("/*")) { + try { + return json(json(data, JsonNode.class, FULL_MAPPER_ALLOW_COMMENTS), COMPACT_MAPPER); + } catch (Exception e) { + log.warn("getRequestJson: error scrubbing comments from JSON, sending as-is: " + shortError(e)); + } } } return data; @@ -43,11 +46,16 @@ public class BubbleHttpEntityOptions extends BubbleHttpOptions { public boolean hasMultipartFileName() { return !empty(multipartFileName); } - public static final String USAGE_CONTENT_TYPE = "Content-Type to send. Default is application/json"; + public static final String USAGE_CONTENT_TYPE = "Content-Type to send. Default is application/json, or multipart/form-data for multipart requests"; public static final String OPT_CONTENT_TYPE = "-C"; public static final String LONGOPT_CONTENT_TYPE= "--content-type"; @Option(name=OPT_CONTENT_TYPE, aliases=LONGOPT_CONTENT_TYPE, usage=USAGE_CONTENT_TYPE) - @Getter @Setter private String contentType = APPLICATION_JSON; + @Setter private String contentType = null; + public String getContentType () { + if (contentType != null) return contentType; + if (hasMultipartFileName()) return MULTIPART_FORM_DATA; + return APPLICATION_JSON; + } public ContentType contentType() { return ContentType.create(getContentType()); } diff --git a/bubble-server/src/main/java/bubble/main/http/BubbleHttpMain.java b/bubble-server/src/main/java/bubble/main/http/BubbleHttpMain.java index 2a0f0a16..51af020c 100644 --- a/bubble-server/src/main/java/bubble/main/http/BubbleHttpMain.java +++ b/bubble-server/src/main/java/bubble/main/http/BubbleHttpMain.java @@ -18,12 +18,16 @@ import org.cobbzilla.wizard.util.RestResponse; import javax.ws.rs.core.HttpHeaders; +import static org.apache.http.HttpHeaders.CONTENT_TYPE; import static org.cobbzilla.util.daemon.ZillaRuntime.errorString; +import static org.cobbzilla.util.http.HttpContentTypes.MULTIPART_FORM_DATA; import static org.cobbzilla.util.http.HttpStatusCodes.OK; import static org.cobbzilla.util.json.JsonUtil.prettyJson; public abstract class BubbleHttpMain extends BubbleApiMain { + public static final NameAndValue[] HEADER_CONTENT_TYPE_MULTIPART = {new NameAndValue(CONTENT_TYPE, MULTIPART_FORM_DATA)}; + protected abstract RestResponse request(String url) throws Exception; protected abstract String getMethod(); @@ -48,7 +52,7 @@ public abstract class BubbleHttpMain extends Bubb final BubbleHttpEntityOptions entityOptions = (options instanceof BubbleHttpEntityOptions) ? (BubbleHttpEntityOptions) options : null; if (entityOptions != null) { if (entityOptions.hasMultipartFileName()) { - request = new HttpRequestBean(getMethod(), requestUrl, entityOptions.getRequestStream(), entityOptions.getMultipartFileName(), NameAndValue.EMPTY_ARRAY); + request = new HttpRequestBean(getMethod(), requestUrl, entityOptions.getRequestStream(), entityOptions.getMultipartFileName(), HEADER_CONTENT_TYPE_MULTIPART); } else { request = new HttpRequestBean(getMethod(), requestUrl, entityOptions.getRequestJson()); } @@ -59,7 +63,16 @@ public abstract class BubbleHttpMain extends Bubb if (options.hasHttpBasicUser()) request.setAuthUsername(options.getHttpBasicUser()); if (options.hasHttpBasicPassword()) request.setAuthPassword(options.getHttpBasicPassword()); if (entityOptions != null && entityOptions.hasMultipartFileName()) { - IOUtils.copyLarge(getApiClient().uploadMultipartStream(request, entityOptions.getMultipartFileName()), System.out); + RestResponse response = getApiClient().uploadStream(options.getUrl(), entityOptions.getRequestStream(), entityOptions.getMultipartFileName(), getMethod()); + if (response.status == OK) { + try { + out(prettyJson(response.json)); + } catch (Exception e) { + out(response.json); + } + } else { + error(response, null, "unexpected status"); + } } else { IOUtils.copyLarge(getApiClient().getStream(request), System.out); } @@ -68,7 +81,11 @@ public abstract class BubbleHttpMain extends Bubb try { response = request(requestUrl); if (response.status == OK) { - out(prettyJson(response.json)); + try { + out(prettyJson(response.json)); + } catch (Exception e) { + out(response.json); + } } else { error(response, null, "unexpected status"); } diff --git a/utils/cobbzilla-wizard b/utils/cobbzilla-wizard index 23e6ab73..b4e6a580 160000 --- a/utils/cobbzilla-wizard +++ b/utils/cobbzilla-wizard @@ -1 +1 @@ -Subproject commit 23e6ab7399be669a1f9bb9abf64186f3d029eda5 +Subproject commit b4e6a58077a87a2ddcb679d3f16f550077096993