FormUrlEncodedHttpServletRequest.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */
  20. package org.openspcoop2.pdd.services.connector;

  21. import java.io.BufferedReader;
  22. import java.io.ByteArrayInputStream;
  23. import java.io.IOException;
  24. import java.io.InputStream;
  25. import java.io.InputStreamReader;
  26. import java.util.ArrayList;
  27. import java.util.Collections;
  28. import java.util.Enumeration;
  29. import java.util.HashMap;
  30. import java.util.Iterator;
  31. import java.util.List;
  32. import java.util.Map;

  33. import javax.mail.internet.ContentType;
  34. import javax.servlet.ReadListener;
  35. import javax.servlet.ServletInputStream;
  36. import javax.servlet.http.HttpServletRequest;

  37. import org.openspcoop2.utils.Utilities;
  38. import org.openspcoop2.utils.UtilsException;
  39. import org.openspcoop2.utils.resources.Charset;
  40. import org.openspcoop2.utils.transport.TransportUtils;
  41. import org.openspcoop2.utils.transport.http.WrappedHttpServletRequest;


  42. /**
  43.  * FormUrlEncodedHttpServletRequest
  44.  *
  45.  * @author Poli Andrea (apoli@link.it)
  46.  * @author $Author$
  47.  * @version $Rev$, $Date$
  48.  */
  49. public class FormUrlEncodedHttpServletRequest extends WrappedHttpServletRequest {

  50.     /*
  51.      * NOTA: da Wilfdly 8.1 questa servlet deve essere abilitata nella configurazione:
  52.      * In the standalone/configuration/standalone.xml file change the servlet-container XML element so that it has the attribute allow-non-standard-wrappers="true".
  53.      *
  54.      *  <servlet-container name="default" allow-non-standard-wrappers="true">
  55.      *           ...
  56.      *  </servlet-container>
  57.      **/
  58.    
  59.     private static final String CONTENT_TYPE_FORM_URL_ENCODED = "application/x-www-form-urlencoded";
  60.    
  61.     public static boolean isFormUrlEncodedRequest(HttpServletRequest httpServletRequest) {
  62.         String ct = httpServletRequest.getContentType();
  63.         try {
  64.             String baseType = readBaseType(ct);
  65.             if(CONTENT_TYPE_FORM_URL_ENCODED.equalsIgnoreCase(baseType)) {
  66.                 return true;
  67.             }
  68.         }catch(Exception e) {
  69.         }
  70.         return false;
  71.     }
  72.    
  73.     public static HttpServletRequest convert(HttpServletRequest httpServletRequest) {
  74.         String ct = httpServletRequest.getContentType();
  75.         try {
  76.             String baseType = readBaseType(ct);
  77.             if(CONTENT_TYPE_FORM_URL_ENCODED.equalsIgnoreCase(baseType)) {
  78.                 return new FormUrlEncodedHttpServletRequest(httpServletRequest);
  79.             }
  80.         }catch(Exception e) {
  81.         }
  82.         return httpServletRequest;
  83.     }
  84.    
  85.     private static String readBaseType(String ct) throws UtilsException {
  86.         if(ct==null || "".equals(ct)) {
  87.             throw new UtilsException("Content-Type not defined");
  88.         }
  89.         String baseType = null;
  90.         try {
  91.             ContentType ctObject = new ContentType(ct);
  92.             baseType = ctObject.getBaseType();
  93.         }catch(Exception e) {
  94.             throw new UtilsException("Content-Type ["+ct+"] (parsing error): "+e.getMessage(),e);
  95.         }
  96.         return baseType;
  97.     }
  98.    
  99.     private byte[] content;
  100.     private Map<String, List<String>> properties;
  101.     public FormUrlEncodedHttpServletRequest(HttpServletRequest httpServletRequest) throws UtilsException{
  102.         super(httpServletRequest);
  103.        
  104.         String ct = httpServletRequest.getContentType();
  105.         String baseType = null;
  106.         try {
  107.             baseType = readBaseType(ct);
  108.         }catch(Exception e) {
  109.         }
  110.         if(CONTENT_TYPE_FORM_URL_ENCODED.equalsIgnoreCase(baseType)==false) {
  111.             throw new UtilsException("Content-Type ["+ct+"] non supportato");
  112.         }
  113.        
  114.         try {
  115.             InputStream is = httpServletRequest.getInputStream();
  116.             if(is!=null) {
  117.                 this.content = Utilities.getAsByteArray(is);
  118.             }
  119.         }catch(Exception e) {
  120.             throw new UtilsException("Content-Type ["+ct+"] read stream error: "+e.getMessage(),e);
  121.         }
  122.        
  123.         java.util.Enumeration<?> en = httpServletRequest.getParameterNames();
  124.         this.properties = new HashMap<>();
  125.         while(en.hasMoreElements()){
  126.             String nomeProperty = (String)en.nextElement();
  127.             String [] s = httpServletRequest.getParameterValues(nomeProperty);
  128.             List<String> values = new ArrayList<>();
  129.             if(s!=null && s.length>0) {
  130.                 for (int i = 0; i < s.length; i++) {
  131.                     String value = s[i];
  132.                     values.add(value);
  133.                     //logCore.info("Parameter ["+nomeProperty+"] valore-"+i+" ["+value+"]");
  134.                 }
  135.             }
  136.             else {
  137.                 //logCore.info("Parameter ["+nomeProperty+"] valore ["+req.getParameter(nomeProperty)+"]");
  138.                 values.add(httpServletRequest.getParameter(nomeProperty));
  139.             }
  140.             this.properties.put(nomeProperty, values);
  141.         }
  142.         if(this.properties.isEmpty() && this.content!=null && this.content.length>0) {
  143.             // su wildfly non vengono ritornati i parameters name
  144.                
  145.             /*
  146.              * application/x-www-form-urlencoded:
  147.              *   the keys and values are encoded in key-value tuples separated by '&', with a '=' between the key and the value.
  148.              *   Non-alphanumeric characters in both keys and values are percent encoded
  149.              **/
  150.             String contentUrlEncoding = new String(this.content);
  151.            
  152. //          StringBuilder sbProperties = new StringBuilder();
  153.             if(contentUrlEncoding.contains("&")) {
  154.                 String [] tmp = contentUrlEncoding.split("&");
  155.                 if(tmp!=null && tmp.length>0) {
  156.                     for (String pUrlEncoding : tmp) {
  157. //                      if(sbProperties.length()>0) {
  158. //                          sbProperties.append("\n");
  159. //                      }
  160.                         String contentUrlDecoding = org.springframework.web.util.UriUtils.decode( pUrlEncoding, Charset.UTF_8.getValue());
  161. //                      sbProperties.append(contentUrlDecoding);
  162.                         addParameter(contentUrlDecoding);
  163.                     }
  164.                 }
  165.             }
  166.             else {
  167.                 String contentUrlDecoding = org.springframework.web.util.UriUtils.decode( contentUrlEncoding, Charset.UTF_8.getValue());
  168. //              sbProperties.append(contentUrlDecoding);
  169.                 addParameter(contentUrlDecoding);
  170.             }
  171.            
  172.             /*
  173.             if(sbProperties.length()>0) {
  174.                 try (ByteArrayInputStream bin = new ByteArrayInputStream(sbProperties.toString().getBytes())) {
  175.                     Properties pTmp = new Properties();
  176.                     pTmp.load(bin);
  177.                     if(pTmp.size()>0) {
  178.                         Enumeration<Object> enKeys = pTmp.keys();
  179.                         while (enKeys.hasMoreElements()) {
  180.                             Object oKey = (Object) enKeys.nextElement();
  181.                             if(oKey instanceof String) {
  182.                                 String key = (String) oKey;
  183.                                 TransportUtils.addParameter(this.properties, key, pTmp.getProperty(key));
  184.                             }
  185.                         }
  186.                     }
  187.                 }catch(Throwable t) {}
  188.             }
  189.             */
  190.         }
  191.     }
  192.    
  193.     private void addParameter(String line) {
  194.         if(line!=null) {
  195.             if(line.contains("=")) {
  196.                 int indexOf = line.indexOf("=");
  197.                 if(indexOf>0 && indexOf<(line.length()-1)) {
  198.                     String key = line.substring(0, indexOf);
  199.                     String value = line.substring(indexOf+1);
  200.                     TransportUtils.addParameter(this.properties, key, value);
  201.                 }
  202.             }
  203.         }
  204.     }
  205.    
  206.     // Metodi modificati nei risultati
  207.    
  208.     @Override
  209.     public int getContentLength() {
  210.         if(this.content!=null) {
  211.             return this.content.length;
  212.         }
  213.         return 0;
  214.     }
  215.    
  216.     @Override
  217.     public String getContentType() {
  218.         return this.httpServletRequest.getContentType();
  219.     }

  220.     @Override
  221.     public ServletInputStream getInputStream() throws IOException {
  222.         if(this.content!=null) {
  223.             try {              
  224.                 return new FormUrlEncodedServletInputStream(new ByteArrayInputStream(this.content));
  225.             }catch(Exception e) {
  226.                 throw new IOException(e.getMessage(),e);
  227.             }
  228.         }
  229.         return null;
  230.     }
  231.    
  232.     @Override
  233.     public BufferedReader getReader() throws IOException {
  234.         if(this.content!=null) {
  235.             return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(this.content), this.httpServletRequest.getCharacterEncoding()));
  236.         }
  237.         return null;
  238.     }
  239.    
  240.     @Override
  241.     public String getParameter(String key) {
  242.         return null;
  243.     }

  244.     @Override
  245.     public Map<java.lang.String,java.lang.String[]> getParameterMap() {
  246.         return new HashMap<java.lang.String,java.lang.String[]>();
  247.     }

  248.     @Override
  249.     public Enumeration<String> getParameterNames() {
  250.         return Collections.emptyEnumeration();
  251.     }

  252.     @Override
  253.     public String[] getParameterValues(String arg0) {
  254.         return null;
  255.     }
  256.    
  257.     @Deprecated
  258.     public String getFormUrlEncodedParameter(String key) {
  259.         return getFormUrlEncodedParameter_compactMultipleValues(key);
  260.     }
  261.     public String getFormUrlEncodedParameter_compactMultipleValues(String key) {
  262.         return TransportUtils.getObjectAsString(this.properties, key);
  263.     }
  264.     public List<String> getFormUrlEncodedParameterValues(String key) {
  265.         return TransportUtils.getRawObject(this.properties, key);
  266.     }
  267.     public String getFormUrlEncodedParameterFirstValue(String key) {
  268.         List<String> l = TransportUtils.getRawObject(this.properties, key);
  269.         if(l!=null && !l.isEmpty()) {
  270.             return l.get(0);
  271.         }
  272.         return null;
  273.     }

  274.     public Iterator<String> getFormUrlEncodedParameterNames() {
  275.         return this.properties.keySet().iterator();
  276.     }
  277.    
  278.     public Map<String, List<String>> getFormUrlEncodedParametersValues(){
  279.         return this.properties;
  280.     }
  281. }


  282. class FormUrlEncodedServletInputStream extends ServletInputStream {

  283.     private InputStream is;
  284.     public FormUrlEncodedServletInputStream(InputStream is) {
  285.         this.is = is;
  286.     }
  287.    
  288.     @Override
  289.     public int readLine(byte[] b, int off, int len) throws IOException {
  290.         return this.is.read(b, off, len);
  291.     }

  292.     @Override
  293.     public int read() throws IOException {
  294.         return this.is.read();
  295.     }
  296.    
  297.     @Override
  298.     public int read(byte[] b) throws IOException {
  299.         return this.is.read(b);
  300.     }

  301.     @Override
  302.     public int read(byte[] b, int off, int len) throws IOException {
  303.         return this.is.read(b, off, len);
  304.     }

  305.     @Override
  306.     public long skip(long n) throws IOException {
  307.         return this.is.skip(n);
  308.     }

  309.     @Override
  310.     public int available() throws IOException {
  311.         return this.is.available();
  312.     }

  313.     @Override
  314.     public void close() throws IOException {
  315.         this.is.close();
  316.     }

  317.     @Override
  318.     public synchronized void mark(int readlimit) {
  319.         this.is.mark(readlimit);
  320.     }

  321.     @Override
  322.     public synchronized void reset() throws IOException {
  323.         this.is.reset();
  324.     }

  325.     @Override
  326.     public boolean markSupported() {
  327.         return this.is.markSupported();
  328.     }

  329.     @Override
  330.     public boolean isFinished() {
  331.         return false;
  332.     }

  333.     @Override
  334.     public boolean isReady() {
  335.         return true;
  336.     }

  337.     @Override
  338.     public void setReadListener(ReadListener arg0) {
  339.        
  340.     }


  341. }