package org.dcache.webdav;
import com.google.common.collect.ImmutableMap;
import io.milton.config.HttpManagerBuilder;
import io.milton.http.Auth;
import io.milton.http.AuthenticationService;
import io.milton.http.HandlerHelper;
import io.milton.http.HttpManager;
import io.milton.http.Response;
import io.milton.http.Response.Status;
import io.milton.http.http11.DefaultHttp11ResponseHandler;
import io.milton.http.webdav.DefaultWebDavResponseHandler;
import io.milton.http.webdav.PropFindXmlGenerator;
import io.milton.http.webdav.WebDavResponseHandler;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Required;
import java.util.Date;
import org.dcache.webdav.federation.FederationResponseHandler;
import static com.google.common.base.Preconditions.checkNotNull;
public class HttpManagerFactory extends HttpManagerBuilder implements FactoryBean
{
private ReloadableTemplate _template;
private ImmutableMap<String,String> _templateConfig;
private String _staticContentPath;
private PathMapper _pathMapper;
@Override
public Object getObject() throws Exception
{
DcacheResponseHandler dcacheResponseHandler = new DcacheResponseHandler();
dcacheResponseHandler.setPathMapper(_pathMapper);
WebDavResponseHandler handler = new FederationResponseHandler(dcacheResponseHandler);
setWebdavResponseHandler(handler);
init();
// Late initialization of DcacheResponseHandler because AuthenticationService and other collaborators
// have to be created first.
dcacheResponseHandler.setAuthenticationService(getAuthenticationService());
dcacheResponseHandler.setWrapped(
new DefaultWebDavResponseHandler(getHttp11ResponseHandler(), getResourceTypeHelper(),
getPropFindXmlGenerator()));
dcacheResponseHandler.setReloadableTemplate(_template);
dcacheResponseHandler.setTemplateConfig(_templateConfig);
dcacheResponseHandler.setStaticContentPath(_staticContentPath);
dcacheResponseHandler.setBuffering(getBuffering());
return buildHttpManager();
}
/* The following hack allows injection of custom objects part way through init */
@Override
protected void buildResourceTypeHelper() {
super.buildResourceTypeHelper();
if (handlerHelper == null) {
handlerHelper = new HandlerHelper(authenticationService);
showLog("handlerHelper", handlerHelper);
}
if (propFindXmlGenerator == null) {
propFindXmlGenerator = new PropFindXmlGenerator(valueWriters);
showLog("propFindXmlGenerator", propFindXmlGenerator);
}
if (http11ResponseHandler == null) {
DefaultHttp11ResponseHandler rh = createDefaultHttp11ResponseHandler(authenticationService);
rh.setCacheControlHelper(cacheControlHelper);
rh.setBuffering(buffering);
http11ResponseHandler = rh;
showLog("http11ResponseHandler", http11ResponseHandler);
}
if (webdavResponseHandler == null) {
webdavResponseHandler = new DefaultWebDavResponseHandler(http11ResponseHandler, resourceTypeHelper, propFindXmlGenerator);
}
outerWebdavResponseHandler = webdavResponseHandler;
if (resourceHandlerHelper == null) {
resourceHandlerHelper = new DcacheResourceHandlerHelper(handlerHelper,
urlAdapter, outerWebdavResponseHandler, authenticationService);
showLog("resourceHandlerHelper", resourceHandlerHelper);
}
}
@Override
protected DefaultHttp11ResponseHandler createDefaultHttp11ResponseHandler(AuthenticationService authenticationService)
{
// Subclass DefaultHttp11ResponseHandler to avoid adding a "Server" response header.
return new DefaultHttp11ResponseHandler(authenticationService,
eTagGenerator, contentGenerator) {
@Override
protected void setRespondCommonHeaders(Response response,
io.milton.resource.Resource resource, Status status, Auth auth)
{
response.setStatus(status);
// The next line is omitted to avoid setting the Server header
// response.setNonStandardHeader("Server", "milton.io-" + miltonVerson);
response.setDateHeader(new Date());
response.setNonStandardHeader("Accept-Ranges", "bytes");
String etag = eTagGenerator.generateEtag(resource);
if (etag != null) {
response.setEtag(etag);
}
}
};
}
@Override
public Class<?> getObjectType()
{
return HttpManager.class;
}
@Override
public boolean isSingleton()
{
return true;
}
@Required
public void setPathMapper(PathMapper mapper)
{
_pathMapper = checkNotNull(mapper);
}
/**
* Sets the resource containing the StringTemplateGroup for
* directory listing.
*/
@Required
public void setTemplate(ReloadableTemplate template)
{
_template = template;
}
@Required
public void setTemplateConfig(ImmutableMap<String,String> config)
{
_templateConfig = config;
}
/**
* The static content path is the path under which the service
* exports the static content. This typically contains stylesheets
* and image files.
*/
public void setStaticContentPath(String path)
{
_staticContentPath = path;
}
}