Ambiguous mapping error : Spring Controller - java

When i deploy my code I get error
Caused by: java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'programController' bean method
public java.lang.String com.quizapp.beans.controller.panal.ProgramController.editProgram(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
to {[],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'programController' bean method
public java.lang.String com.quizapp.beans.controller.panal.ProgramController.setupProgram(javax.servlet.http.HttpSession,org.springframework.ui.Model) mapped.
Below is my programController class
#Controller
public class ProgramController {
#RequestMapping(name = "/editProgram", method = RequestMethod.GET)
public String editProgram(HttpServletRequest request, HttpServletResponse response) {
if (request.getSession().getAttribute(Constants.LOGGED_IN_USER) != null) {
ProgramEntity program = new ProgramEntity();
if (request.getParameter("id") == null) {// create
program.setType("create");
} else {// edit
program.setType("edit");
program.setCode(request.getParameter("id"));
}
request.setAttribute("programBean", program);
return "editProgram";
} else {
return "redirect:/login";
}
}
#RequestMapping(name = "/program", method = RequestMethod.GET)
public String setupProgram(HttpSession session, Model model) {
if (session.getAttribute(Constants.LOGGED_IN_USER) != null) {
model.addAttribute("programBean", new ProgramEntity());
// if (request.getSession().getAttribute(Constants.LOGGED_IN_USER) != null) {
// request.setAttribute("programBean", new ProgramEntity());
return "viewProgram";
} else {
return "redirect:/login";
}
}
}
When i make the method editProgram as POST then it deploy perfectly.
Why is there problem with adding two GET method.
There are many similar questions available on StackOverflow but i couldn't find right answer.

Because you are specifying different names of RequestMapping and not values. Currently, value of both the methods are same ("" - empty) which is not allowed. Your URL part of request mapping should be specified in value and not name attribute of #RequestMapping.

Try This:
#Controller
public class ProgramController {
#RequestMapping(value = "/editProgram", method = RequestMethod.GET)
public String editProgram(HttpServletRequest request, HttpServletResponse response) {
if (request.getSession().getAttribute(Constants.LOGGED_IN_USER) != null) {
ProgramEntity program = new ProgramEntity();
if (request.getParameter("id") == null) {// create
program.setType("create");
} else {// edit
program.setType("edit");
program.setCode(request.getParameter("id"));
}
request.setAttribute("programBean", program);
return "editProgram";
} else {
return "redirect:/login";
}
}
#RequestMapping(value= "/program", method = RequestMethod.GET)
public String setupProgram(HttpSession session, Model model) {
if (session.getAttribute(Constants.LOGGED_IN_USER) != null) {
model.addAttribute("programBean", new ProgramEntity());
// if (request.getSession().getAttribute(Constants.LOGGED_IN_USER) != null) {
// request.setAttribute("programBean", new ProgramEntity());
return "viewProgram";
} else {
return "redirect:/login";
}
}
}

Related

Play framework 2.7.* Java - HTTP Context Deprecated - Token Based Authentication

Currently upgrading play framework to 2.7.* I'm getting an error response due to deprecation in the security authenticator class of HTTP.Context class
The application was on Play 2.6.* and auth was working as designed. If I roll back to 2.6.* the authentication works well. Essentially I'm hoping to return the auth token as a String.
#Override
public String getUsername(Http.Request ctx) {
Optional token = getTokenFromHeader(ctx);
if(token.isPresent()){
UserAccount userAccount = UserAccount.find.query().where().eq("authtoken",token.toString()).findOne();
if (userAccount != null){
//ctx.args.put("userAccount", userAccount);
//String resp = Optional.<String>ofNullable(null).orElse(orelesMethod());
String resp = Optional.<String>ofNullable(null).orElse(userAccount.authtoken);
return resp;
}
}
return null;
}
#Override
public Result onUnauthorized(Http.Request ctx) {
Logger.info("onUnauthorized");
ObjectNode result = Json.newObject();
result.put("error","Unauthorized, Please login");
return status(401,result);
}
private Optional getTokenFromHeader(Http.Request ctx) {
return ctx.header("X-AUTH-TOKEN");
}
}
Original Code is as below
public class Secured extends Security.Authenticator{
#Override
public String getUsername(Http.Context ctx) {
String token = getTokenFromHeader(ctx);
if(token != null){
UserAccount userAccount = UserAccount.find.query().where().eq("authtoken",token).findOne();
if (userAccount != null){
ctx.args.put("userAccount", userAccount);
return userAccount.authtoken;
}
}
return null;
}
#Override
public Result onUnauthorized(Http.Context ctx) {
Logger.info("onUnauthorized");
ObjectNode result = Json.newObject();
result.put("error","Unauthorized, Please login");
return status(401,result);
}
private String getTokenFromHeader(Http.Context ctx) {
String[] authTokenHeaderValues = ctx.request().headers().get("X-AUTH-TOKEN");
if ((authTokenHeaderValues != null) && (authTokenHeaderValues.length == 1) && (authTokenHeaderValues[0] != null)) {
return authTokenHeaderValues[0];
}
return null;
}
}
Error response
return type java.lang.String is not compatible with java.util.Optional<java.lang.String>
Play 2.7 has some changes in Security.Authenticator class. Now it has two methods named getUsername.
You override method with Request param, so you should return Optional not String.
Take a look on Authenticator code:
/**
* Handles authentication.
*/
public static class Authenticator extends Results {
#Deprecated
public String getUsername(Context ctx) {
return ctx.session().get("username");
}
// You override this method
public Optional<String> getUsername(Request req) {
return req.session().getOptional("username");
}
...
}

Java Interceptor not working on web service app

I have my app in Java Spring, and I cannot make the interceptors work.
The idea of the interceptor is to check if the token is still valid.
Below you have the code:
Interceptor class:
#Interceptor
public class SessionInterceptor {
#Autowired
LoginDao loginDao;
public SessionInterceptor(){}
#AroundInvoke
public Object intercept(InvocationContext context) throws Exception {
Response response = new Response();
Object[] parameters = context.getParameters();
if(parameters.length > 0 && parameters[0] instanceof HttpServletRequest){
HttpServletRequest jwt = (HttpServletRequest) parameters[0];
String token = JWTTokenAuthFilter.getToken(jwt);
if(token != null && this.loginDao.isTokenValid(JWTTokenAuthFilter.getToken(jwt))){
return context.proceed();
}
else
response.failed(CodeList.SESSION_TIME_OUT);
}
else
response.failed(CodeList.NOT_ALLOWED);
return response;
}
}
And this is how I'm using it in the User class
#Override
#Transactional
#Interceptors(SessionInterceptor.class)
public Response add(HttpServletRequest request, UserEnrollmentBO s) throws Exception {
Response response = new Response();
try {
...
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
I also added to the spring-config.xml
<bean id="sessionInterceptor" class="com.app.security.SessionInterceptor" />
Am I missing something?

Mockito mock doAnswer returns same value when reused between tests

I have the following tests. When I run them separately they pass. If I run all of them only the first passes.
Business Logic gets a JSON response from the APIServiceTask code. It creates an event to post using EventBus. I am writing tests to verify that EventBus is creating the correct calls.
The JSON Reponses class at the end is just the answers I am trying to post. If I run all of the tests, it seems like the loginFailureChangePasswordJSON is the one posted to the business logic.
public class LoginBusinessLogic {
private static LoginBusinessLogic instance = null;
APIServiceTask apiServiceTask;
public static LoginBusinessLogic getInstance(APIServiceTask apiServiceTask) {
if (instance == null) {
instance = new LoginBusinessLogic();
instance.apiServiceTask = apiServiceTask;
}
return instance;
}
protected void doLogin() {
EventBus.getDefault().register(this);
apiServiceTask.execute();
}
#Subscribe
public void onEvent(ServiceResultEvent event) {
switch (event.event) {
case failed:
handleLoginError(event.result);
break;
case cancelled:
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_CANCELLE, event.result));
break;
case error:
if(event.originatorEvent != LoginEvent.TYPE_TOUCH_TOKEN_DELETE) {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_ERROR, event.result));
}
break;
default:
break;
}
EventBus.getDefault().unregister(this);
}
private void handleLoginError(String error) {
ErrorModel signInError = new Gson().fromJson(error, ErrorModel.class);
int statusCode = signInError.getMTBStatusCode();
String errMsg;
if (statusCode == 40022) {
errMsg = signInError.getUserMessage();
} else {
errMsg = signInError.getUserMessage().replace("*", "").replace("\"", "");
}
if (statusCode == 40001) {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, false));
} else if (statusCode == 40108) {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, true, false));
}
else if (statusCode == 40107) {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, false));
} else if (statusCode == 40104) {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, true));
} else {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, false));
}
}
}
public class APIServiceTask {
public APIServiceTask(){
}
#SuppressWarnings("ConstantConditions")
public void execute() {
}
}
public class BusinessLogicTests {
#Mock
APIServiceTask service;
private LoginEvent loginEvent;
private LoginBusinessLogic loginBusinessLogic;
#Before
public void setUp(){
MockitoAnnotations.initMocks(this);
loginBusinessLogic = LoginBusinessLogic.getInstance(service);
EventBus.getDefault().register(this);
}
#After
public void tearDown(){
EventBus.getDefault().unregister(this);
}
#Subscribe
public void onEvent(LoginEvent event){
loginEvent = event;
}
#Test
public void badUsernamePasscode(){
doAnswer(JSONResponses.loginInvalidUsernamePasscodeJSON())
.when(service).execute();
loginBusinessLogic.doLogin();
Assert.assertEquals(40108, loginEvent.mtbStstusCode);
}
#Test
public void accountBlocked(){
doAnswer(JSONResponses.loginAccountBlockedJSON())
.when(service).execute();
loginBusinessLogic.doLogin();
Assert.assertEquals(40104, loginEvent.mtbStstusCode);
}
#Test
public void temporaryPasscode(){
doAnswer(JSONResponses.loginTemporaryPasscodeJSON())
.when(service).execute();
loginBusinessLogic.doLogin();
Assert.assertEquals(40109, loginEvent.mtbStstusCode);
}
#Test
public void changedPasscode(){
doAnswer(JSONResponses.loginFailureChangePasscodeJSON())
.when(service).execute();
loginBusinessLogic.doLogin();
Assert.assertEquals(40107, loginEvent.mtbStstusCode);
}
}
public class JSONResponses {
public static Answer loginFailureChangePasscodeJSON(){
Answer answer = new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
String result = "{\"MTBStatusCode\":40107, \"UserMessage\":\"Your passcode has changed since last login.\"}";
EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
return null;
}
};
return answer;
}
public static Answer loginAccountBlockedJSON(){
Answer answer = new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
String result = "{\"Version\":1,\"MTBStatusCode\":40104,\"HttpStatus\":401,\"UserMessage\":\"\\\"Your account is locked due to too many failed login attempts. <br><br>Reset Passcode >\\\"\",\"DeveloperMessage\":\"\\\"Account locked via multi-factor authentication.\\\"\"}";
EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
return null;
}
};
return answer;
}
public static Answer loginInvalidUsernamePasscodeJSON(){
Answer answer = new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
String result = "{\"Version\":1,\"MTBStatusCode\":40108,\"HttpStatus\":401,\"UserMessage\":\"\\\"User ID or Passcode doesn’t match. Try again.\\\"\",\"DeveloperMessage\":\"\\\"Voyager Error -1073739414 : User ID or Passcode doesn’t match. Try again.\\\"\"}";
EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
return null;
}
};
return answer;
}
public static Answer loginTemporaryPasscodeJSON(){
Answer answer = new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
String result = "{\"Version\":1,\"MTBStatusCode\":40107,\"HttpStatus\":401,\"UserMessage\":\"\\\"You have logged in with a temporary passcode. Log in to M&T Online Banking to create a new passcode.\\\"\",\"DeveloperMessage\":\"\\\"Password should be changed.\\\"\"}";
EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
return null;
}
};
return answer;
}
}
For anyone interested, it seems the singleton still exists when the other tests run. 2 ways I found to fix it are nulling out the singleton in a separate method or moving the following statement outside of the if in LoginBusinessLogic.
instance.apiServiceTask = apiServiceTask;

The request sent by the client was syntactically incorrect while calling a WebService through rest using AngularJS

I have WebService which is checking whether the email is already present in the database.
#RequestMapping(value = "/checkPersonEmail/{jClientSessionId}/{jClientSessionId}/{email}", method = RequestMethod.GET)
public boolean checkName(#PathVariable String jUserSessionId,
#PathVariable String jClientSessionId, #PathVariable String email)
throws Exception {
String decryptedClientKey = EncryptContetns
.getDecryptedvalue(jClientSessionId);
List<String> emailIds = dimPersonManager
.getEmailIdsByClientKey(Long.valueOf(decryptedClientKey));
List<String> emailIdList = new ArrayList<String>();
for (String ids : emailIds) {
emailIdList.add(ids.toLowerCase());
}
if (emailIdList != null && !emailIdList.isEmpty()) {
if (emailIdList.contains(email.toLowerCase())) {
return false;
} else {
return true;
}
} else {
return true;
}
}
Then I'm calling this service using a http.get method as show below.
AngularJS call
$scope.checkEmail = function() {
if (!appClient.isUndefinedOrNull($scope.person.email)) {
alert( $scope.person.email);
$scope.spinnerClass = "icon-2x icon-spinner icon-spin";
var serverConnect = serverUrl + 'checkPersonEmail' + '/' + jUserSessionId + '/' + jClientSessionId + '/'+ $scope.person.email;
$http.get(serverConnect).success(function(data, status) {
// alert(JSON.stringify(data));
if (data == "true") {
$scope.spinnerClass = "icon-hide";
$scope.msgClass = "text-success icon-ok";
$scope.message = "Available";
} else {
$scope.spinnerClass = "icon-hide";
$scope.msgClass = "text-error icon-remove";
$scope.message = "Not Available";
}
}).error(function(data, status) {
alert("Failure");
});
}
}
Whenever this checkEmail is called it is a HTTP Bad request(400).
Could be because you have two jClientSessionId and no jUserSessionId in the #RequestMapping ({jClientSessionId}/{jClientSessionId})?
You need to put #ResponseBody annotation on your checkName method, if your controller is not annotated as #RestController.

Use servlet filter to remove a form parameter from posted data

A vendor has been posting XML data over HTTPS within a form variable named XMLContent to my Coldfusion application server. I recently moved to a more recent version of the application server and those requests are throwing 500 server errors. It is throwing the error because a second form parameter's content is not properly urlencoded, but I don't need that parameter anyway. (I contacted the vendor to fix this but they are forcing me to pay to fix their mistake so I'm looking to fix it myself if possible.)
How would I utilize a servlet filter to remove all but the form parameter named: XMLContent
I have tried various attempts to explicitly remove the offending parameter "TContent" but it never gets removed.
A snippet of the data being received:
XMLContent=%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%0A%3CCheck+xmlns%3D%22http .........&TContent=<!--?xml version="1.0" encoding="UTF-8"?--><check xmlns="http...........
The code I've tried:
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.*;
public class MultipartFilter implements Filter {
// Init ----------------------------------------------------------------
public FilterConfig filterConfig;
// Actions -------------------------------------------------------------
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
/**
* Check the type request and if it is a HttpServletRequest, then parse the request.
* #throws ServletException If parsing of the given HttpServletRequest fails.
* #see javax.servlet.Filter#doFilter(
* javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws ServletException, IOException
{
// Check type request.
if (request instanceof HttpServletRequest) {
// Cast back to HttpServletRequest.
HttpServletRequest httpRequest = (HttpServletRequest) request;
// Parse HttpServletRequest.
HttpServletRequest parsedRequest = parseRequest(httpRequest);
// Continue with filter chain.
chain.doFilter(parsedRequest, response);
} else {
// Not a HttpServletRequest.
chain.doFilter(request, response);
}
}
/**
* #see javax.servlet.Filter#destroy()
*/
public void destroy() {
this.filterConfig = null;
}
private HttpServletRequest parseRequest(HttpServletRequest request) throws ServletException {
// Prepare the request parameter map.
Map<String, String[]> parameterMap = new HashMap<String, String[]>();
// Loop through form parameters.
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String paramName = parameterNames.nextElement();
String[] paramValues = request.getParameterValues(paramName);
// Add just the XMLContent form parameter
if (paramName.equalsIgnoreCase("xmlcontent")) {
parameterMap.put(paramName, new String[] { paramValues[0] });
}
}
// Wrap the request with the parameter map which we just created and return it.
return wrapRequest(request, parameterMap);
}
// Utility (may be refactored to public utility class) ---------------
/**
* Wrap the given HttpServletRequest with the given parameterMap.
* #param request The HttpServletRequest of which the given parameterMap have to be wrapped in.
* #param parameterMap The parameterMap to be wrapped in the given HttpServletRequest.
* #return The HttpServletRequest with the parameterMap wrapped in.
*/
private static HttpServletRequest wrapRequest(
HttpServletRequest request, final Map<String, String[]> parameterMap)
{
return new HttpServletRequestWrapper(request) {
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
public String getParameter(String name) {
String[] params = getParameterValues(name);
return params != null && params.length > 0 ? params[0] : null;
}
public Enumeration<String> getParameterNames() {
return Collections.enumeration(parameterMap.keySet());
}
};
}
}
We face these situations every day while handling locale. If user locale is different than browser locale, we have to update the request. But its not mutable.
Solution: create a request wrapper class. Copy existing request parameters (the ones you want) into it and pass this wrapper class in filterchain.doFilter()
sample wrapper class:
public class WrappedRequest extends HttpServletRequestWrapper
{
Map<String, String[]> parameterMap;
public WrappedRequest(final HttpServletRequest request)
{
//build your param Map here with required values
}
#Override
public Map<String, String[]> getParameterMap()
{
//return local param map
}
//override other methods if needed.
}
Now in your filter code, do following.
wrapRequest = new WrappedRequest(hreq);
filterChain.doFilter(wrapRequest, servletResponse);
Hopefully it will solve your problem.
Approach
The code follows the correct approach:
in wrapRequest(), it instantiates HttpServletRequestWrapper and overrides the 4 methods that trigger request parsing:
public String getParameter(String name)
public Map<String, String[]> getParameterMap()
public Enumeration<String> getParameterNames()
public String[] getParameterValues(String name)
the doFilter() method invokes the filter chain using the wrapped request, meaning subsequent filters, plus the target servlet (URL-mapped) will be supplied the wrapped request.
Problem
Calling any of the 4 methods getParameterXXX() methods on the underlying 'original request' triggers implicit parsing of all request parameters (via a server internal method such as Request.parseRequestParameters or parsePameters). These 4 methods are the only way to trigger such parsing.
Before the request is wrapped, in parseRequest(), your code calls such methods on the underlying request:
request.getParameterNames();
request.getParameterValues(paramName);
Solution
You need to control the parsing logic. Reading raw bytes from the input stream and doing your own URL decoding is too complex - it would mean replacing a large volume of tightly-coupled server code. Instead, the simplest approach is to just replace the method that does the actual URL decoding. That means you can leave in place the request.getParameterXXX calls mentioned in prev section.
Not sure what server you're hosting ColdFusion on, but following description is based on Glassfish/Tomcat, but can be adapted. At the bottom of this post is the internal request parsing method from Glassfish (a modified version of Tomcat). JD-decompiler is useful for this tinkering for converting .class files to .java.
Find the class that does URL decoding (for Glassfish this is com.sun.grizzly.util.http.Parameters from grizzly-utils.jar as shown below, for Tomcat this is org.apache.tomcat.util.http.Parameters from tomcat-coyote.jar)
Copy the entire source code to a new class somepackage.StrippedParameters
Find the line of code that decodes the parameter value (below: value = urlDecode(this.tmpValue))
Change this code so that it only decodes when the parameter name matches your desired parameter:
if (decodeName)
name = urlDecode(this.tmpName);
else
name = this.tmpName.toString();
//
// !! THIS IF STATEMENT ADDED TO ONLY DECODE DESIRED PARAMETERS,
// !! OTHERS ARE STRIPPED:
//
if ("XMLContent".equals(name)) {
String value;
String value;
if (decodeValue)
value = urlDecode(this.tmpValue);
else {
value = this.tmpValue.toString();
}
try
{
addParameter(name, value);
}
catch (IllegalStateException ise)
{
logger.warning(ise.getMessage());
break;
}
}
Now the tricky part: replace the default class Parameters with your class StrippedParmeters just before URL decoding occurs. Once the parameters are obtained, copy them back to the container class. For Glassfish copy the method parseRequestParameters into your implementation of HttpServletRequestWrapper (for Tomcat, the corresponding method is parseParameters in class org.apache.catalina.connector.Request in catalina.jar)
replace this line:
Parameters parameters = this.coyoteRequest.getParameters();
with:
Parameters parameters = new somepackage.StrippedParameters();
at the bottom of the method, add this:
Parameters coyoteParameters = this.coyoteRequest.getParameters();
for (String paramName : parameters.getParameterNames()) {
String paramValue = parameters.getParameterValue(paramName);
coyoteParameters.addParameter(paramName, paramValue);
}
Glassfish Container Code - Modified Version of Tomcat, with Grizzly replacing Coyote
(Catalina Servlet Engine still refers to Coyote objects, but they are Grizzly instances mocked like Coyote)
package org.apache.catalina.connector;
....
public class Request implements HttpRequest, HttpServletRequest {
....
protected com.sun.grizzly.tcp.Request coyoteRequest;
....
// This is called from the 4 methods named 'getParameterXXX'
protected void parseRequestParameters() {
Parameters parameters = this.coyoteRequest.getParameters();
parameters.setLimit(getConnector().getMaxParameterCount());
String enc = getCharacterEncoding();
this.requestParametersParsed = true;
if (enc != null) {
parameters.setEncoding(enc);
parameters.setQueryStringEncoding(enc);
} else {
parameters.setEncoding("ISO-8859-1");
parameters.setQueryStringEncoding("ISO-8859-1");
}
parameters.handleQueryParameters();
if ((this.usingInputStream) || (this.usingReader)) {
return;
}
if (!getMethod().equalsIgnoreCase("POST")) {
return;
}
String contentType = getContentType();
if (contentType == null) {
contentType = "";
}
int semicolon = contentType.indexOf(';');
if (semicolon >= 0)
contentType = contentType.substring(0, semicolon).trim();
else {
contentType = contentType.trim();
}
if ((isMultipartConfigured()) && ("multipart/form-data".equals(contentType))) {
getMultipart().init();
}
if (!"application/x-www-form-urlencoded".equals(contentType)) {
return;
}
int len = getContentLength();
if (len > 0) {
int maxPostSize = ((Connector)this.connector).getMaxPostSize();
if ((maxPostSize > 0) && (len > maxPostSize)) {
log(sm.getString("coyoteRequest.postTooLarge"));
throw new IllegalStateException("Post too large");
}
try {
byte[] formData = getPostBody();
if (formData != null)
parameters.processParameters(formData, 0, len);
} catch (Throwable t) {
}
}
}
}
package com.sun.grizzly.tcp;
import com.sun.grizzly.util.http.Parameters;
public class Request {
....
private Parameters parameters = new Parameters();
....
public Parameters getParameters() {
return this.parameters;
}
}
package com.sun.grizzly.util.http;
public class Parameters {
....
public void processParameters(byte[] bytes, int start, int len) {
processParameters(bytes, start, len, getCharset(this.encoding));
}
public void processParameters(byte[] bytes, int start, int len, Charset charset) {
if (debug > 0) {
try {
log(sm.getString("parameters.bytes", new String(bytes, start, len, "ISO-8859-1")));
} catch (UnsupportedEncodingException e) {
logger.log(Level.SEVERE, sm.getString("parameters.convertBytesFail"), e);
}
}
int decodeFailCount = 0;
int end = start + len;
int pos = start;
while (pos < end) {
int nameStart = pos;
int nameEnd = -1;
int valueStart = -1;
int valueEnd = -1;
boolean parsingName = true;
boolean decodeName = false;
boolean decodeValue = false;
boolean parameterComplete = false;
do {
switch (bytes[pos]) {
case 61:
if (parsingName) {
nameEnd = pos;
parsingName = false;
pos++; valueStart = pos;
} else {
pos++;
}
break;
case 38:
if (parsingName) {
nameEnd = pos;
} else {
valueEnd = pos;
}
parameterComplete = true;
pos++;
break;
case 37:
case 43:
if (parsingName)
decodeName = true;
else {
decodeValue = true;
}
pos++;
break;
default:
pos++;
}
} while ((!parameterComplete) && (pos < end));
if (pos == end) {
if (nameEnd == -1)
nameEnd = pos;
else if ((valueStart > -1) && (valueEnd == -1)) {
valueEnd = pos;
}
}
if ((debug > 0) && (valueStart == -1)) {
try {
log(sm.getString("parameters.noequal", Integer.valueOf(nameStart),
Integer.valueOf(nameEnd),
new String(bytes, nameStart, nameEnd - nameStart, "ISO-8859-1")));
} catch (UnsupportedEncodingException e) {
logger.log(Level.SEVERE, sm.getString("parameters.convertBytesFail"), e);
}
}
if (nameEnd <= nameStart) {
if (logger.isLoggable(Level.INFO)) {
if (valueEnd >= nameStart)
try {
new String(bytes, nameStart, valueEnd - nameStart, "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
logger.log(Level.SEVERE,
sm.getString("parameters.convertBytesFail"), e);
} else {
logger.fine(sm.getString("parameters.invalidChunk",
Integer.valueOf(nameStart), Integer.valueOf(nameEnd), null));
}
}
} else {
this.tmpName.setCharset(charset);
this.tmpValue.setCharset(charset);
this.tmpName.setBytes(bytes, nameStart, nameEnd - nameStart);
this.tmpValue.setBytes(bytes, valueStart, valueEnd - valueStart);
if (debug > 0)
try {
this.origName.append(bytes, nameStart, nameEnd - nameStart);
this.origValue.append(bytes, valueStart, valueEnd - valueStart);
}
catch (IOException ioe) {
logger.log(Level.SEVERE, sm.getString("parameters.copyFail"), ioe);
}
try
{
String name;
String name;
if (decodeName)
name = urlDecode(this.tmpName);
else
name = this.tmpName.toString();
String value;
String value;
if (decodeValue)
value = urlDecode(this.tmpValue);
else {
value = this.tmpValue.toString();
}
try
{
addParameter(name, value);
}
catch (IllegalStateException ise)
{
logger.warning(ise.getMessage());
break;
}
} catch (IOException e) {
decodeFailCount++;
if ((decodeFailCount == 1) || (debug > 0)) {
if (debug > 0) {
log(sm.getString("parameters.decodeFail.debug", this.origName.toString(), this.origValue.toString()), e);
}
else if (logger.isLoggable(Level.INFO)) {
logger.log(Level.INFO, sm.getString("parameters.decodeFail.info", this.tmpName.toString(), this.tmpValue.toString()), e);
}
}
}
this.tmpName.recycle();
this.tmpValue.recycle();
if (debug > 0) {
this.origName.recycle();
this.origValue.recycle();
}
}
}
if ((decodeFailCount > 1) && (debug <= 0))
logger.info(sm.getString("parameters.multipleDecodingFail", Integer.valueOf(decodeFailCount)));
}

Categories

Resources