RFC2047Utilities.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.utils.transport.http;

  21. import java.util.List;

  22. import javax.mail.internet.MimeUtility;

  23. import org.apache.logging.log4j.Level;
  24. import org.openspcoop2.utils.LoggerWrapperFactory;
  25. import org.openspcoop2.utils.UtilsException;
  26. import org.openspcoop2.utils.resources.Charset;
  27. import org.slf4j.Logger;

  28. /**
  29. * RFC2047Utilities
  30. *
  31. * @author Andrea Poli (apoli@link.it)
  32. * @author $Author$
  33. * @version $Rev$, $Date$
  34. */

  35. public class RFC2047Utilities {

  36.     public static void main(String[] args) throws Exception {
  37.         test();
  38.     }
  39.    
  40.     private static Logger log = null;
  41.    
  42.     private static void initLogger() {
  43.         LoggerWrapperFactory.setDefaultConsoleLogConfiguration(Level.ALL);
  44.         log = LoggerWrapperFactory.getLogger(RFC2047Utilities.class);
  45.     }
  46.    
  47.     private static void logInfo(String msg) {
  48.         log.info(msg);
  49.     }
  50.    
  51.     private static final String VALORE_DIVERSO_ATTESO = "Riscontrato valore diverso da quello atteso";
  52.     private static final String VALORE_DIVERSO_SORGENTE = "Valore decodificato diverso dal sorgente";
  53.     private static final String ENCODED_IN = "] encoded in RFC2047(";
  54.     private static final String DECODE = "Decode: ";
  55.    
  56.     public static void test() throws UtilsException {
  57.        
  58.         initLogger();
  59.        
  60.         // Test String con caratteri appartenenti all'ISO ISO_8859_1
  61.         String stringIso88591 = "für psychisch";
  62.         String stringUsAscii = "fur psychisch";
  63.         String stringLunga = "Non è possibile inviare un header con questi/caratteri nella richiesta";
  64.        
  65.         boolean v = isAllCharactersInCharset(stringIso88591, Charset.ISO_8859_1);
  66.         logInfo("IS ["+stringIso88591+"] in CHARSET ISO_8859_1 ?: "+v);
  67.         if(!v) {
  68.             throw new UtilsException(VALORE_DIVERSO_ATTESO);
  69.         }
  70.        
  71.         v = isAllCharactersInCharset(stringIso88591, Charset.US_ASCII);
  72.         logInfo("IS ["+stringIso88591+"] in CHARSET US_ASCII ?: "+v);
  73.         if(v) {
  74.             throw new UtilsException(VALORE_DIVERSO_ATTESO);
  75.         }
  76.        
  77.         v = isAllCharactersInCharset(stringUsAscii, Charset.ISO_8859_1);
  78.         logInfo("IS ["+stringUsAscii+"] in CHARSET ISO_8859_1 ?: "+v);
  79.         if(!v) {
  80.             throw new UtilsException(VALORE_DIVERSO_ATTESO);
  81.         }
  82.        
  83.         v = isAllCharactersInCharset(stringUsAscii, Charset.US_ASCII);
  84.         logInfo("IS ["+stringUsAscii+"] in CHARSET US_ASCII ?: "+v);
  85.         if(!v) {
  86.             throw new UtilsException(VALORE_DIVERSO_ATTESO);
  87.         }
  88.        
  89.         logInfo("\n*** RFC2047 ISO_8859_1 B ***");
  90.         String varRFC2047ISO88591B = encode(stringIso88591, Charset.ISO_8859_1, RFC2047Encoding.B);
  91.         logInfo("["+stringIso88591+ENCODED_IN+Charset.ISO_8859_1+","+RFC2047Encoding.B+"): "+varRFC2047ISO88591B);
  92.         String decode = decode(varRFC2047ISO88591B);
  93.         logInfo(DECODE+decode);
  94.         if(!stringIso88591.equals(decode)) {
  95.             throw new UtilsException(VALORE_DIVERSO_SORGENTE);
  96.         }
  97.        
  98.         logInfo("\n*** RFC2047 ISO_8859_1 Q ***");
  99.         String varRFC2047ISO88591Q = encode(stringIso88591, Charset.ISO_8859_1, RFC2047Encoding.Q);
  100.         logInfo("["+stringIso88591+ENCODED_IN+Charset.ISO_8859_1+","+RFC2047Encoding.Q+"): "+varRFC2047ISO88591Q);
  101.         decode = decode(varRFC2047ISO88591Q);
  102.         logInfo(DECODE+decode);
  103.         if(!stringIso88591.equals(decode)) {
  104.             throw new UtilsException(VALORE_DIVERSO_SORGENTE);
  105.         }
  106.        
  107.         logInfo("\n*** RFC2047 US_ASCII B ***");
  108.         String varRFC2047USASCIIB = encode(stringIso88591, Charset.US_ASCII, RFC2047Encoding.B);
  109.         logInfo("["+stringIso88591+ENCODED_IN+Charset.US_ASCII+","+RFC2047Encoding.B+"): "+varRFC2047USASCIIB);
  110.         decode = decode(varRFC2047USASCIIB);
  111.         logInfo(DECODE+decode);
  112.         if(!stringIso88591.equals(decode)) {
  113.             throw new UtilsException(VALORE_DIVERSO_SORGENTE);
  114.         }
  115.        
  116.         logInfo("\n*** RFC2047 US_ASCII Q ***");
  117.         String varRFC2047USASCIIQ = encode(stringIso88591, Charset.US_ASCII, RFC2047Encoding.Q);
  118.         logInfo("["+stringIso88591+ENCODED_IN+Charset.US_ASCII+","+RFC2047Encoding.Q+"): "+varRFC2047USASCIIQ);
  119.         decode = decode(varRFC2047USASCIIQ);
  120.         logInfo(DECODE+decode);
  121.         if(!stringIso88591.equals(decode)) {
  122.             throw new UtilsException(VALORE_DIVERSO_SORGENTE);
  123.         }
  124.        
  125.         logInfo("\n*** RFC2047 US_ASCII B (stringa lunga) ***");
  126.         varRFC2047USASCIIB = encode(stringLunga, Charset.US_ASCII, RFC2047Encoding.B);
  127.         logInfo("["+stringLunga+ENCODED_IN+Charset.US_ASCII+","+RFC2047Encoding.B+"): "+varRFC2047USASCIIB);
  128.         decode = decode(varRFC2047USASCIIB);
  129.         logInfo(DECODE+decode);
  130.         if(!stringLunga.equals(decode)) {
  131.             throw new UtilsException(VALORE_DIVERSO_SORGENTE);
  132.         }
  133.        
  134.         logInfo("\n*** RFC2047 US_ASCII Q (stringa lunga) ***");
  135.         varRFC2047USASCIIQ = encode(stringLunga, Charset.US_ASCII, RFC2047Encoding.Q);
  136.         logInfo("["+stringLunga+ENCODED_IN+Charset.US_ASCII+","+RFC2047Encoding.Q+"): "+varRFC2047USASCIIQ);
  137.         decode = decode(varRFC2047USASCIIQ);
  138.         logInfo(DECODE+decode);
  139.         if(!stringLunga.equals(decode)) {
  140.             throw new UtilsException(VALORE_DIVERSO_SORGENTE);
  141.         }
  142.     }
  143.    
  144.     public static String encode(String value,Charset charset,RFC2047Encoding encoding) throws UtilsException{
  145.         try{
  146.             return MimeUtility.encodeWord(value,charset.getValue(),encoding.name());
  147.         }catch(Exception e){
  148.             throw new UtilsException(e.getMessage(),e);
  149.         }
  150.     }
  151.    
  152.     public static String decode(String value) throws UtilsException{
  153.         try{
  154.             return MimeUtility.decodeText(value);
  155.         }catch(Exception e){
  156.             throw new UtilsException(e.getMessage(),e);
  157.         }
  158.     }
  159.    
  160.     public static boolean isAllCharactersInCharset(String value,Charset charset) throws UtilsException{
  161.         try{
  162.             java.nio.charset.CharsetEncoder encoder =
  163.                     java.nio.charset.Charset.forName(charset.getValue()).newEncoder();
  164.             return encoder.canEncode(value);
  165.         }catch(Exception e){
  166.             throw new UtilsException(e.getMessage(),e);
  167.         }
  168.     }
  169.    
  170.    
  171.    
  172.     public static void validHeader(String key, List<String> values) throws UtilsException{
  173.         if(values!=null && !values.isEmpty()) {
  174.             for (String value : values) {
  175.                 validHeader(key, value);
  176.             }
  177.         }
  178.     }
  179.     public static void validHeader(String key, String value) throws UtilsException{
  180.        
  181.         // jdk/openjdk/6-b14/sun/net/www/protocol/http/HttpURLConnection.java
  182.        
  183.         char lf = '\n';
  184.         int index = key.indexOf(lf);
  185.         if (index != -1) {
  186.             throw new UtilsException("Found illegal character(s) in message header field ["+key+"]");
  187.         }
  188.         else {
  189.             if (value == null) {
  190.                 return;
  191.             }

  192.             index = value.indexOf(lf);
  193.             while (index != -1) {
  194.                 index++;
  195.                 if (index < value.length()) {
  196.                     char c = value.charAt(index);
  197.                     if ((c==' ') || (c=='\t')) {
  198.                         // ok, check the next occurrence
  199.                         index = value.indexOf(lf, index);
  200.                         continue;
  201.                     }
  202.                 }
  203.                 throw new UtilsException("Found Illegal character(s) in message header ["+key+"]. Found value: ["+value+"]");
  204.             }
  205.         }
  206.     }
  207. }