1 //
2 // ========================================================================
3 // Copyright (c) 1995-2013 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.
8 //
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
11 //
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
14 //
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
17 //
18
19 package org.eclipse.jetty.util;
20
21 import java.io.FilterOutputStream;
22 import java.io.IOException;
23 import java.io.OutputStream;
24
25
26 /* ================================================================ */
27 /** Handle a multipart MIME response.
28 *
29 *
30 *
31 */
32 public class MultiPartOutputStream extends FilterOutputStream
33 {
34 /* ------------------------------------------------------------ */
35 private static final byte[] __CRLF={'\r','\n'};
36 private static final byte[] __DASHDASH={'-','-'};
37
38 public static String MULTIPART_MIXED="multipart/mixed";
39 public static String MULTIPART_X_MIXED_REPLACE="multipart/x-mixed-replace";
40
41 /* ------------------------------------------------------------ */
42 private String boundary;
43 private byte[] boundaryBytes;
44
45 /* ------------------------------------------------------------ */
46 private boolean inPart=false;
47
48 /* ------------------------------------------------------------ */
49 public MultiPartOutputStream(OutputStream out)
50 throws IOException
51 {
52 super(out);
53
54 boundary = "jetty"+System.identityHashCode(this)+
55 Long.toString(System.currentTimeMillis(),36);
56 boundaryBytes=boundary.getBytes(StringUtil.__ISO_8859_1);
57
58 inPart=false;
59 }
60
61 /* ------------------------------------------------------------ */
62 /** End the current part.
63 * @exception IOException IOException
64 */
65 @Override
66 public void close()
67 throws IOException
68 {
69 if (inPart)
70 out.write(__CRLF);
71 out.write(__DASHDASH);
72 out.write(boundaryBytes);
73 out.write(__DASHDASH);
74 out.write(__CRLF);
75 inPart=false;
76 super.close();
77 }
78
79 /* ------------------------------------------------------------ */
80 public String getBoundary()
81 {
82 return boundary;
83 }
84
85 public OutputStream getOut() {return out;}
86
87 /* ------------------------------------------------------------ */
88 /** Start creation of the next Content.
89 */
90 public void startPart(String contentType)
91 throws IOException
92 {
93 if (inPart)
94 out.write(__CRLF);
95 inPart=true;
96 out.write(__DASHDASH);
97 out.write(boundaryBytes);
98 out.write(__CRLF);
99 if (contentType != null)
100 out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1));
101 out.write(__CRLF);
102 out.write(__CRLF);
103 }
104
105 /* ------------------------------------------------------------ */
106 /** Start creation of the next Content.
107 */
108 public void startPart(String contentType, String[] headers)
109 throws IOException
110 {
111 if (inPart)
112 out.write(__CRLF);
113 inPart=true;
114 out.write(__DASHDASH);
115 out.write(boundaryBytes);
116 out.write(__CRLF);
117 if (contentType != null)
118 out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1));
119 out.write(__CRLF);
120 for (int i=0;headers!=null && i<headers.length;i++)
121 {
122 out.write(headers[i].getBytes(StringUtil.__ISO_8859_1));
123 out.write(__CRLF);
124 }
125 out.write(__CRLF);
126 }
127
128 /* ------------------------------------------------------------ */
129 @Override
130 public void write(byte[] b, int off, int len) throws IOException
131 {
132 out.write(b,off,len);
133 }
134 }
135
136
137
138