2 // ========================================================================
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.util;
21 import java.io.FilterOutputStream;
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.nio.charset.StandardCharsets;
27 /* ================================================================ */
28 /** Handle a multipart MIME response.
33 public class MultiPartOutputStream extends FilterOutputStream
35 /* ------------------------------------------------------------ */
36 private static final byte[] __CRLF={'\r','\n'};
37 private static final byte[] __DASHDASH={'-','-'};
39 public static final String MULTIPART_MIXED="multipart/mixed";
40 public static final String MULTIPART_X_MIXED_REPLACE="multipart/x-mixed-replace";
42 /* ------------------------------------------------------------ */
43 private final String boundary;
44 private final byte[] boundaryBytes;
46 /* ------------------------------------------------------------ */
47 private boolean inPart=false;
49 /* ------------------------------------------------------------ */
50 public MultiPartOutputStream(OutputStream out)
55 boundary = "jetty"+System.identityHashCode(this)+
56 Long.toString(System.currentTimeMillis(),36);
57 boundaryBytes=boundary.getBytes(StandardCharsets.ISO_8859_1);
60 public MultiPartOutputStream(OutputStream out, String boundary)
65 this.boundary = boundary;
66 boundaryBytes=boundary.getBytes(StandardCharsets.ISO_8859_1);
69 /* ------------------------------------------------------------ */
70 /** End the current part.
71 * @exception IOException IOException
81 out.write(__DASHDASH);
82 out.write(boundaryBytes);
83 out.write(__DASHDASH);
93 /* ------------------------------------------------------------ */
94 public String getBoundary()
99 public OutputStream getOut() {return out;}
101 /* ------------------------------------------------------------ */
102 /** Start creation of the next Content.
104 public void startPart(String contentType)
110 out.write(__DASHDASH);
111 out.write(boundaryBytes);
113 if (contentType != null)
114 out.write(("Content-Type: "+contentType).getBytes(StandardCharsets.ISO_8859_1));
119 /* ------------------------------------------------------------ */
120 /** Start creation of the next Content.
122 public void startPart(String contentType, String[] headers)
128 out.write(__DASHDASH);
129 out.write(boundaryBytes);
131 if (contentType != null)
132 out.write(("Content-Type: "+contentType).getBytes(StandardCharsets.ISO_8859_1));
134 for (int i=0;headers!=null && i<headers.length;i++)
136 out.write(headers[i].getBytes(StandardCharsets.ISO_8859_1));
142 /* ------------------------------------------------------------ */
144 public void write(byte[] b, int off, int len) throws IOException
146 out.write(b,off,len);