📄 multipartrelatedinputstream.java
字号:
/* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed 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.axis.attachments;import org.apache.axis.Part;import org.apache.axis.components.logger.LogFactory;import org.apache.axis.transport.http.HTTPConstants;import org.apache.axis.utils.Messages;import org.apache.axis.utils.IOUtils;import org.apache.commons.logging.Log;import javax.activation.DataHandler;import javax.mail.internet.MimeUtility;import java.io.IOException;import java.io.BufferedInputStream;/** * This simulates the multipart stream. * * @author Rick Rineholt */public class MultiPartRelatedInputStream extends MultiPartInputStream{ /** Field log */ protected static Log log = LogFactory.getLog(MultiPartRelatedInputStream.class.getName()); /** Field MIME_MULTIPART_RELATED */ public static final String MIME_MULTIPART_RELATED = "multipart/related"; /** Field parts */ protected java.util.HashMap parts = new java.util.HashMap(); /** Field orderedParts */ protected java.util.LinkedList orderedParts = new java.util.LinkedList(); /** Field rootPartLength */ protected int rootPartLength = 0; /** Field closed */ protected boolean closed = false; // If true the stream has been closed. /** Field eos */ protected boolean eos = false; // This is set once the SOAP packet has reached the end of stream. // protected java.io.InputStream is = null; //The orginal multipart/related stream. // This stream controls and manages the boundary. /** Field boundaryDelimitedStream */ protected org.apache.axis.attachments.BoundaryDelimitedStream boundaryDelimitedStream = null; /** Field soapStream */ protected java.io.InputStream soapStream = null; // Set the soap stream once found. /** Field soapStreamBDS */ protected java.io.InputStream soapStreamBDS = null; // Set to the boundary delimited stream assoc. with soap stream once found. /** Field boundary */ protected byte[] boundary = null; /** Field cachedSOAPEnvelope */ protected java.io.ByteArrayInputStream cachedSOAPEnvelope = null; // Caches the soap stream if it is // Still open and a reference to read data in a later attachment occurs. /** Field contentLocation */ protected String contentLocation = null; /** Field contentId */ protected String contentId = null; /** Field MAX_CACHED */ private static final int MAX_CACHED = 16 * 1024; /** * Create a new Multipart stream. * @param contentType the string that holds the contentType * @param stream the true input stream from where the source * * @throws org.apache.axis.AxisFault if the stream could not be created */ public MultiPartRelatedInputStream( String contentType, java.io.InputStream stream) throws org.apache.axis.AxisFault { super(null); // don't cache this stream. if(!(stream instanceof BufferedInputStream)) { stream = new BufferedInputStream(stream); } try { // First find the start and boundary parameters. There are real weird rules regard what // can be in real headers what needs to be escaped etc let mail parse it. javax.mail.internet.ContentType ct = new javax.mail.internet.ContentType(contentType); String rootPartContentId = ct.getParameter("start"); // Get the root part content. if (rootPartContentId != null) { rootPartContentId = rootPartContentId.trim(); if (rootPartContentId.startsWith("<")) { rootPartContentId = rootPartContentId.substring(1); } if (rootPartContentId.endsWith(">")) { rootPartContentId = rootPartContentId.substring(0, rootPartContentId.length() - 1); } } if(ct.getParameter("boundary") != null) { String boundaryStr = "--" + ct.getParameter( "boundary"); // The boundary with -- add as always the case. // if start is null then the first attachment is the rootpart // First read the start boundary -- this is done with brute force since the servlet may swallow the crlf between headers. // after this we use the more efficient boundarydelimeted stream. There should never be any data here anyway. byte[][] boundaryMarker = new byte[2][boundaryStr.length() + 2]; IOUtils.readFully(stream, boundaryMarker[0]); boundary = (boundaryStr + "\r\n").getBytes("US-ASCII"); int current = 0; // This just goes brute force one byte at a time to find the first boundary. // in most cases this just a crlf. for (boolean found = false; !found; ++current) { if (!(found = java.util.Arrays.equals(boundaryMarker[current & 0x1], boundary))) { System.arraycopy(boundaryMarker[current & 0x1], 1, boundaryMarker[(current + 1) & 0x1], 0, boundaryMarker[0].length - 1); if (stream.read( boundaryMarker[(current + 1) & 0x1], boundaryMarker[0].length - 1, 1) < 1) { throw new org.apache.axis.AxisFault( Messages.getMessage( "mimeErrorNoBoundary", new String(boundary))); } } } // after the first boundary each boundary will have a cr lf at the beginning since after the data in any part there // is a cr lf added to put the boundary at the begining of a line. boundaryStr = "\r\n" + boundaryStr; boundary = boundaryStr.getBytes("US-ASCII"); } else { // Since boundary is not specified, we try to find one. for (boolean found = false; !found;) { boundary= readLine(stream); if( boundary == null) throw new org.apache.axis.AxisFault( Messages.getMessage( "mimeErrorNoBoundary", "--")); found = boundary.length >4 && boundary[2] == '-' && boundary[3]== '-'; } } // create the boundary delmited stream. boundaryDelimitedStream = new org.apache.axis.attachments.BoundaryDelimitedStream(stream, boundary, 1024); // Now read through all potential streams until we have found the root part. String contentTransferEncoding = null; do { contentId = null; contentLocation = null; contentTransferEncoding = null; // Read this attachments headers from the stream. javax.mail.internet.InternetHeaders headers = new javax.mail.internet.InternetHeaders( boundaryDelimitedStream); // Use java mail utility to read through the headers. contentId = headers.getHeader(HTTPConstants.HEADER_CONTENT_ID, null); // Clean up the headers and remove any < > if (contentId != null) { contentId = contentId.trim(); if (contentId.startsWith("<")) { contentId = contentId.substring(1); } if (contentId.endsWith(">")) { contentId = contentId.substring(0, contentId.length() - 1); } contentId = contentId.trim(); // if (!contentId.startsWith("cid:")) { // contentId = // "cid:" // + contentId; // make sure its identified as cid // } } contentLocation = headers.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION, null); if (contentLocation != null) { contentLocation = contentLocation.trim(); if (contentLocation.startsWith("<")) { contentLocation = contentLocation.substring(1); } if (contentLocation.endsWith(">")) { contentLocation = contentLocation.substring( 0, contentLocation.length() - 1); } contentLocation = contentLocation.trim(); } contentType = headers.getHeader(HTTPConstants.HEADER_CONTENT_TYPE, null); if (contentType != null) { contentType = contentType.trim(); } contentTransferEncoding = headers.getHeader( HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING, null); if (contentTransferEncoding != null) { contentTransferEncoding = contentTransferEncoding.trim(); } java.io.InputStream decodedStream = boundaryDelimitedStream; if ((contentTransferEncoding != null) && (0 != contentTransferEncoding.length())) { decodedStream = MimeUtility.decode(decodedStream, contentTransferEncoding); } if ((rootPartContentId != null) && !rootPartContentId.equals( contentId)) { // This is a part that has come in prior to the root part. Need to buffer it up. javax.activation.DataHandler dh = new javax.activation.DataHandler( new org.apache.axis.attachments.ManagedMemoryDataSource( decodedStream, MAX_CACHED, contentType, true)); AttachmentPart ap = new AttachmentPart(dh); if (contentId != null) { ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, contentId); } if (contentLocation != null) { ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION, contentLocation); } for (java.util.Enumeration en = headers.getNonMatchingHeaders(new String[]{ HTTPConstants.HEADER_CONTENT_ID, HTTPConstants.HEADER_CONTENT_LOCATION, HTTPConstants.HEADER_CONTENT_TYPE}); en.hasMoreElements();) { javax.mail.Header header = (javax.mail.Header) en.nextElement(); String name = header.getName(); String value = header.getValue(); if ((name != null) && (value != null)) { name = name.trim(); if (name.length() != 0) { ap.addMimeHeader(name, value); } } } addPart(contentId, contentLocation, ap); boundaryDelimitedStream = boundaryDelimitedStream.getNextStream(); // Gets the next stream. } } while ((null != boundaryDelimitedStream) && (rootPartContentId != null) && !rootPartContentId.equals(contentId)); if (boundaryDelimitedStream == null) { throw new org.apache.axis.AxisFault( Messages.getMessage("noRoot", rootPartContentId)); } soapStreamBDS = boundaryDelimitedStream; if ((contentTransferEncoding != null) && (0 != contentTransferEncoding.length())) { soapStream = MimeUtility.decode(boundaryDelimitedStream, contentTransferEncoding); } else { soapStream = boundaryDelimitedStream; // This should be the SOAP part } // Read from the input stream all attachments prior to the root part. } catch (javax.mail.internet.ParseException e) { throw new org.apache.axis.AxisFault( Messages.getMessage("mimeErrorParsing", e.getMessage())); } catch (java.io.IOException e) { throw new org.apache.axis.AxisFault(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -