]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/util/MultiPartOutputStream.java
updating jetty to jetty-9.2.16.v2016040
[gigi.git] / lib / jetty / org / eclipse / jetty / util / MultiPartOutputStream.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2016 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 import java.nio.charset.StandardCharsets;
25
26
27 /* ================================================================ */
28 /** Handle a multipart MIME response.
29  *
30  * 
31  * 
32 */
33 public class MultiPartOutputStream extends FilterOutputStream
34 {
35     /* ------------------------------------------------------------ */
36     private static final byte[] __CRLF={'\r','\n'};
37     private static final byte[] __DASHDASH={'-','-'};
38     
39     public static final String MULTIPART_MIXED="multipart/mixed";
40     public static final String MULTIPART_X_MIXED_REPLACE="multipart/x-mixed-replace";
41     
42     /* ------------------------------------------------------------ */
43     private final String boundary;
44     private final byte[] boundaryBytes;
45
46     /* ------------------------------------------------------------ */
47     private boolean inPart=false;    
48     
49     /* ------------------------------------------------------------ */
50     public MultiPartOutputStream(OutputStream out)
51     throws IOException
52     {
53         super(out);
54
55         boundary = "jetty"+System.identityHashCode(this)+
56         Long.toString(System.currentTimeMillis(),36);
57         boundaryBytes=boundary.getBytes(StandardCharsets.ISO_8859_1);
58     }
59
60     public MultiPartOutputStream(OutputStream out, String boundary)
61          throws IOException
62     {
63         super(out);
64
65         this.boundary = boundary;
66         boundaryBytes=boundary.getBytes(StandardCharsets.ISO_8859_1);
67     }
68
69     /* ------------------------------------------------------------ */
70     /** End the current part.
71      * @exception IOException IOException
72      */
73     @Override
74     public void close()
75          throws IOException
76     {
77         try
78         {
79             if (inPart)
80                 out.write(__CRLF);
81             out.write(__DASHDASH);
82             out.write(boundaryBytes);
83             out.write(__DASHDASH);
84             out.write(__CRLF);
85             inPart=false;
86         }
87         finally
88         {
89             super.close();
90         }
91     }
92     
93     /* ------------------------------------------------------------ */
94     public String getBoundary()
95     {
96         return boundary;
97     }
98
99     public OutputStream getOut() {return out;}
100     
101     /* ------------------------------------------------------------ */
102     /** Start creation of the next Content.
103      */
104     public void startPart(String contentType)
105          throws IOException
106     {
107         if (inPart)
108             out.write(__CRLF);
109         inPart=true;
110         out.write(__DASHDASH);
111         out.write(boundaryBytes);
112         out.write(__CRLF);
113         if (contentType != null)
114             out.write(("Content-Type: "+contentType).getBytes(StandardCharsets.ISO_8859_1));
115         out.write(__CRLF);
116         out.write(__CRLF);
117     }
118         
119     /* ------------------------------------------------------------ */
120     /** Start creation of the next Content.
121      */
122     public void startPart(String contentType, String[] headers)
123          throws IOException
124     {
125         if (inPart)
126             out.write(__CRLF);
127         inPart=true;
128         out.write(__DASHDASH);
129         out.write(boundaryBytes);
130         out.write(__CRLF);
131         if (contentType != null)
132             out.write(("Content-Type: "+contentType).getBytes(StandardCharsets.ISO_8859_1));
133         out.write(__CRLF);
134         for (int i=0;headers!=null && i<headers.length;i++)
135         {
136             out.write(headers[i].getBytes(StandardCharsets.ISO_8859_1));
137             out.write(__CRLF);
138         }
139         out.write(__CRLF);
140     }
141
142     /* ------------------------------------------------------------ */
143     @Override
144     public void write(byte[] b, int off, int len) throws IOException
145     {
146         out.write(b,off,len);
147     }
148 }
149
150
151
152