use of io.milton.resource.GetableResource in project lobcder by skoulouzis.
the class PutHandler method processReplace.
/**
* "If an existing resource is modified, either the 200 (OK) or 204 (No
* Content) response codes SHOULD be sent to indicate successful completion
* of the request."
*
* @param request
* @param response
* @param replacee
*/
private void processReplace(HttpManager manager, Request request, Response response, ReplaceableResource replacee) throws BadRequestException, NotAuthorizedException, ConflictException, NotFoundException {
if (!handlerHelper.checkAuthorisation(manager, replacee, request)) {
responseHandler.respondUnauthorised(replacee, response, request);
return;
}
try {
Range range = putHelper.parseContentRange(replacee, request);
if (range != null) {
log.debug("partial put: " + range);
if (replacee instanceof PartialllyUpdateableResource) {
log.debug("doing partial put on a PartialllyUpdateableResource");
PartialllyUpdateableResource partialllyUpdateableResource = (PartialllyUpdateableResource) replacee;
partialllyUpdateableResource.replacePartialContent(range, request.getInputStream());
} else if (replacee instanceof GetableResource) {
log.debug("doing partial put on a GetableResource");
File tempFile = File.createTempFile("milton-partial", null);
RandomAccessFile randomAccessFile = null;
// The new length of the resource
long length;
try {
randomAccessFile = new RandomAccessFile(tempFile, "rw");
RandomFileOutputStream tempOut = new RandomFileOutputStream(tempFile);
GetableResource gr = (GetableResource) replacee;
// Update the content with the supplied partial content, and get the result as an inputstream
gr.sendContent(tempOut, null, null, null);
// Calculate new length, if the partial put is extending it
length = randomAccessFile.length();
if (range.getFinish() + 1 > length) {
length = range.getFinish() + 1;
}
randomAccessFile.setLength(length);
randomAccessFile.seek(range.getStart());
int numBytesRead;
byte[] copyBuffer = new byte[1024];
InputStream newContent = request.getInputStream();
while ((numBytesRead = newContent.read(copyBuffer)) != -1) {
randomAccessFile.write(copyBuffer, 0, numBytesRead);
}
} finally {
FileUtils.close(randomAccessFile);
}
InputStream updatedContent = new FileInputStream(tempFile);
BufferedInputStream bufin = new BufferedInputStream(updatedContent);
// Now, finally, we can just do a normal update
replacee.replaceContent(bufin, length);
} else {
throw new BadRequestException(replacee, "Cant apply partial update. Resource does not support PartialllyUpdateableResource or GetableResource");
}
} else {
// Not a partial update, but resource implements Replaceable, so give it the new data
Long l = request.getContentLengthHeader();
replacee.replaceContent(request.getInputStream(), l);
}
} catch (IOException ex) {
log.warn("IOException reading input stream. Probably interrupted upload: " + ex.getMessage());
return;
}
// Respond with a 204
responseHandler.respondNoContent(replacee, response, request);
log.debug("process: finished");
}
use of io.milton.resource.GetableResource in project lobcder by skoulouzis.
the class GetHandler method processExistingResource.
@Override
public void processExistingResource(HttpManager manager, Request request, Response response, Resource resource) throws NotAuthorizedException, BadRequestException, ConflictException, NotFoundException {
if (log.isTraceEnabled()) {
log.trace("process: " + request.getAbsolutePath());
}
manager.getEventManager().fireEvent(new GetEvent(resource));
GetableResource r = (GetableResource) resource;
if (checkConditional(r, request)) {
if (log.isTraceEnabled()) {
log.trace("respond not modified with: " + responseHandler.getClass().getCanonicalName());
}
responseHandler.respondNotModified(r, response, request);
return;
}
sendContent(manager, request, response, r, request.getParams());
}
use of io.milton.resource.GetableResource in project lobcder by skoulouzis.
the class DefaultHttp11ResponseHandler method respondHead.
@Override
public void respondHead(Resource resource, Response response, Request request) {
// setRespondContentCommonHeaders(response, resource, Response.Status.SC_NO_CONTENT, request.getAuthorization());
setRespondContentCommonHeaders(response, resource, Response.Status.SC_OK, request.getAuthorization());
if (!(resource instanceof GetableResource)) {
return;
}
GetableResource gr = (GetableResource) resource;
String acc = request.getAcceptHeader();
String ct = gr.getContentType(acc);
if (ct != null) {
ct = pickBestContentType(ct);
if (ct != null) {
response.setContentTypeHeader(ct);
}
}
Long contentLength = gr.getContentLength();
if (contentLength != null) {
response.setContentLengthHeader(contentLength);
} else {
log.trace("No content length is available for HEAD request");
}
}
use of io.milton.resource.GetableResource in project lobcder by skoulouzis.
the class AuthenticationService method canUseExternalAuth.
/**
* Determine if we can use external identify providers to authenticate this
* request
*
* @param resource
* @param request
* @return
*/
public boolean canUseExternalAuth(Resource resource, Request request) {
if (isDisableExternal()) {
log.trace("auth svc has disabled external auth");
return false;
}
if (getExternalIdentityProviders() == null || getExternalIdentityProviders().isEmpty()) {
log.trace("auth service has no external auth providers");
return false;
}
// has a content type of html
if (resource instanceof GetableResource) {
GetableResource gr = (GetableResource) resource;
String ct = gr.getContentType("text/html");
if (ct == null || !ct.contains("html")) {
log.trace("is not of content type html");
return false;
}
} else {
log.trace("is not getable");
// not getable, so definitely not suitable for external auth
return false;
}
// This can only be done for user agents which support displaying forms and redirection
// Ie typical web browsers are ok, webdav clients are generally not ok
String ua = request.getUserAgentHeader();
if (StringUtils.contains(ua.toLowerCase(), browserIds)) {
log.trace("is a known web browser, so can offer external auth");
return true;
} else {
log.trace("not a known web browser, so cannot offer external auth");
return false;
}
}
use of io.milton.resource.GetableResource in project lobcder by skoulouzis.
the class CompressingResponseHandler method respondContent.
@Override
public void respondContent(Resource resource, Response response, Request request, Map<String, String> params) throws NotAuthorizedException, BadRequestException, NotFoundException {
if (resource instanceof GetableResource) {
GetableResource r = (GetableResource) resource;
String acceptableContentTypes = request.getAcceptHeader();
String contentType = r.getContentType(acceptableContentTypes);
// Experimental support for already compressed content...
String acceptableEncodings = request.getAcceptEncodingHeader();
if (r instanceof CompressedResource) {
CompressedResource compressedResource = (CompressedResource) r;
String acceptableEncoding = compressedResource.getSupportedEncoding(acceptableEncodings);
if (acceptableEncoding != null) {
response.setContentTypeHeader(contentType);
cacheControlHelper.setCacheControl(r, response, request.getAuthorization());
Long contentLength = compressedResource.getCompressedContentLength(acceptableEncoding);
response.setContentLengthHeader(contentLength);
response.setContentEncodingHeader(Response.ContentEncoding.GZIP);
response.setVaryHeader("Accept-Encoding");
response.setEntity(new CompressedResourceEntity(compressedResource, params, contentType, acceptableEncoding));
return;
}
}
if (canCompress(r, contentType, acceptableEncodings)) {
log.trace("respondContent: compressable");
// get the zipped content before sending so we can determine its
// compressed size
BufferingOutputStream tempOut = new BufferingOutputStream(maxMemorySize);
try {
OutputStream gzipOut = new GZIPOutputStream(tempOut);
r.sendContent(gzipOut, null, params, contentType);
gzipOut.flush();
gzipOut.close();
tempOut.flush();
} catch (NotFoundException e) {
throw e;
} catch (Exception ex) {
tempOut.deleteTempFileIfExists();
throw new RuntimeException(ex);
} finally {
FileUtils.close(tempOut);
}
log.trace("respondContent-compressed: " + resource.getClass());
setRespondContentCommonHeaders(response, resource, Response.Status.SC_OK, request.getAuthorization());
response.setContentEncodingHeader(Response.ContentEncoding.GZIP);
response.setVaryHeader("Accept-Encoding");
Long contentLength = tempOut.getSize();
if (contentLength != null) {
response.setContentLengthHeader(contentLength);
}
response.setContentTypeHeader(contentType);
cacheControlHelper.setCacheControl(r, response, request.getAuthorization());
response.setEntity(new InputStreamEntity(tempOut.getInputStream()));
} else {
log.trace("respondContent: not compressable");
// We really should set this header, but it causes IE to not cache files (eg images)
// response.setVaryHeader( "Accept-Encoding" );
wrapped.respondContent(resource, response, request, params);
}
} else {
throw new RuntimeException("Cant generate content for non-Getable resource: " + resource.getClass());
}
}
Aggregations