mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-30 18:15:39 +00:00
65606: Merged V4.2-BUG-FIX (4.2.2) to HEAD-BUG-FIX (4.3/Cloud) 65512: MNT-10976: A possible typo error on LimitedStreamCopier class? - fixed incorrect log message git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@66257 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
120 lines
4.2 KiB
Java
120 lines
4.2 KiB
Java
/*
|
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
|
*
|
|
* This file is part of Alfresco
|
|
*
|
|
* Alfresco is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Alfresco is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package org.alfresco.repo.content;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
|
/**
|
|
* This class is a simple utility to copy bytes from an {@link InputStream} to an {@link OutputStream}.
|
|
* The copy can be performed with an optional byte limit and as soon as this limit is reached,
|
|
* the copy will be stopped immediately and a {@link ContentLimitViolationException} will be thrown.
|
|
*
|
|
* @since Thor
|
|
*/
|
|
public final class LimitedStreamCopier
|
|
{
|
|
private static final Log logger = LogFactory.getLog(LimitedStreamCopier.class);
|
|
private static final int BYTE_BUFFER_SIZE = 4096;
|
|
|
|
/**
|
|
* Copy of the the Spring FileCopyUtils, but does not silently absorb IOExceptions
|
|
* when the streams are closed. We require the stream write to happen successfully.
|
|
* <p/>
|
|
* Both streams are closed but any IOExceptions are thrown
|
|
*
|
|
* @param in the stream from which to read content.
|
|
* @param out the stream to which to write content.
|
|
* @param sizeLimit the maximum number of bytes that will be copied between the streams before a
|
|
* {@link ContentLimitViolationException} will be thrown.
|
|
* A negative number or zero will be deemed to mean 'no limit'.
|
|
*/
|
|
public final int copyStreams(InputStream in, OutputStream out, long sizeLimit) throws IOException
|
|
{
|
|
long bytes = copyStreamsLong(in, out, sizeLimit);
|
|
if (bytes > Integer.MAX_VALUE)
|
|
{
|
|
throw new IllegalArgumentException(bytes + " cannot be cast to int.");
|
|
}
|
|
|
|
return (int) bytes;
|
|
}
|
|
|
|
public final long copyStreamsLong(InputStream in, OutputStream out, long sizeLimit) throws IOException
|
|
{
|
|
long byteCount = 0;
|
|
IOException error = null;
|
|
|
|
long totalBytesRead = 0;
|
|
|
|
try
|
|
{
|
|
byte[] buffer = new byte[BYTE_BUFFER_SIZE];
|
|
int bytesRead = -1;
|
|
while ((bytesRead = in.read(buffer)) != -1)
|
|
{
|
|
// We are able to abort the copy immediately upon limit violation.
|
|
totalBytesRead += bytesRead;
|
|
if (sizeLimit > 0 && totalBytesRead > sizeLimit)
|
|
{
|
|
StringBuilder msg = new StringBuilder();
|
|
msg.append("Content size violation, limit = ")
|
|
.append(sizeLimit);
|
|
|
|
throw new ContentLimitViolationException(msg.toString());
|
|
}
|
|
|
|
out.write(buffer, 0, bytesRead);
|
|
byteCount += bytesRead;
|
|
}
|
|
out.flush();
|
|
}
|
|
finally
|
|
{
|
|
try
|
|
{
|
|
in.close();
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
error = e;
|
|
logger.error("Failed to close input stream: " + this, e);
|
|
}
|
|
try
|
|
{
|
|
out.close();
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
error = e;
|
|
logger.error("Failed to close output stream: " + this, e);
|
|
}
|
|
}
|
|
if (error != null)
|
|
{
|
|
throw error;
|
|
}
|
|
return byteCount;
|
|
}
|
|
}
|