|
Glassfish example source code file (RequestItemIterator.java)
The Glassfish RequestItemIterator.java source code/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.catalina.fileupload;
import org.apache.catalina.Globals;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.Map;
/**
* <p>High level API for processing file uploads.
*
* <p>This class handles multiple forms/files per single HTML widget, sent
* using <code>multipart/mixed encoding type, as specified by
* <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867.
*
* Original authors from org.apache.common.fileupload:
* @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski
* @author <a href="mailto:dlr@collab.net">Daniel Rall
* @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl
* @author <a href="mailto:jmcnally@collab.net">John McNally
* @author <a href="mailto:martinc@apache.org">Martin Cooper
* @author Sean C. Sullivan
*
* Adopted for glassfish:
* @author Kin-man Chung
*/
class RequestItemIterator {
private class RequestItemImpl implements RequestItem {
// The file items content type.
private final String contentType;
// The file items field name.
private final String fieldName;
// The file items file name.
private final String name;
// Whether the file item is a form field.
private final boolean formField;
// The file items input stream.
private InputStream stream;
// The headers, if any.
private PartHeaders headers;
/**
* Creates a new instance.
* @param pHeaders The item headers
* @param pName The items file name, or null.
* @param pFieldName The items field name.
* @param pContentType The items content type, or null.
* @param pFormField Whether the item is a form field.
* @param pContentLength The items content length, if known, or -1
* @throws ServletException Creating the file item failed.
*/
RequestItemImpl(PartHeaders pHeaders, String pName, String pFieldName,
String pContentType, boolean pFormField,
long pContentLength) throws ServletException {
headers = pHeaders;
name = pName;
fieldName = pFieldName;
contentType = pContentType;
formField = pFormField;
stream = multiStream.newInputStream();
long fileSizeMax = multipart.getMaxFileSize();
if (fileSizeMax != -1) {
if (pContentLength != -1) {
if (pContentLength > fileSizeMax) {
throw new ServletException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + fileSizeMax
+ " characters.");
}
} else {
stream = new LimitedInputStream(stream, fileSizeMax) {
protected void raiseError(long pSizeMax, long pCount)
throws SizeException {
throw new SizeException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + pSizeMax
+ " characters.");
}
};
}
}
}
/**
* Returns the items content type, or null.
* @return Content type, if known, or null.
*/
public String getContentType() {
return contentType;
}
/**
* Returns the items field name.
* @return Field name.
*/
public String getFieldName() {
return fieldName;
}
/**
* Returns the items file name.
* @return File name, if known, or null.
*/
public String getName() {
return name;
}
/**
* Returns, whether this is a form field.
* @return True, if the item is a form field,
* otherwise false.
*/
public boolean isFormField() {
return formField;
}
/**
* Returns an input stream, which may be used to
* read the items contents.
* @return Opened input stream.
* @throws IOException An I/O error occurred.
*/
public InputStream openStream() throws IOException {
return stream;
}
/**
* Closes the file item.
* @throws IOException An I/O error occurred.
*/
public void close() throws IOException {
stream.close();
}
/**
* Returns the file item headers.
* @return The items header object
*/
public PartHeaders getHeaders() {
return headers;
}
/**
* Sets the file item headers.
* @param pHeaders The items header object
*/
public void setHeaders(PartHeaders pHeaders) {
headers = pHeaders;
}
}
private static final String CONTENT_TYPE = "Content-type";
private static final String CONTENT_LENGTH = "Content-length";
private static final String CONTENT_DISPOSITION = "Content-disposition";
private static final String FORM_DATA = "form-data";
private static final String ATTACHMENT = "attachment";
private static final String MULTIPART = "multipart/";
private static final String MULTIPART_FORM_DATA = "multipart/form-data";
private static final String MULTIPART_MIXED = "multipart/mixed";
// Multipart instance, for accessing global properties, e.g. maxFileSize
private Multipart multipart;
// The multi part stream to process.
private final MultipartStream multiStream;
// The notifier, which used for triggering the
private final MultipartStream.ProgressNotifier notifier;
// The boundary, which separates the various parts.
private final byte[] boundary;
// The item, which we currently process.
private RequestItem currentItem;
// The current items field name.
private String currentFieldName;
// Whether the current item may still be read.
private boolean itemValid;
// Whether we have seen the end of the file.
private boolean eof;
/**
* Creates a new instance.
* @param request The HttpServletRequest.
* @throws FileUploadException An error occurred while
* parsing the request.
* @throws ServletException An I/O error occurred.
*/
RequestItemIterator(Multipart multipart, HttpServletRequest request)
throws IOException, ServletException {
this.multipart = multipart;
String contentType = request.getContentType();
if ((null == contentType)
|| (!contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART))) {
throw new ServletException(
"the request doesn't contain a "
+ MULTIPART_FORM_DATA
+ " or "
+ MULTIPART_MIXED
+ " stream, content type header is "
+ contentType);
}
InputStream input = request.getInputStream();
long sizeMax = multipart.getMaxRequestSize();
if (sizeMax >= 0) {
int requestSize = request.getContentLength();
if (requestSize == -1) {
input = new LimitedInputStream(input, sizeMax) {
protected void raiseError(long pSizeMax, long pCount)
throws SizeException {
throw new SizeException(
"the request was rejected because"
+ " its size (" + pCount
+ ") exceeds the configured maximum"
+ " (" + pSizeMax + ")");
}
};
} else if (requestSize > sizeMax) {
throw new ServletException(
"the request was rejected because its size ("
+ requestSize
+ ") exceeds the configured maximum ("
+ sizeMax + ")");
}
}
boundary = getBoundary(contentType);
if (boundary == null) {
throw new ServletException(
"the request was rejected because "
+ "no multipart boundary was found");
}
notifier = new MultipartStream.ProgressNotifier(
multipart.getProgressListener(),
request.getContentLength());
multiStream = new MultipartStream(input, boundary, notifier);
multiStream.setHeaderEncoding(request.getCharacterEncoding());
findNextItem();
}
/**
* Called for finding the nex item, if any.
* @return true, if an next item was found, otherwise false.
* @throws IOException An I/O error occurred.
*/
private boolean findNextItem() throws IOException, ServletException {
if (eof) {
return false;
}
if (currentItem != null) {
currentItem.close();
currentItem = null;
}
for (;;) {
if (! multiStream.skipPreamble()) {
if (currentFieldName == null) {
// Outer multipart terminated -> No more data
eof = true;
return false;
}
// Inner multipart terminated -> Return to parsing the outer
multiStream.setBoundary(boundary);
currentFieldName = null;
continue;
}
PartHeaders headers = getParsedHeaders(multiStream.readHeaders());
if (currentFieldName == null) {
// We're parsing the outer multipart
String fieldName = getFieldName(headers);
if (fieldName != null) {
String subContentType = headers.getHeader(CONTENT_TYPE);
if (subContentType != null
&& subContentType.toLowerCase(Locale.ENGLISH)
.startsWith(MULTIPART_MIXED)) {
currentFieldName = fieldName;
// Multiple files associated with this field name
byte[] subBoundary = getBoundary(subContentType);
multiStream.setBoundary(subBoundary);
continue;
}
String fileName = getFileName(headers);
currentItem = new RequestItemImpl(headers, fileName,
fieldName, headers.getHeader(CONTENT_TYPE),
fileName == null, getContentLength(headers));
notifier.noteItem();
itemValid = true;
return true;
}
} else {
String fileName = getFileName(headers);
if (fileName != null) {
currentItem = new RequestItemImpl(headers, fileName,
currentFieldName,
headers.getHeader(CONTENT_TYPE),
false, getContentLength(headers));
notifier.noteItem();
itemValid = true;
return true;
}
}
multiStream.discardBodyData();
}
}
private long getContentLength(PartHeaders pHeaders) {
try {
return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH));
} catch (Exception e) {
return -1;
}
}
/**
* Retrieves the file name from the <code>Content-disposition
* header.
*
* @param headers The HTTP headers object.
*
* @return The file name for the current <code>encapsulation.
*/
protected String getFileName(PartHeaders headers) {
return getFileName(headers.getHeader(CONTENT_DISPOSITION));
}
/**
* Returns the given content-disposition headers file name.
* @param pContentDisposition The content-disposition headers value.
* @return The file name
*/
private String getFileName(String pContentDisposition) {
String fileName = null;
if (pContentDisposition != null) {
String cdl = pContentDisposition.toLowerCase(Locale.ENGLISH);
if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) {
ParameterParser parser = new ParameterParser();
parser.setLowerCaseNames(true);
// Parameter parser can handle null input
Map<String, String> params =
parser.parse(pContentDisposition, ';');
if (params.containsKey("filename")) {
fileName = params.get("filename");
if (fileName != null) {
fileName = fileName.trim();
} else {
// Even if there is no value, the parameter is present,
// so we return an empty file name rather than no file
// name.
fileName = "";
}
}
}
}
return fileName;
}
/**
* Retrieves the field name from the <code>Content-disposition
* header.
*
* @param headers A <code>Map containing the HTTP request headers.
*
* @return The field name for the current <code>encapsulation.
*/
protected String getFieldName(PartHeaders headers) {
return getFieldName(headers.getHeader(CONTENT_DISPOSITION));
}
/**
* Returns the field name, which is given by the content-disposition
* header.
* @param pContentDisposition The content-dispositions header value.
* @return The field jake
*/
private String getFieldName(String pContentDisposition) {
String fieldName = null;
if (pContentDisposition != null
&& pContentDisposition.toLowerCase(Locale.ENGLISH).startsWith(FORM_DATA)) {
ParameterParser parser = new ParameterParser();
parser.setLowerCaseNames(true);
// Parameter parser can handle null input
Map<String, String> params = parser.parse(pContentDisposition, ';');
fieldName = params.get("name");
if (fieldName != null) {
fieldName = fieldName.trim();
}
}
return fieldName;
}
/**
* <p> Parses the
Other Glassfish examples (source code examples)Here is a short list of links related to this Glassfish RequestItemIterator.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.