src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/mimepull/InternetHeaders.java

Fri, 04 Oct 2013 16:21:34 +0100

author
mkos
date
Fri, 04 Oct 2013 16:21:34 +0100
changeset 408
b0610cd08440
parent 368
0989ad8c0860
child 637
9c07ef4934dd
permissions
-rw-r--r--

8025054: Update JAX-WS RI integration to 2.2.9-b130926.1035
Reviewed-by: chegar

ohair@286 1 /*
alanb@368 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
ohair@286 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@286 4 *
ohair@286 5 * This code is free software; you can redistribute it and/or modify it
ohair@286 6 * under the terms of the GNU General Public License version 2 only, as
ohair@286 7 * published by the Free Software Foundation. Oracle designates this
ohair@286 8 * particular file as subject to the "Classpath" exception as provided
ohair@286 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@286 10 *
ohair@286 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@286 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@286 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@286 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@286 15 * accompanied this code).
ohair@286 16 *
ohair@286 17 * You should have received a copy of the GNU General Public License version
ohair@286 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@286 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@286 20 *
ohair@286 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@286 22 * or visit www.oracle.com if you need additional information or have any
ohair@286 23 * questions.
ohair@286 24 */
ohair@286 25
ohair@286 26 package com.sun.xml.internal.org.jvnet.mimepull;
ohair@286 27
ohair@286 28 import java.io.IOException;
ohair@286 29 import java.util.NoSuchElementException;
ohair@286 30 import java.util.List;
ohair@286 31
ohair@286 32 /**
ohair@286 33 * InternetHeaders is a utility class that manages RFC822 style
ohair@286 34 * headers. Given an RFC822 format message stream, it reads lines
ohair@286 35 * until the blank line that indicates end of header. The input stream
ohair@286 36 * is positioned at the start of the body. The lines are stored
ohair@286 37 * within the object and can be extracted as either Strings or
ohair@286 38 * {@link Header} objects. <p>
ohair@286 39 * <p/>
ohair@286 40 * This class is mostly intended for service providers. MimeMessage
ohair@286 41 * and MimeBody use this class for holding their headers. <p>
ohair@286 42 * <p/>
ohair@286 43 * <hr> <strong>A note on RFC822 and MIME headers</strong><p>
ohair@286 44 * <p/>
ohair@286 45 * RFC822 and MIME header fields <strong>must</strong> contain only
ohair@286 46 * US-ASCII characters. If a header contains non US-ASCII characters,
ohair@286 47 * it must be encoded as per the rules in RFC 2047. The MimeUtility
ohair@286 48 * class provided in this package can be used to to achieve this.
ohair@286 49 * Callers of the <code>setHeader</code>, <code>addHeader</code>, and
ohair@286 50 * <code>addHeaderLine</code> methods are responsible for enforcing
ohair@286 51 * the MIME requirements for the specified headers. In addition, these
ohair@286 52 * header fields must be folded (wrapped) before being sent if they
ohair@286 53 * exceed the line length limitation for the transport (1000 bytes for
ohair@286 54 * SMTP). Received headers may have been folded. The application is
ohair@286 55 * responsible for folding and unfolding headers as appropriate. <p>
ohair@286 56 *
ohair@286 57 * @author John Mani
ohair@286 58 * @author Bill Shannon
ohair@286 59 */
ohair@286 60 final class InternetHeaders {
ohair@286 61
alanb@368 62 private final FinalArrayList<Hdr> headers = new FinalArrayList<Hdr>();
ohair@286 63
ohair@286 64 /**
ohair@286 65 * Read and parse the given RFC822 message stream till the
ohair@286 66 * blank line separating the header from the body. Store the
ohair@286 67 * header lines inside this InternetHeaders object. <p>
ohair@286 68 * <p/>
ohair@286 69 * Note that the header lines are added into this InternetHeaders
ohair@286 70 * object, so any existing headers in this object will not be
ohair@286 71 * affected.
ohair@286 72 *
ohair@286 73 * @param lis RFC822 input stream
ohair@286 74 */
ohair@286 75 InternetHeaders(MIMEParser.LineInputStream lis) {
ohair@286 76 // Read header lines until a blank line. It is valid
ohair@286 77 // to have BodyParts with no header lines.
ohair@286 78 String line;
ohair@286 79 String prevline = null; // the previous header line, as a string
ohair@286 80 // a buffer to accumulate the header in, when we know it's needed
alanb@368 81 StringBuilder lineBuffer = new StringBuilder();
ohair@286 82
ohair@286 83 try {
ohair@286 84 //while ((line = lis.readLine()) != null) {
ohair@286 85 do {
ohair@286 86 line = lis.readLine();
ohair@286 87 if (line != null &&
ohair@286 88 (line.startsWith(" ") || line.startsWith("\t"))) {
ohair@286 89 // continuation of header
ohair@286 90 if (prevline != null) {
ohair@286 91 lineBuffer.append(prevline);
ohair@286 92 prevline = null;
ohair@286 93 }
ohair@286 94 lineBuffer.append("\r\n");
ohair@286 95 lineBuffer.append(line);
ohair@286 96 } else {
ohair@286 97 // new header
alanb@368 98 if (prevline != null) {
ohair@286 99 addHeaderLine(prevline);
alanb@368 100 } else if (lineBuffer.length() > 0) {
ohair@286 101 // store previous header first
ohair@286 102 addHeaderLine(lineBuffer.toString());
ohair@286 103 lineBuffer.setLength(0);
ohair@286 104 }
ohair@286 105 prevline = line;
ohair@286 106 }
ohair@286 107 } while (line != null && line.length() > 0);
ohair@286 108 } catch (IOException ioex) {
ohair@286 109 throw new MIMEParsingException("Error in input stream", ioex);
ohair@286 110 }
ohair@286 111 }
ohair@286 112
ohair@286 113 /**
ohair@286 114 * Return all the values for the specified header. The
ohair@286 115 * values are String objects. Returns <code>null</code>
ohair@286 116 * if no headers with the specified name exist.
ohair@286 117 *
ohair@286 118 * @param name header name
ohair@286 119 * @return array of header values, or null if none
ohair@286 120 */
ohair@286 121 List<String> getHeader(String name) {
ohair@286 122 // XXX - should we just step through in index order?
ohair@286 123 FinalArrayList<String> v = new FinalArrayList<String>(); // accumulate return values
ohair@286 124
ohair@286 125 int len = headers.size();
ohair@286 126 for( int i=0; i<len; i++ ) {
alanb@368 127 Hdr h = (Hdr) headers.get(i);
ohair@286 128 if (name.equalsIgnoreCase(h.name)) {
ohair@286 129 v.add(h.getValue());
ohair@286 130 }
ohair@286 131 }
ohair@286 132 return (v.size() == 0) ? null : v;
ohair@286 133 }
ohair@286 134
ohair@286 135 /**
ohair@286 136 * Return all the headers as an Enumeration of
ohair@286 137 * {@link Header} objects.
ohair@286 138 *
ohair@286 139 * @return Header objects
ohair@286 140 */
ohair@286 141 FinalArrayList<? extends Header> getAllHeaders() {
ohair@286 142 return headers; // conceptually it should be read-only, but for performance reason I'm not wrapping it here
ohair@286 143 }
ohair@286 144
ohair@286 145 /**
ohair@286 146 * Add an RFC822 header line to the header store.
ohair@286 147 * If the line starts with a space or tab (a continuation line),
ohair@286 148 * add it to the last header line in the list. <p>
ohair@286 149 * <p/>
ohair@286 150 * Note that RFC822 headers can only contain US-ASCII characters
ohair@286 151 *
ohair@286 152 * @param line raw RFC822 header line
ohair@286 153 */
ohair@286 154 void addHeaderLine(String line) {
ohair@286 155 try {
ohair@286 156 char c = line.charAt(0);
ohair@286 157 if (c == ' ' || c == '\t') {
alanb@368 158 Hdr h = (Hdr) headers.get(headers.size() - 1);
ohair@286 159 h.line += "\r\n" + line;
alanb@368 160 } else {
alanb@368 161 headers.add(new Hdr(line));
alanb@368 162 }
ohair@286 163 } catch (StringIndexOutOfBoundsException e) {
ohair@286 164 // line is empty, ignore it
ohair@286 165 } catch (NoSuchElementException e) {
ohair@286 166 // XXX - vector is empty?
ohair@286 167 }
ohair@286 168 }
ohair@286 169
ohair@286 170 }
ohair@286 171
ohair@286 172 /*
ohair@286 173 * A private utility class to represent an individual header.
ohair@286 174 */
ohair@286 175
alanb@368 176 class Hdr implements Header {
ohair@286 177
ohair@286 178 String name; // the canonicalized (trimmed) name of this header
ohair@286 179 // XXX - should name be stored in lower case?
ohair@286 180 String line; // the entire RFC822 header "line"
ohair@286 181
ohair@286 182 /*
ohair@286 183 * Constructor that takes a line and splits out
ohair@286 184 * the header name.
ohair@286 185 */
alanb@368 186 Hdr(String l) {
ohair@286 187 int i = l.indexOf(':');
ohair@286 188 if (i < 0) {
ohair@286 189 // should never happen
ohair@286 190 name = l.trim();
ohair@286 191 } else {
ohair@286 192 name = l.substring(0, i).trim();
ohair@286 193 }
ohair@286 194 line = l;
ohair@286 195 }
ohair@286 196
ohair@286 197 /*
ohair@286 198 * Constructor that takes a header name and value.
ohair@286 199 */
alanb@368 200 Hdr(String n, String v) {
ohair@286 201 name = n;
ohair@286 202 line = n + ": " + v;
ohair@286 203 }
ohair@286 204
ohair@286 205 /*
ohair@286 206 * Return the "name" part of the header line.
ohair@286 207 */
alanb@368 208 @Override
ohair@286 209 public String getName() {
ohair@286 210 return name;
ohair@286 211 }
ohair@286 212
ohair@286 213 /*
ohair@286 214 * Return the "value" part of the header line.
ohair@286 215 */
alanb@368 216 @Override
ohair@286 217 public String getValue() {
ohair@286 218 int i = line.indexOf(':');
alanb@368 219 if (i < 0) {
ohair@286 220 return line;
alanb@368 221 }
ohair@286 222
ohair@286 223 int j;
ohair@286 224 if (name.equalsIgnoreCase("Content-Description")) {
ohair@286 225 // Content-Description should retain the folded whitespace after header unfolding -
ohair@286 226 // rf. RFC2822 section 2.2.3, rf. RFC2822 section 3.2.3
ohair@286 227 for (j = i + 1; j < line.length(); j++) {
ohair@286 228 char c = line.charAt(j);
alanb@368 229 if (!(/*c == ' ' ||*/c == '\t' || c == '\r' || c == '\n')) {
ohair@286 230 break;
alanb@368 231 }
ohair@286 232 }
ohair@286 233 } else {
ohair@286 234 // skip whitespace after ':'
ohair@286 235 for (j = i + 1; j < line.length(); j++) {
ohair@286 236 char c = line.charAt(j);
alanb@368 237 if (!(c == ' ' || c == '\t' || c == '\r' || c == '\n')) {
ohair@286 238 break;
alanb@368 239 }
ohair@286 240 }
ohair@286 241 }
ohair@286 242 return line.substring(j);
ohair@286 243 }
ohair@286 244 }

mercurial