View Javadoc

1   /*
2    * $Id: StaticResourceMessageProcessor.java 22547 2011-07-24 03:15:16Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  package org.mule.transport.http.components;
11  
12  import org.mule.DefaultMuleEvent;
13  import org.mule.DefaultMuleMessage;
14  import org.mule.api.MuleEvent;
15  import org.mule.api.MuleException;
16  import org.mule.api.config.ConfigurationException;
17  import org.mule.api.lifecycle.Initialisable;
18  import org.mule.api.lifecycle.InitialisationException;
19  import org.mule.api.processor.MessageProcessor;
20  import org.mule.transport.NullPayload;
21  import org.mule.transport.http.HttpConnector;
22  import org.mule.transport.http.HttpConstants;
23  import org.mule.transport.http.i18n.HttpMessages;
24  import org.mule.util.IOUtils;
25  import org.mule.util.StringUtils;
26  
27  import java.io.ByteArrayOutputStream;
28  import java.io.File;
29  import java.io.FileInputStream;
30  import java.io.IOException;
31  import java.io.InputStream;
32  
33  import javax.activation.MimetypesFileTypeMap;
34  
35  /**
36   * A MessageProcessor that can be used by HTTP endpoints to serve static files from a directory on the
37   * filesystem.  This processor allows the user to specify a resourceBase which refers to the local directory
38   * from where files will be served from. Additionally, a default file can be specificed for URLs where no
39   * file is set
40   */
41  public class StaticResourceMessageProcessor implements MessageProcessor, Initialisable
42  {
43      public static final String DEFAULT_MIME_TYPE = "application/octet-stream";
44  
45      private String resourceBase;
46      private String defaultFile = "index.html";
47      private MimetypesFileTypeMap mimeTypes;
48  
49      public void initialise() throws InitialisationException
50      {
51          mimeTypes = new MimetypesFileTypeMap();
52          mimeTypes.addMimeTypes("text/javascript js");
53          mimeTypes.addMimeTypes("text/css css");
54      }
55  
56      public MuleEvent process(MuleEvent event) throws MuleException
57      {
58          if (StringUtils.isEmpty(resourceBase))
59          {
60              throw new ConfigurationException(HttpMessages.noResourceBaseDefined());
61          }
62  
63          String path = event.getMessage().getInboundProperty(HttpConnector.HTTP_REQUEST_PATH_PROPERTY);
64          String contextPath = event.getMessage().getInboundProperty(HttpConnector.HTTP_CONTEXT_PATH_PROPERTY);
65  
66          // Remove the contextPath from the endpoint from the request as this isn't part of the path.
67          path = path.substring(contextPath.length());
68  
69          File file = new File(resourceBase + path);
70          MuleEvent resultEvent = event;
71  
72          if (file.isDirectory() && path.endsWith("/"))
73          {
74              file = new File(resourceBase + path +  defaultFile);
75          }
76          else if (file.isDirectory())
77          {
78              // Return a 302 with the new location
79              resultEvent = new DefaultMuleEvent(new DefaultMuleMessage(NullPayload.getInstance(), event.getMuleContext()), event);
80              resultEvent.getMessage().setOutboundProperty(HttpConnector.HTTP_STATUS_PROPERTY, String.valueOf(HttpConstants.SC_MOVED_TEMPORARILY));
81              resultEvent.getMessage().setOutboundProperty(HttpConstants.HEADER_CONTENT_LENGTH, 0);
82              resultEvent.getMessage().setOutboundProperty(HttpConstants.HEADER_LOCATION,
83                      event.getMessage().getInboundProperty(HttpConnector.HTTP_REQUEST_PATH_PROPERTY) + "/");
84              return resultEvent;
85          }
86  
87  
88          InputStream in = null;
89          try
90          {
91              in = new FileInputStream(file);
92              byte[] buffer;
93  
94              if (in == null)
95              {
96                  resultEvent = new DefaultMuleEvent(new DefaultMuleMessage(NullPayload.getInstance(), event.getMuleContext()), event);
97                  resultEvent.getMessage().setOutboundProperty(HttpConnector.HTTP_STATUS_PROPERTY, String.valueOf(HttpConstants.SC_NOT_FOUND));
98                  return resultEvent;
99              }
100 
101             ByteArrayOutputStream baos = new ByteArrayOutputStream();
102             IOUtils.copyLarge(in, baos);
103 
104             buffer = baos.toByteArray();
105 
106             String mimetype = mimeTypes.getContentType(file);
107 
108             if (mimetype == null)
109             {
110                 mimetype = DEFAULT_MIME_TYPE;
111             }
112 
113             resultEvent = new DefaultMuleEvent(new DefaultMuleMessage(buffer, event.getMuleContext()), event);
114             resultEvent.getMessage().setOutboundProperty(HttpConnector.HTTP_STATUS_PROPERTY, String.valueOf(HttpConstants.SC_OK));
115             resultEvent.getMessage().setOutboundProperty(HttpConstants.HEADER_CONTENT_TYPE, mimetype);
116             resultEvent.getMessage().setOutboundProperty(HttpConstants.HEADER_CONTENT_LENGTH, buffer.length);
117 
118 
119         } catch (IOException e)
120         {
121             throw new ResourceNotFoundException(HttpMessages.fileNotFound(resourceBase + path));
122         }
123 
124 
125         return resultEvent;
126     }
127 
128     public String getResourceBase()
129     {
130         return resourceBase;
131     }
132 
133     public void setResourceBase(String resourceBase)
134     {
135         this.resourceBase = resourceBase;
136     }
137 
138     public String getDefaultFile()
139     {
140         return defaultFile;
141     }
142 
143     public void setDefaultFile(String defaultFile)
144     {
145         this.defaultFile = defaultFile;
146     }
147 }