mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
GUAC-587: Implement support for serving of arbitrary resources.
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.net.basic.resource;
|
||||
|
||||
/**
|
||||
* Base abstract resource implementation which provides an associated mimetype,
|
||||
* and modification time. Classes which extend AbstractResource must provide
|
||||
* their own InputStream, however.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public abstract class AbstractResource implements Resource {
|
||||
|
||||
/**
|
||||
* The mimetype of this resource.
|
||||
*/
|
||||
private final String mimetype;
|
||||
|
||||
/**
|
||||
* The time this resource was last modified, in milliseconds since midnight
|
||||
* of January 1, 1970 UTC.
|
||||
*/
|
||||
private final long lastModified;
|
||||
|
||||
/**
|
||||
* Initializes this AbstractResource with the given mimetype and
|
||||
* modification time.
|
||||
*
|
||||
* @param mimetype
|
||||
* The mimetype of this resource.
|
||||
*
|
||||
* @param lastModified
|
||||
* The time this resource was last modified, in milliseconds since
|
||||
* midnight of January 1, 1970 UTC.
|
||||
*/
|
||||
public AbstractResource(String mimetype, long lastModified) {
|
||||
this.mimetype = mimetype;
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this AbstractResource with the given mimetype. The
|
||||
* modification time of the resource is set to the current system time.
|
||||
*
|
||||
* @param mimetype
|
||||
* The mimetype of this resource.
|
||||
*/
|
||||
public AbstractResource(String mimetype) {
|
||||
this(mimetype, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMimeType() {
|
||||
return mimetype;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.net.basic.resource;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* A resource which is located within the classpath of an arbitrary
|
||||
* ClassLoader.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ClassPathResource extends AbstractResource {
|
||||
|
||||
/**
|
||||
* The classloader to use when reading this resource.
|
||||
*/
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
/**
|
||||
* The path of this resource relative to the classloader.
|
||||
*/
|
||||
private final String path;
|
||||
|
||||
/**
|
||||
* Creates a new ClassPathResource which uses the given ClassLoader to
|
||||
* read the resource having the given path.
|
||||
*
|
||||
* @param classLoader
|
||||
* The ClassLoader to use when reading the resource.
|
||||
*
|
||||
* @param mimetype
|
||||
* The mimetype of the resource.
|
||||
*
|
||||
* @param path
|
||||
* The path of the resource relative to the given ClassLoader.
|
||||
*/
|
||||
public ClassPathResource(ClassLoader classLoader, String mimetype, String path) {
|
||||
super(mimetype);
|
||||
this.classLoader = classLoader;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ClassPathResource which uses the ClassLoader associated
|
||||
* with the ClassPathResource class to read the resource having the given
|
||||
* path.
|
||||
*
|
||||
* @param mimetype
|
||||
* The mimetype of the resource.
|
||||
*
|
||||
* @param path
|
||||
* The path of the resource relative to the ClassLoader associated
|
||||
* with the ClassPathResource class.
|
||||
*/
|
||||
public ClassPathResource(String mimetype, String path) {
|
||||
this(ClassPathResource.class.getClassLoader(), mimetype, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream asStream() {
|
||||
return classLoader.getResourceAsStream(path);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.net.basic.resource;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* An arbitrary resource that can be served to a user via HTTP. Resources are
|
||||
* anonymous but have a defined mimetype and corresponding input stream.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface Resource {
|
||||
|
||||
/**
|
||||
* Returns the mimetype of this resource. This function MUST always return
|
||||
* a value. If the type is unknown, return "application/octet-stream".
|
||||
*
|
||||
* @return
|
||||
* The mimetype of this resource.
|
||||
*/
|
||||
String getMimeType();
|
||||
|
||||
/**
|
||||
* Returns the time the resource was last modified in milliseconds since
|
||||
* midnight of January 1, 1970 UTC.
|
||||
*
|
||||
* @return
|
||||
* The time the resource was last modified, in milliseconds.
|
||||
*/
|
||||
long getLastModified();
|
||||
|
||||
/**
|
||||
* Returns an InputStream which reads the contents of this resource,
|
||||
* starting with the first byte. Reading from the returned InputStream will
|
||||
* not affect reads from other InputStreams returned by other calls to
|
||||
* asStream(). The returned InputStream must be manually closed when no
|
||||
* longer needed. If the resource is unexpectedly unavailable, this will
|
||||
* return null.
|
||||
*
|
||||
* @return
|
||||
* An InputStream which reads the contents of this resource, starting
|
||||
* with the first byte, or null if the resource is unavailable.
|
||||
*/
|
||||
InputStream asStream();
|
||||
|
||||
}
|
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.net.basic.resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Servlet which serves a given resource for all HTTP GET requests. The HEAD
|
||||
* method is correctly supported, and HTTP 304 ("Not Modified") responses will
|
||||
* be properly returned for GET requests depending on the last time the
|
||||
* resource was modified.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ResourceServlet extends HttpServlet {
|
||||
|
||||
/**
|
||||
* Logger for this class.
|
||||
*/
|
||||
private static final Logger logger = LoggerFactory.getLogger(ResourceServlet.class);
|
||||
|
||||
/**
|
||||
* The size of the buffer to use when transferring data from the input
|
||||
* stream of a resource to the output stream of a request.
|
||||
*/
|
||||
private static final int BUFFER_SIZE = 10240;
|
||||
|
||||
/**
|
||||
* The resource to serve for every GET request.
|
||||
*/
|
||||
private final Resource resource;
|
||||
|
||||
/**
|
||||
* Creates a new ResourceServlet which serves the given Resource for all
|
||||
* HTTP GET requests.
|
||||
*
|
||||
* @param resource
|
||||
* The Resource to serve.
|
||||
*/
|
||||
public ResourceServlet(Resource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHead(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
|
||||
// Set last modified and content type headers
|
||||
response.addDateHeader("Last-Modified", resource.getLastModified());
|
||||
response.setContentType(resource.getMimeType());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
|
||||
// Get input stream from resource
|
||||
InputStream input = resource.asStream();
|
||||
|
||||
// If resource does not exist, return not found
|
||||
if (input == null) {
|
||||
logger.debug("Resource does not exist: \"{}\"", request.getServletPath());
|
||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// Write headers
|
||||
doHead(request, response);
|
||||
|
||||
// If not modified since "If-Modified-Since" header, return not modified
|
||||
long ifModifiedSince = request.getDateHeader("If-Modified-Since");
|
||||
if (resource.getLastModified() - ifModifiedSince < 1000) {
|
||||
logger.debug("Resource not modified: \"{}\"", request.getServletPath());
|
||||
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
return;
|
||||
}
|
||||
|
||||
int length;
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
|
||||
// Write resource to response body
|
||||
OutputStream output = response.getOutputStream();
|
||||
while ((length = input.read(buffer)) != -1)
|
||||
output.write(buffer, 0, length);
|
||||
|
||||
}
|
||||
|
||||
// Ensure input stream is always closed
|
||||
finally {
|
||||
input.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.net.basic.resource;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.SequenceInputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* A resource which is the logical concatenation of other resources.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class SequenceResource extends AbstractResource {
|
||||
|
||||
/**
|
||||
* The resources to be concatenated.
|
||||
*/
|
||||
private final Iterable<Resource> resources;
|
||||
|
||||
/**
|
||||
* Returns the mimetype of the first resource in the given Iterable, or
|
||||
* "application/octet-stream" if no resources are provided.
|
||||
*
|
||||
* @param resources
|
||||
* The resources from which the mimetype should be retrieved.
|
||||
*
|
||||
* @return
|
||||
* The mimetype of the first resource, or "application/octet-stream"
|
||||
* if no resources were provided.
|
||||
*/
|
||||
private static String getMimeType(Iterable<Resource> resources) {
|
||||
|
||||
// If no resources, just assume application/octet-stream
|
||||
Iterator<Resource> resourceIterator = resources.iterator();
|
||||
if (!resourceIterator.hasNext())
|
||||
return "application/octet-stream";
|
||||
|
||||
// Return mimetype of first resource
|
||||
return resourceIterator.next().getMimeType();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SequenceResource as the logical concatenation of the
|
||||
* given resources. Each resource is concatenated in iteration order as
|
||||
* needed when reading from the input stream of the SequenceResource.
|
||||
*
|
||||
* @param mimetype
|
||||
* The mimetype of the resource.
|
||||
*
|
||||
* @param resources
|
||||
* The resources to concatenate within the InputStream of this
|
||||
* SequenceResource.
|
||||
*/
|
||||
public SequenceResource(String mimetype, Iterable<Resource> resources) {
|
||||
super(mimetype);
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SequenceResource as the logical concatenation of the
|
||||
* given resources. Each resource is concatenated in iteration order as
|
||||
* needed when reading from the input stream of the SequenceResource. The
|
||||
* mimetype of the resulting concatenation is derived from the first
|
||||
* resource.
|
||||
*
|
||||
* @param resources
|
||||
* The resources to concatenate within the InputStream of this
|
||||
* SequenceResource.
|
||||
*/
|
||||
public SequenceResource(Iterable<Resource> resources) {
|
||||
super(getMimeType(resources));
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SequenceResource as the logical concatenation of the
|
||||
* given resources. Each resource is concatenated in iteration order as
|
||||
* needed when reading from the input stream of the SequenceResource.
|
||||
*
|
||||
* @param mimetype
|
||||
* The mimetype of the resource.
|
||||
*
|
||||
* @param resources
|
||||
* The resources to concatenate within the InputStream of this
|
||||
* SequenceResource.
|
||||
*/
|
||||
public SequenceResource(String mimetype, Resource... resources) {
|
||||
this(mimetype, Arrays.asList(resources));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SequenceResource as the logical concatenation of the
|
||||
* given resources. Each resource is concatenated in iteration order as
|
||||
* needed when reading from the input stream of the SequenceResource. The
|
||||
* mimetype of the resulting concatenation is derived from the first
|
||||
* resource.
|
||||
*
|
||||
* @param resources
|
||||
* The resources to concatenate within the InputStream of this
|
||||
* SequenceResource.
|
||||
*/
|
||||
public SequenceResource(Resource... resources) {
|
||||
this(Arrays.asList(resources));
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream asStream() {
|
||||
return new SequenceInputStream(new Enumeration<InputStream>() {
|
||||
|
||||
/**
|
||||
* Iterator over all resources associated with this
|
||||
* SequenceResource.
|
||||
*/
|
||||
private final Iterator<Resource> resourceIterator = resources.iterator();
|
||||
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return resourceIterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream nextElement() {
|
||||
return resourceIterator.next().asStream();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.net.basic.resource;
|
||||
|
||||
import java.io.InputStream;
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
/**
|
||||
* A resource which is located within the classpath associated with another
|
||||
* class.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class WebApplicationResource extends AbstractResource {
|
||||
|
||||
/**
|
||||
* The servlet context to use when reading the resource and, if necessary,
|
||||
* when determining the mimetype of the resource.
|
||||
*/
|
||||
private final ServletContext context;
|
||||
|
||||
/**
|
||||
* The path of this resource relative to the ServletContext.
|
||||
*/
|
||||
private final String path;
|
||||
|
||||
/**
|
||||
* Derives a mimetype from the filename within the given path using the
|
||||
* given ServletContext, if possible.
|
||||
*
|
||||
* @param context
|
||||
* The ServletContext to use to derive the mimetype.
|
||||
*
|
||||
* @param path
|
||||
* The path to derive the mimetype from.
|
||||
*
|
||||
* @return
|
||||
* An appropriate mimetype based on the name of the file in the path,
|
||||
* or "application/octet-stream" if no mimetype could be determined.
|
||||
*/
|
||||
private static String getMimeType(ServletContext context, String path) {
|
||||
|
||||
// If mimetype is known, use defined mimetype
|
||||
String mimetype = context.getMimeType(path);
|
||||
if (mimetype != null)
|
||||
return mimetype;
|
||||
|
||||
// Otherwise, default to application/octet-stream
|
||||
return "application/octet-stream";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new WebApplicationResource which serves the resource at the
|
||||
* given path relative to the given ServletContext. Rather than deriving
|
||||
* the mimetype of the resource from the filename within the path, the
|
||||
* mimetype given is used.
|
||||
*
|
||||
* @param context
|
||||
* The ServletContext to use when reading the resource.
|
||||
*
|
||||
* @param mimetype
|
||||
* The mimetype of the resource.
|
||||
*
|
||||
* @param path
|
||||
* The path of the resource relative to the given ServletContext.
|
||||
*/
|
||||
public WebApplicationResource(ServletContext context, String mimetype, String path) {
|
||||
super(mimetype);
|
||||
this.context = context;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new WebApplicationResource which serves the resource at the
|
||||
* given path relative to the given ServletContext. The mimetype of the
|
||||
* resource is automatically determined based on the filename within the
|
||||
* path.
|
||||
*
|
||||
* @param context
|
||||
* The ServletContext to use when reading the resource and deriving the
|
||||
* mimetype.
|
||||
*
|
||||
* @param path
|
||||
* The path of the resource relative to the given ServletContext.
|
||||
*/
|
||||
public WebApplicationResource(ServletContext context, String path) {
|
||||
this(context, getMimeType(context, path), path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream asStream() {
|
||||
return context.getResourceAsStream(path);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes which describe and provide access to arbitrary resources, such as
|
||||
* the contents of the classpath of a classloader, or files within the web
|
||||
* application itself.
|
||||
*/
|
||||
package org.glyptodon.guacamole.net.basic.resource;
|
Reference in New Issue
Block a user