diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PluginResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PluginResource.java
index bd3462c..a36e94c 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PluginResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PluginResource.java
@@ -20,7 +20,10 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URLEncoder;
import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
@@ -31,6 +34,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
+import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
@@ -38,6 +42,7 @@ import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
+import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import org.slf4j.Logger;
@@ -59,7 +64,8 @@ import com.google.inject.name.Named;
public class PluginResource extends JaxRsResourceBase {
private static final Logger log = LoggerFactory.getLogger(PluginResource.class);
- private static final Charset UTF_8 = Charset.forName("UTF-8");
+ private static final String UTF_8_STRING = "UTF-8";
+ private static final Charset UTF_8 = Charset.forName(UTF_8_STRING);
private final HttpServlet osgiServlet;
@@ -99,6 +105,16 @@ public class PluginResource extends JaxRsResourceBase {
}
@POST
+ @Consumes("application/x-www-form-urlencoded")
+ public Response doFormPOST(final MultivaluedMap<String, String> form,
+ @javax.ws.rs.core.Context final HttpServletRequest request,
+ @javax.ws.rs.core.Context final HttpServletResponse response,
+ @javax.ws.rs.core.Context final ServletContext servletContext,
+ @javax.ws.rs.core.Context final ServletConfig servletConfig) throws ServletException, IOException {
+ return serviceViaOSGIPlugin(form, request, response, servletContext, servletConfig);
+ }
+
+ @POST
public Response doPOST(@javax.ws.rs.core.Context final HttpServletRequest request,
@javax.ws.rs.core.Context final HttpServletResponse response,
@javax.ws.rs.core.Context final ServletContext servletContext,
@@ -127,8 +143,21 @@ public class PluginResource extends JaxRsResourceBase {
private Response serviceViaOSGIPlugin(final HttpServletRequest request, final HttpServletResponse response,
final ServletContext servletContext, final ServletConfig servletConfig) throws ServletException, IOException {
+ return serviceViaOSGIPlugin(request, request.getInputStream(), response, servletContext, servletConfig);
+ }
+
+ private Response serviceViaOSGIPlugin(final MultivaluedMap<String, String> form,
+ final HttpServletRequest request, final HttpServletResponse response,
+ final ServletContext servletContext, final ServletConfig servletConfig) throws ServletException, IOException {
+ // form will contain form parameters, if any. Even if the request contains such parameters, it may be empty
+ // if a filter (e.g. Shiro) has already consumed them (see kludge below)
+ return serviceViaOSGIPlugin(request, createInputStream(request, form), response, servletContext, servletConfig);
+ }
+
+ private Response serviceViaOSGIPlugin(final HttpServletRequest request, final InputStream inputStream, final HttpServletResponse response,
+ final ServletContext servletContext, final ServletConfig servletConfig) throws ServletException, IOException {
prepareOSGIRequest(request, servletContext, servletConfig);
- osgiServlet.service(new OSGIServletRequestWrapper(request, createInputStream(request)), new OSGIServletResponseWrapper(response));
+ osgiServlet.service(new OSGIServletRequestWrapper(request, inputStream), new OSGIServletResponseWrapper(response));
if (response.isCommitted()) {
if (response.getStatus() >= 400) {
@@ -141,32 +170,41 @@ public class PluginResource extends JaxRsResourceBase {
}
}
- private InputStream createInputStream(final HttpServletRequest request) throws IOException {
+ private InputStream createInputStream(final HttpServletRequest request, final MultivaluedMap<String, String> form) throws IOException {
// /!\ Kludge alert (pierre) /!\
// This is awful... But because of various servlet filters we have in place, include Shiro,
// the request parameters and/or body at this point have already been looked at.
// We can't use @FormParam in PluginResource because we don't know the form parameter names
// in advance.
// So... We just stick them back in :-)
- // TODO Support x-www-form-urlencoded vs multipart/form-data
+ // TODO Support application/x-www-form-urlencoded vs multipart/form-data
final ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ final Map<String, String> data = new HashMap<String, String>();
for (final String key : request.getParameterMap().keySet()) {
- out.write((key + "=").getBytes(UTF_8));
-
- int idx = 0;
- for (final String value : request.getParameterMap().get(key)) {
- if (idx > 0) {
- out.write("&".getBytes(UTF_8));
- }
- idx++;
- out.write(value.getBytes(UTF_8));
- }
+ data.put(key, request.getParameter(key));
}
- ByteStreams.copy(request.getInputStream(), out);
+ for (final String key : form.keySet()) {
+ data.put(key, form.getFirst(key));
+ }
+ appendFormParametersToBody(out, data);
+ ByteStreams.copy(request.getInputStream(), out);
return new ByteArrayInputStream(out.toByteArray());
}
+ private void appendFormParametersToBody(final ByteArrayOutputStream out, final Map<String, String> data) throws IOException {
+ int idx = 0;
+ for (final String key : data.keySet()) {
+ if (idx > 0) {
+ out.write("&".getBytes(UTF_8));
+ }
+
+ out.write((key + "=" + URLEncoder.encode(data.get(key), UTF_8_STRING)).getBytes(UTF_8));
+ idx++;
+ }
+ }
+
private void prepareOSGIRequest(final HttpServletRequest request, final ServletContext servletContext, final ServletConfig servletConfig) {
request.setAttribute("killbill.osgi.servletContext", servletContext);
request.setAttribute("killbill.osgi.servletConfig", servletConfig);