Skip to content
Snippets Groups Projects
Commit afce5871 authored by Grégory Mantelet's avatar Grégory Mantelet
Browse files

[UWS] Fix shifted mapping for the MIME types and the file extensions (in

UWSToolBox).

_ See GitHub Issue #100 _
parent e10489b2
No related branches found
No related tags found
No related merge requests found
......@@ -2,21 +2,21 @@ package uws;
/*
* This file is part of UWSLibrary.
*
*
* UWSLibrary is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* UWSLibrary is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public License
* along with UWSLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
*
* Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
......@@ -53,9 +53,9 @@ import uws.service.request.UploadFile;
/**
* Some useful functions for the managing of a UWS service.
*
*
* @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 4.2 (09/2017)
* @version 4.3 (01/2019)
*/
public class UWSToolBox {
......@@ -78,13 +78,13 @@ public class UWSToolBox {
* <li><i>if you want the URL of the html page "basic.html" of the root directory:</i> servletPath=<b>"/basic.html"</b> => returned URL=<b>http://foo.org/uwstuto/basic.html</b></li>
* <li><i>if you want the URL of the image "ivoa.png" contained into the directory "images":</i> servletPath=<b>"/images/ivoa.png"</b> => returned URL=<b>"http://foo.org/uwstuto/images/ivoa.png"</b></li>
* </ul>
*
*
* @param serverPath The relative path to access a server resource.
* @param req A request of the servlet.
*
*
* @return The absolute URL to access the desired server resource
* or <i>null</i> if one of the parameter is <i>null</i> or if a well-formed URL can not be built.
*
*
* @see HttpServletRequest#getRequestURL()
* @see HttpServletRequest#getContextPath()
* @see URL#URL(String)
......@@ -106,7 +106,7 @@ public class UWSToolBox {
/**
* Gets the default {@link UWSLog} instance.
* Any log message will be print on the standard error output ({@link System#err}).
*
*
* @return The default {@link UWSLog} instance.
*/
public static final UWSLog getDefaultLogger(){
......@@ -120,35 +120,35 @@ public class UWSToolBox {
/* ****************** */
/**
* <p>Builds a map of strings with all parameters of the given HTTP request.</p>
*
*
* <p><i>Note:
* If the request attribute {@link UWS#REQ_ATTRIBUTE_PARAMETERS} has been already set by the UWS library,
* this map (after conversion into a Map<String,String>) is returned.
* Otherwise, the parameters identified automatically by the Servlet are returned (just the last occurrence of each parameter is kept).
* </i></p>
*
*
* <p><i><b>WARNING:</b>
* This function does not extract directly the parameters from the request content. It is just returning those already extracted
* either by the Servlet or by a {@link RequestParser}.
* </i></p>
*
*
* @param req The HTTP request which contains the parameters to extract.
*
*
* @return The corresponding map of string.
*/
@SuppressWarnings("unchecked")
public static final Map<String,String> getParamsMap(final HttpServletRequest req){
HashMap<String,String> map = new HashMap<String,String>();
public static final Map<String, String> getParamsMap(final HttpServletRequest req){
HashMap<String, String> map = new HashMap<String, String>();
/* If the attribute "PARAMETERS" has been already set by the UWS library,
* return it by casting it from Map<String,Object> into Map<String,String>: */
if (req.getAttribute(UWS.REQ_ATTRIBUTE_PARAMETERS) != null){
try{
// Get the extracted parameters:
Map<String,Object> params = (Map<String,Object>)req.getAttribute(UWS.REQ_ATTRIBUTE_PARAMETERS);
Map<String, Object> params = (Map<String, Object>)req.getAttribute(UWS.REQ_ATTRIBUTE_PARAMETERS);
// Transform the map of Objects into a map of Strings:
for(Map.Entry<String,Object> e : params.entrySet()){
for(Map.Entry<String, Object> e : params.entrySet()){
if (e.getValue() != null){
if (e.getValue().getClass().isArray()){
StringBuffer str = new StringBuffer();
......@@ -195,17 +195,17 @@ public class UWSToolBox {
/**
* Converts map of UWS parameters into a string corresponding to the query part of a HTTP-GET URL (i.e. ?EXECUTIONDURATION=60&DESTRUCTION=2010-09-01T13:58:00:000-0200).
*
*
* @param parameters A Map of parameters.
*
*
* @return The corresponding query part of an HTTP-GET URL (all keys have been set in upper case).
*/
public final static String getQueryPart(final Map<String,String> parameters){
public final static String getQueryPart(final Map<String, String> parameters){
if (parameters == null || parameters.isEmpty())
return "";
StringBuffer queryPart = new StringBuffer();
for(Map.Entry<String,String> e : parameters.entrySet()){
for(Map.Entry<String, String> e : parameters.entrySet()){
String key = e.getKey();
String val = e.getValue();
......@@ -218,7 +218,8 @@ public class UWSToolBox {
try{
queryPart.append(URLEncoder.encode(e.getKey(), "UTF-8") + "=" + URLEncoder.encode(val, "UTF-8"));
queryPart.append("&");
}catch(UnsupportedEncodingException uee){}
}catch(UnsupportedEncodingException uee){
}
}
}
......@@ -227,13 +228,13 @@ public class UWSToolBox {
/**
* Converts the given query part of a HTTP-GET URL to a map of parameters.
*
*
* @param queryPart A query part of a HTTP-GET URL.
*
*
* @return The corresponding map of parameters (all keys have been set in lower case).
*/
public final static Map<String,String> getParameters(String queryPart){
HashMap<String,String> parameters = new HashMap<String,String>();
public final static Map<String, String> getParameters(String queryPart){
HashMap<String, String> parameters = new HashMap<String, String>();
if (queryPart != null){
queryPart = queryPart.substring(queryPart.indexOf("?") + 1).trim();
......@@ -247,7 +248,8 @@ public class UWSToolBox {
if (!keyValue[0].isEmpty() && !keyValue[1].isEmpty()){
try{
parameters.put(URLDecoder.decode(keyValue[0], "UTF-8"), URLDecoder.decode(keyValue[1], "UTF-8"));
}catch(UnsupportedEncodingException uee){}
}catch(UnsupportedEncodingException uee){
}
}
}
}
......@@ -259,19 +261,19 @@ public class UWSToolBox {
/**
* <p>Extract only the GET parameters from the given HTTP request and add them inside the given map.</p>
*
*
* <p><b>Warning</b>:
* If entries with the same key already exist in the map, they will overwritten.
* </p>
*
*
* @param req The HTTP request whose the GET parameters must be extracted.
* @param parameters List of parameters to update.
*
*
* @return The same given parameters map (but updated with all found GET parameters).
*
*
* @since 4.1
*/
public static final Map<String,Object> addGETParameters(final HttpServletRequest req, final Map<String,Object> parameters){
public static final Map<String, Object> addGETParameters(final HttpServletRequest req, final Map<String, Object> parameters){
String queryString = req.getQueryString();
if (queryString != null){
String[] params = queryString.split("&");
......@@ -281,7 +283,8 @@ public class UWSToolBox {
if (indSep >= 0){
try{
parameters.put(URLDecoder.decode(p.substring(0, indSep), "UTF-8"), URLDecoder.decode(p.substring(indSep + 1), "UTF-8"));
}catch(UnsupportedEncodingException uee){}
}catch(UnsupportedEncodingException uee){
}
}
}
}
......@@ -290,11 +293,11 @@ public class UWSToolBox {
/**
* Get the number of parameters submitted in the given HTTP request.
*
*
* @param request An HTTP request;
*
*
* @return The number of submitted parameters.
*
*
* @since 4.1
*/
@SuppressWarnings("unchecked")
......@@ -302,7 +305,7 @@ public class UWSToolBox {
if (request == null)
return 0;
try{
return ((Map<String,Object>)request.getAttribute(UWS.REQ_ATTRIBUTE_PARAMETERS)).size();
return ((Map<String, Object>)request.getAttribute(UWS.REQ_ATTRIBUTE_PARAMETERS)).size();
}catch(Exception ex){
return request.getParameterMap().size();
}
......@@ -310,14 +313,14 @@ public class UWSToolBox {
/**
* Check whether a parameter has been submitted with the given name.
*
*
* @param name Name of the parameter to search. <b>The case is important!</b>
* @param request HTTP request in which the specified parameter must be searched.
* @param caseSensitive <i>true</i> to perform the research case-sensitively,
* <i>false</i> for a case INsensitive research.
*
*
* @return <i>true</i> if the specified parameter has been found, <i>false</i> otherwise.
*
*
* @since 4.1
*/
public static final boolean hasParameter(final String name, final HttpServletRequest request, final boolean caseSensitive){
......@@ -326,16 +329,16 @@ public class UWSToolBox {
/**
* Check whether the parameter specified with the given pair (name,value) exists in the given HTTP request.
*
*
* @param name Name of the parameter to search.
* @param value Expected value of the parameter.
* @param request HTTP request in which the given pair must be searched.
* @param caseSensitive <i>true</i> to perform the research (on name AND value) case-sensitively,
* <i>false</i> for a case INsensitive research.
*
*
* @return <i>true</i> if the specified parameter has been found with the given value in the given HTTP request,
* <i>false</i> otherwise.
*
*
* @since 4.1
*/
public static final boolean hasParameter(final String name, final String value, final HttpServletRequest request, final boolean caseSensitive){
......@@ -352,45 +355,46 @@ public class UWSToolBox {
/**
* Get the parameter specified by the given name from the given HTTP request.
*
*
* @param name Name of the parameter to search.
* @param request HTTP request in which the given pair must be searched.
* @param caseSensitive <i>true</i> to perform the research case-sensitively,
* <i>false</i> for a case INsensitive research.
*
*
* @return Value of the parameter.
*
*
* @since 4.1
*/
@SuppressWarnings("unchecked")
public static final Object getParameter(final String name, final HttpServletRequest request, final boolean caseSensitive){
try{
// Get the extracted parameters:
Map<String,Object> params = (Map<String,Object>)request.getAttribute(UWS.REQ_ATTRIBUTE_PARAMETERS);
Map<String, Object> params = (Map<String, Object>)request.getAttribute(UWS.REQ_ATTRIBUTE_PARAMETERS);
// Search case IN-sensitively the given pair (name, value):
for(Map.Entry<String,Object> e : params.entrySet()){
for(Map.Entry<String, Object> e : params.entrySet()){
if ((!caseSensitive && e.getKey().equalsIgnoreCase(name)) || (caseSensitive && e.getKey().equals(name)))
return (e.getValue() != null) ? e.getValue() : null;
}
}catch(Exception ex){}
}catch(Exception ex){
}
return null;
}
/**
* <p>Delete all unused uploaded files of the given request.</p>
*
*
* <p>
* These files have been stored on the file system
* if there is a request attribute named {@link UWS#REQ_ATTRIBUTE_PARAMETERS}.
* </p>
*
*
* @param req Request in which files have been uploaded.
*
*
* @return The number of deleted files.
*
*
* @see UploadFile#isUsed()
*
*
* @since 4.1
*/
@SuppressWarnings("unchecked")
......@@ -399,15 +403,16 @@ public class UWSToolBox {
Object attribute = req.getAttribute(UWS.REQ_ATTRIBUTE_PARAMETERS);
// If there is the request attribute "UWS_PARAMETERS":
if (attribute != null && attribute instanceof Map){
Map<String,Object> params = (Map<String,Object>)attribute;
Map<String, Object> params = (Map<String, Object>)attribute;
// For each parameter...
for(Map.Entry<String,Object> e : params.entrySet()){
for(Map.Entry<String, Object> e : params.entrySet()){
// ...delete physically the uploaded file ONLY IF not used AND IF it is an uploaded file:
if (e.getValue() != null && e.getValue() instanceof UploadFile && !((UploadFile)e.getValue()).isUsed()){
try{
((UploadFile)e.getValue()).deleteFile();
cnt++;
}catch(IOException ioe){}
}catch(IOException ioe){
}
}
}
}
......@@ -419,23 +424,23 @@ public class UWSToolBox {
/* *************** */
/**
* <p>Extract the user/job owner from the given HTTP request.</p>
*
*
* Two cases are supported:
* <ol>
* <li><b>The user has already been identified and is stored in the HTTP attribute {@link UWS#REQ_ATTRIBUTE_USER}</b> => the stored value is returned.</li>
* <li><b>No HTTP attribute and a {@link UserIdentifier} is provided</b> => the user is identified with the given {@link UserIdentifier} and stored in the HTTP attribute {@link UWS#REQ_ATTRIBUTE_USER} before being returned.</li>
* </ol>
*
*
* <p>In any other case, NULL is returned.</p>
*
*
* @param request The HTTP request from which the user must be extracted. <i>note: if NULL, NULL will be returned.</i>
* @param userIdentifier The method to use in order to extract a user from the given request. <i>note: if NULL, NULL is returned IF no HTTP attribute {@link UWS#REQ_ATTRIBUTE_USER} can be found.</i>
*
*
* @return The identified user. <i>MAY be NULL</i>
*
*
* @throws NullPointerException If an error occurs while extracting a {@link UWSUrl} from the given {@link HttpServletRequest}.
* @throws UWSException If any error occurs while extracting a user from the given {@link HttpServletRequest}.
*
*
* @since 4.1
*/
public static final JobOwner getUser(final HttpServletRequest request, final UserIdentifier userIdentifier) throws NullPointerException, UWSException{
......@@ -456,7 +461,7 @@ public class UWSToolBox {
/* **************************** */
/**
* Empties the specified directory.
*
*
* @param directoryPath The path of the directory to empty.
*/
public static final void clearDirectory(String directoryPath){
......@@ -465,9 +470,9 @@ public class UWSToolBox {
/**
* <p>Empties the specified directory.</p>
*
*
* <p><i><u>Note:</u> The directory is NOT deleted. Just its content is destroyed.</i></p>
*
*
* @param directory The directory which has to be emptied.
*/
public static final void clearDirectory(File directory){
......@@ -484,19 +489,19 @@ public class UWSToolBox {
/**
* <p>Flush the buffer of the given {@link PrintWriter}.</p>
*
*
* <p>
* This function aims to be used if the given {@link PrintWriter} has been provided by an {@link HttpServletResponse}.
* In such case, a call to its flush() function may generate a silent error which could only mean that
* the connection with the HTTP client has been closed.
* </p>
*
*
* @param writer The writer to flush.
*
*
* @throws ClientAbortException If the connection with the HTTP client is closed.
*
*
* @see PrintWriter#flush()
*
*
* @since 4.1
*/
public static final void flush(final PrintWriter writer) throws ClientAbortException{
......@@ -507,12 +512,12 @@ public class UWSToolBox {
/**
* Copies the content of the given input stream in the given HTTP response.
*
*
* @param input Data to copy.
* @param mimeType Type of data to copy (may be null).
* @param contentSize Size of the file to write.
* @param response Response in which the data must be copied.
*
*
* @throws IOException If there is an error while opening the output stream or while copying.
*/
public static final void write(final InputStream input, final String mimeType, final long contentSize, final HttpServletResponse response) throws IOException{
......@@ -545,14 +550,14 @@ public class UWSToolBox {
* Writes the stack trace of the given exception in the file whose the name and the parent directory are given in parameters.
* If the specified file already exists, it will be overwritten if the parameter <i>overwrite</i> is equal to <i>true</i>, otherwise
* no file will not be changed <i>(default behavior of {@link UWSToolBox#writeErrorFile(Exception, ErrorSummary, UWSJob, OutputStream)})</i>.
*
*
* @param ex The exception which has to be used to generate the error file.
* @param error The error description.
* @param job The job which ended with the given error.
* @param output The stream in which the error description and trace must be written.
*
*
* @return <i>true</i> if the file has been successfully created, <i>false</i> otherwise.
*
*
* @throws IOException If there is an error while writing the description and the stack trace of the given error.
*/
public static final boolean writeErrorFile(final Exception ex, final ErrorSummary error, final UWSJob job, final OutputStream output) throws IOException{
......@@ -573,10 +578,10 @@ public class UWSToolBox {
/**
* Prints the full stack trace of the given exception in the given writer.
*
*
* @param ex The exception whose the stack trace must be printed.
* @param pw The stream in which the stack trace must be written.
*
*
* @throws IOException If there is an error while printing the stack trace.
*/
public static final void printStackTrace(final Throwable ex, final PrintWriter pw) throws IOException{
......@@ -600,9 +605,9 @@ public class UWSToolBox {
/* *********************** */
/**
* Displays all the fields of the given UWSUrl.
*
*
* @param url The UWSUrl which has to be displayed.
*
*
* @see #printURL(UWSUrl, java.io.OutputStream)
*/
public static final void printURL(UWSUrl url){
......@@ -615,10 +620,10 @@ public class UWSToolBox {
/**
* Displays all the fields of the given UWSUrl in the given output stream.
*
*
* @param url The UWSUrl which has to be displayed.
* @param output The stream in which the fields of the given UWSUrl has to be displayed.
*
*
* @throws IOException If there is an error while writing in the given stream.
*/
public static final void printURL(UWSUrl url, java.io.OutputStream output) throws IOException{
......@@ -643,16 +648,16 @@ public class UWSToolBox {
/* MIME TYPE */
/* ********* */
/** List of file extensions whose the MIME type is known (see {@link #mimeTypes}). */
protected static final String[] fileExts = new String[]{"","vot","json","json","csv","tsv","txt","xml","xml","pdf","ai","eps","ps","html","zip","gzip","gz","tar","gif","jpeg","jpg","png","bmp"};
protected static final String[] fileExts = new String[]{ "", "vot", "json", "json", "csv", "tsv", "txt", "xml", "xml", "pdf", "ai", "eps", "ps", "html", "zip", "gzip", "gz", "tar", "gif", "jpeg", "jpg", "png", "bmp" };
/** List of known MIME types (see {@link #fileExts}). */
protected static final String[] mimeTypes = new String[]{"application/octet-stream","application/x-votable+xml","application/json","text/json","text/csv","text/tab-separated-values","text/plain","application/xml","text/xml","application/pdf","application/postscript","application/postscript","application/postscript","text/html","application/zip","application/x-gzip","application/x-tar","image/gif","image/jpeg","image/jpeg","image/png","image/x-portable-bitmap"};
protected static final String[] mimeTypes = new String[]{ "application/octet-stream", "application/x-votable+xml", "application/json", "text/json", "text/csv", "text/tab-separated-values", "text/plain", "application/xml", "text/xml", "application/pdf", "application/postscript", "application/postscript", "application/postscript", "text/html", "application/zip", "application/x-gzip", "application/x-gzip", "application/x-tar", "image/gif", "image/jpeg", "image/jpeg", "image/png", "image/x-portable-bitmap" };
/**
* Gets the MIME type corresponding to the given file extension.
*
*
* @param fileExtension File extension (i.e. .txt, json, .xml, xml, ....)
*
*
* @return The corresponding MIME type or <i>null</i> if not known.
*/
public static final String getMimeType(String fileExtension){
......@@ -672,9 +677,9 @@ public class UWSToolBox {
/**
* Gets the file extension corresponding to the given MIME type.
*
*
* @param mimeType A MIME type (i.e. text/plain, application/json, application/xml, text/xml, application/x-votable+xml, ....)
*
*
* @return The corresponding file extension or <i>null</i> if not known.
*/
public static final String getFileExtension(String mimeType){
......
package uws;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.Test;
public class TestUWSToolBox {
@Test
public void testGetMimeType(){
// TEST: NULL => NULL
assertNull(UWSToolBox.getMimeType(null));
// TEST: empty string => binary
assertEquals("application/octet-stream", UWSToolBox.getMimeType(""));
assertEquals("application/octet-stream", UWSToolBox.getMimeType(" "));
/*
* Note: each test is also performed with the file name and file
* extension separator(.).
*/
// TEST: unknown file extension => NULL
assertNull(UWSToolBox.getMimeType("foo"));
assertNull(UWSToolBox.getMimeType(".foo"));
/* Ensure length of known MIME types and file extensions have the same
* number of items: */
assertEquals(UWSToolBox.fileExts.length, UWSToolBox.mimeTypes.length);
// Roughly check the MIME types and file extensions mapping:
String ext, mime;
/* ...1st item (i.e. binary) */
ext = UWSToolBox.fileExts[0];
mime = UWSToolBox.mimeTypes[0];
assertEquals("", ext);
assertEquals("application/octet-stream", mime);
assertEquals(mime, UWSToolBox.getMimeType(ext));
assertEquals(mime, UWSToolBox.getMimeType("." + ext));
/* ...last item (i.e. bmp) */
ext = UWSToolBox.fileExts[UWSToolBox.fileExts.length - 1];
mime = UWSToolBox.mimeTypes[UWSToolBox.mimeTypes.length - 1];
assertEquals("bmp", ext);
assertEquals("image/x-portable-bitmap", mime);
assertEquals(mime, UWSToolBox.getMimeType(ext));
assertEquals(mime, UWSToolBox.getMimeType("." + ext));
// TEST: VOTable mapping => ok
assertEquals("application/x-votable+xml", UWSToolBox.getMimeType("vot"));
assertEquals("application/x-votable+xml", UWSToolBox.getMimeType(".vot"));
// Ensure it is not not case sensitive:
assertEquals("application/x-votable+xml", UWSToolBox.getMimeType(".VOt"));
}
@Test
public void testGetFileExtension(){
// TEST: NULL => NULL
assertNull(UWSToolBox.getFileExtension(null));
// TEST: empty string => NULL
assertNull(UWSToolBox.getFileExtension(""));
assertNull(UWSToolBox.getFileExtension(" "));
// TEST: unknown MIME type => NULL
assertNull(UWSToolBox.getMimeType("foo"));
/* Ensure length of known MIME types and file extensions have the same
* number of items: */
assertEquals(UWSToolBox.mimeTypes.length, UWSToolBox.fileExts.length);
// Roughly check the MIME types and file extensions mapping:
String ext, mime;
/* ...1st item (i.e. binary) */
mime = UWSToolBox.mimeTypes[0];
ext = UWSToolBox.fileExts[0];
assertEquals("application/octet-stream", mime);
assertEquals("", ext);
assertEquals(ext, UWSToolBox.getFileExtension(mime));
/* ...last item (i.e. bmp) */
mime = UWSToolBox.mimeTypes[UWSToolBox.mimeTypes.length - 1];
ext = UWSToolBox.fileExts[UWSToolBox.fileExts.length - 1];
assertEquals("image/x-portable-bitmap", mime);
assertEquals("bmp", ext);
assertEquals(ext, UWSToolBox.getFileExtension(mime));
// TEST: VOTable mapping => ok
assertEquals("vot", UWSToolBox.getFileExtension("application/x-votable+xml"));
// Ensure it is not not case sensitive:
assertEquals("vot", UWSToolBox.getFileExtension("application/x-VOTable+XML"));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment