if the directory the file should be written is not existing, it is created now
[mir.git] / source / mircoders / servlet / ServletModuleUploadedMedia.java
index f9ebde3..fd66221 100755 (executable)
@@ -7,7 +7,7 @@ import mir.media.MediaHelper;
 import mir.media.MirMedia;
 import mir.media.MirMediaException;
 import mir.media.MirMediaUserException;
-import mir.misc.FileUtil;
+import mir.misc.MirConfig;
 import mir.misc.MpRequest;
 import mir.misc.StringUtil;
 import mir.misc.WebdbMultipartRequest;
@@ -24,6 +24,8 @@ import mircoders.storage.DatabaseMediafolder;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import javax.servlet.ServletContext;
+
 import java.io.IOException;
 import java.net.URLEncoder;
 import java.util.GregorianCalendar;
@@ -70,20 +72,33 @@ public abstract class ServletModuleUploadedMedia
       if (contentType.equals("text/plain") ||
               contentType.equals("application/octet-stream")) {
         /**
-         * This is just a temporary way to get the content-type via
-         * the .extension , we could maybe use a magic method, by looking
-         * at the header (first few bytes) of the file. (like the file(1)
-         * command).
-         * The Oreilly method  relies on the content-type that the client
-         * browser sends and that sometimes is application-octet stream with
+         * Fallback to finding the mime-type through the standard ServletApi
+         * ServletContext getMimeType() method.
+         *
+         * This is a way to get the content-type via the .extension,
+         * we could maybe use a magic method as an additional method of
+         * figuring out the content-type, by looking at the header (first
+         * few bytes) of the file. (like the file(1) command). We could 
+         * also call the "file" command through Runtime. This is an
+         * option that I almost prefer as it is already implemented and
+         * exists with an up-to-date map on most modern Unix like systems.
+         * I haven't found a really nice implementation of the magic method
+         * in pure java yet.
+         *
+         * The first method we try thought is the "Oreilly method". It
+         * relies on the content-type that the client browser sends and 
+         * that sometimes is application-octet stream with
          * broken/mis-configured browsers.
          *
-         * The map file should be Mir/content-types.properties, it's the
-         * default Sun Java file with some additional entries that it did
-         * not have. So if you support a new media type you have to make
-         * sure that it is in this file -mh
+         * The map file we use for the extensions is the standard web-app
+         * deployment descriptor file (web.xml). See Mir's web.xml or see
+         * your Servlet containers (most likely Tomcat) documentation.
+         * So if you support a new media type you have to make sure that 
+         * it is in this file -mh
          */
-        contentType = FileUtil.guessContentTypeFromName(fileName);
+        ServletContext ctx =
+          (ServletContext)MirConfig.getPropAsObject("ServletContext");
+        contentType = ctx.getMimeType(fileName);
         if (contentType == null)
           contentType = "text/plain"; // rfc1867 says this is the default
       }
@@ -91,8 +106,7 @@ public abstract class ServletModuleUploadedMedia
 
       if (contentType.equals("text/plain") ||
               contentType.equals("application/octet-stream")) {
-        throw new ServletModuleUserException(
-                "One or more files of unrecognized types");
+        _throwBadContentType(fileName, contentType);
       }
 
       parameters.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
@@ -110,24 +124,29 @@ public abstract class ServletModuleUploadedMedia
       // if we didn't find an entry matching the
       // content-type in the table.
       if (mediaTypesList.size() == 0) {
-        theLog.printDebugInfo("Wrong file type uploaded!: " + fileName);
-        throw new MirMediaUserException("One or more files of unrecognized type");
+        _throwBadContentType(fileName, contentType);
       }
       Entity mediaType = null;
+      Entity mediaType2 = null;
 
       // find out if we an exact content-type match if so take it.
-      // otherwise just use the first one.
+      // otherwise try to match majortype/*
       // @todo this should probably be moved to DatabaseMediaType -mh
-      for (int j = 0; j < mediaTypesList.size(); j++) {
-        theLog.printDebugInfo("mediaTypesList: "+mediaTypesList.size());
-                               if (contentType.equals(
-                mediaTypesList.elementAt(j).getValue("mime_type")))
+      for(int j=0;j<mediaTypesList.size();j++) {
+        if(contentType.equals(
+                        mediaTypesList.elementAt(j).getValue("mime_type")))
           mediaType = mediaTypesList.elementAt(j);
+        else if ((mediaTypesList.elementAt(j).getValue("mime_type")).equals(
+                  contentTypeSplit[0]+"/*"))
+          mediaType2= mediaTypesList.elementAt(j); 
+      }
+
+      if ( (mediaType == null) && (mediaType2 == null) ) {
+        _throwBadContentType(fileName, contentType);
       }
+      else if( (mediaType == null) && (mediaType2 != null) )
+        mediaType = mediaType2;
 
-      // if no exact match, whatever foo/* might match
-      if (mediaType == null)
-        mediaType = mediaTypesList.elementAt(0);
 
       // get the class names from the media_type table.
       mediaTypeId = mediaType.getId();
@@ -184,10 +203,6 @@ public abstract class ServletModuleUploadedMedia
       throw new ServletModuleException(
               "upload -- media handling exception " + e.toString());
     }
-    catch (MirMediaUserException e) {
-      throw new ServletModuleUserException(
-              e.getMsg());
-    }
     catch (IOException e) {
       throw new ServletModuleException("upload -- ioexception " + e.toString());
     }
@@ -197,6 +212,18 @@ public abstract class ServletModuleUploadedMedia
 
   }
 
+  private void _throwBadContentType (String fileName, String contentType)
+    throws ServletModuleUserException {
+
+    theLog.printDebugInfo("Wrong file type uploaded!: " + fileName+" "
+                          +contentType);
+    throw new ServletModuleUserException("The file you uploaded is of the "
+        +"following mime-type: "+contentType
+        +", we do not support this mime-type. "
+        +"Error One or more files of unrecognized type. Sorry");
+  }
+
   public void update(HttpServletRequest req, HttpServletResponse res) throws ServletModuleException {
 
     try {