in jspwiki-main/src/main/java/org/apache/wiki/attachment/AttachmentServlet.java [175:284]
public void doGet( final HttpServletRequest req, final HttpServletResponse res ) throws IOException {
final Context context = Wiki.context().create( m_engine, req, ContextEnum.PAGE_ATTACH.getRequestContext() );
final AttachmentManager mgr = m_engine.getManager( AttachmentManager.class );
final AuthorizationManager authmgr = m_engine.getManager( AuthorizationManager.class );
final String version = req.getParameter( HDR_VERSION );
final String nextPage = req.getParameter( "nextpage" );
final String page = context.getPage().getName();
int ver = WikiProvider.LATEST_VERSION;
if( page == null ) {
LOG.info( "Invalid attachment name." );
res.sendError( HttpServletResponse.SC_BAD_REQUEST );
return;
}
try( final OutputStream out = res.getOutputStream() ) {
LOG.debug("Attempting to download att "+page+", version "+version);
if( version != null ) {
ver = Integer.parseInt( version );
}
final Attachment att = mgr.getAttachmentInfo( page, ver );
if( att != null ) {
//
// Check if the user has permission for this attachment
//
final Permission permission = PermissionFactory.getPagePermission( att, "view" );
if( !authmgr.checkPermission( context.getWikiSession(), permission ) ) {
LOG.debug("User does not have permission for this");
res.sendError( HttpServletResponse.SC_FORBIDDEN );
return;
}
//
// Check if the client already has a version of this attachment.
//
if( HttpUtil.checkFor304( req, att.getName(), att.getLastModified() ) ) {
LOG.debug( "Client has latest version already, sending 304..." );
res.sendError( HttpServletResponse.SC_NOT_MODIFIED );
return;
}
final String mimetype = getMimeType( context, att.getFileName() );
res.setContentType( mimetype );
final String contentDisposition = getContentDisposition( att );
res.addHeader( "Content-Disposition", contentDisposition );
res.addDateHeader("Last-Modified",att.getLastModified().getTime());
if( !att.isCacheable() ) {
res.addHeader( "Pragma", "no-cache" );
res.addHeader( "Cache-control", "no-cache" );
}
// If a size is provided by the provider, report it.
if( att.getSize() >= 0 ) {
// LOG.info("size:"+att.getSize());
res.setContentLength( (int)att.getSize() );
}
try( final InputStream in = mgr.getAttachmentStream( context, att ) ) {
int read;
final byte[] buffer = new byte[ BUFFER_SIZE ];
while( ( read = in.read( buffer ) ) > -1 ) {
out.write( buffer, 0, read );
}
}
LOG.debug( "Attachment {} sent to {} on {}", att.getFileName(), req.getRemoteUser(), HttpUtil.getRemoteAddress(req) );
if( nextPage != null ) {
res.sendRedirect(
validateNextPage(
TextUtil.urlEncodeUTF8(nextPage),
m_engine.getURL( ContextEnum.WIKI_ERROR.getRequestContext(), "", null )
)
);
}
} else {
final String msg = "Attachment '" + page + "', version " + ver + " does not exist.";
LOG.info( msg );
res.sendError( HttpServletResponse.SC_NOT_FOUND, msg );
}
} catch( final ProviderException pe ) {
LOG.debug("Provider failed while reading", pe);
//
// This might fail, if the response is already committed. So in that
// case we just log it.
//
sendError( res, "Provider error: "+ pe.getMessage() );
} catch( final NumberFormatException nfe ) {
LOG.warn( "Invalid version number: " + version );
res.sendError( HttpServletResponse.SC_BAD_REQUEST, "Invalid version number" );
} catch( final SocketException se ) {
//
// These are very common in download situations due to aggressive
// clients. No need to try and send an error.
//
LOG.debug( "I/O exception during download", se );
} catch( final IOException ioe ) {
//
// Client dropped the connection or something else happened.
// We don't know where the error came from, so we'll at least
// try to send an error and catch it quietly if it doesn't quite work.
//
LOG.debug( "I/O exception during download", ioe );
sendError( res, "Error: " + ioe.getMessage() );
}
}