Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,9 @@ public static boolean isRESTRequest(String contentType) {
* This contains,
* 1. application/json
* <p/>
* Only the media type, the part before any parameters and the part the message
* builder is selected by, is compared, so "text/plain; x=application/json" is not
* a JSON request.
* If the request does not contain a content type, this will return false.
*
* @param contentType content type to check
Expand All @@ -381,7 +384,9 @@ public static boolean isJSONRequest(String contentType) {
if (contentType == null || contentType.isEmpty()) {
return false;
}
return (contentType.toLowerCase().indexOf(HTTPConstants.MEDIA_TYPE_APPLICATION_JSON) != -1);
int index = contentType.indexOf(';');
String mediaType = index >= 0 ? contentType.substring(0, index) : contentType;
return HTTPConstants.MEDIA_TYPE_APPLICATION_JSON.equalsIgnoreCase(mediaType);
}

public static EndpointReference[] getEPRsForService(ConfigurationContext configurationContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,47 @@ public void testEnableJSONOnlyFalseAllowsNormalProcessing() throws Exception {
}
}

/**
* application/json in a parameter does not make a form-encoded POST a JSON request.
* The type is CORS-safelisted, so a cross-site page can send it without a preflight.
*/
public void testEnableJSONOnlyRejectsJSONInContentTypeParameter() throws Exception {
axisConfig.addParameter(new Parameter(Constants.Configuration.ENABLE_JSON_ONLY, "true"));
axisConfig.addMessageBuilder("application/x-www-form-urlencoded",
new org.apache.axis2.builder.XFormURLEncodedBuilder());

final int[] invocations = new int[1];
axisConfig.getService("TestService").getOperation(new QName("testOperation"))
.setMessageReceiver(new org.apache.axis2.engine.MessageReceiver() {
public void receive(MessageContext messageContext) {
invocations[0]++;
}
});

String uri = "/axis2/services/TestService/testOperation";
when(mockRequest.getRequestURI()).thenReturn(uri);
when(mockRequest.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080" + uri));
when(mockRequest.getMethod()).thenReturn("POST");
when(mockRequest.getContentType()).thenReturn("application/x-www-form-urlencoded; x=application/json");
when(mockRequest.getInputStream()).thenReturn(new MockServletInputStream("value=1"));

when(mockServletContext.getAttribute(AxisServlet.CONFIGURATION_CONTEXT)).thenReturn(configContext);
servlet.init(mockServletConfig);
servlet.doPost(mockRequest, mockResponse);

assertEquals("the operation must not be reached", 0, invocations[0]);
assertTrue("Should return JSON error message",
responseOutputStream.toString().contains("application/json is mandatory"));
}

public void testIsJSONRequestComparesTheMediaType() {
assertTrue(HTTPTransportUtils.isJSONRequest("application/json"));
assertTrue(HTTPTransportUtils.isJSONRequest("application/json; charset=UTF-8"));
assertTrue(HTTPTransportUtils.isJSONRequest("Application/JSON"));
assertFalse(HTTPTransportUtils.isJSONRequest("text/plain; x=application/json"));
assertFalse(HTTPTransportUtils.isJSONRequest("application/json-patch+json"));
}

/**
* Test that non-JSON requests are rejected when enableJSONOnly=true.
*/
Expand Down