View Javadoc

    1   // ========================================================================
    2   // Copyright 1996-2005 Mort Bay Consulting Pty. Ltd.
    3   // ------------------------------------------------------------------------
    4   // Licensed under the Apache License, Version 2.0 (the "License");
    5   // you may not use this file except in compliance with the License.
    6   // You may obtain a copy of the License at
    7   // http://www.apache.org/licenses/LICENSE-2.0
    8   // Unless required by applicable law or agreed to in writing, software
    9   // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  // ========================================================================
    14
    15  package org.mortbay.util;
    16
    17  import java.io.FilterOutputStream;
    18  import java.io.IOException;
    19  import java.io.OutputStream;
    20
    21
    22  /* ================================================================ */
    23  /** Handle a multipart MIME response.
    24   *
    25   * @author Greg Wilkins
    26   * @author Jim Crossley
    27  */
    28  public class MultiPartOutputStream extends FilterOutputStream
    29  {
    30      /* ------------------------------------------------------------ */
    31      private static byte[] __CRLF;
    32      private static byte[] __DASHDASH;
    33
    34      public static String MULTIPART_MIXED="multipart/mixed";
    35      public static String MULTIPART_X_MIXED_REPLACE="multipart/x-mixed-replace";
    36      static
    37      {
    38          try
    39          {
    40              __CRLF="\015\012".getBytes(StringUtil.__ISO_8859_1);
    41              __DASHDASH="--".getBytes(StringUtil.__ISO_8859_1);
    42          }
    43          catch (Exception e) {e.printStackTrace(); System.exit(1);}
    44      }
    45
    46      /* ------------------------------------------------------------ */
    47      private String boundary;
    48      private byte[] boundaryBytes;
    49
    50      /* ------------------------------------------------------------ */
    51      private boolean inPart=false;
    52
    53      /* ------------------------------------------------------------ */
    54      public MultiPartOutputStream(OutputStream out)
    55      throws IOException
    56      {
    57          super(out);
    58
    59          boundary = "jetty"+System.identityHashCode(this)+
    60          Long.toString(System.currentTimeMillis(),36);
    61          boundaryBytes=boundary.getBytes(StringUtil.__ISO_8859_1);
    62
    63          inPart=false;
    64      }
    65
    66
    67
    68      /* ------------------------------------------------------------ */
    69      /** End the current part.
    70       * @exception IOException IOException
    71       */
    72      public void close()
    73           throws IOException
    74      {
    75          if (inPart)
    76              out.write(__CRLF);
    77          out.write(__DASHDASH);
    78          out.write(boundaryBytes);
    79          out.write(__DASHDASH);
    80          out.write(__CRLF);
    81          inPart=false;
    82          super.close();
    83      }
    84
    85      /* ------------------------------------------------------------ */
    86      public String getBoundary()
    87      {
    88          return boundary;
    89      }
    90
    91      public OutputStream getOut() {return out;}
    92
    93      /* ------------------------------------------------------------ */
    94      /** Start creation of the next Content.
    95       */
    96      public void startPart(String contentType)
    97           throws IOException
    98      {
    99          if (inPart)
    100             out.write(__CRLF);
    101         inPart=true;
    102         out.write(__DASHDASH);
    103         out.write(boundaryBytes);
    104         out.write(__CRLF);
    105         out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1));
    106         out.write(__CRLF);
    107         out.write(__CRLF);
    108     }
    109
    110     /* ------------------------------------------------------------ */
    111     /** Start creation of the next Content.
    112      */
    113     public void startPart(String contentType, String[] headers)
    114          throws IOException
    115     {
    116         if (inPart)
    117             out.write(__CRLF);
    118         inPart=true;
    119         out.write(__DASHDASH);
    120         out.write(boundaryBytes);
    121         out.write(__CRLF);
    122         out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1));
    123         out.write(__CRLF);
    124         for (int i=0;headers!=null && i<headers.length;i++)
    125         {
    126             out.write(headers[i].getBytes(StringUtil.__ISO_8859_1));
    127             out.write(__CRLF);
    128         }
    129         out.write(__CRLF);
    130     }
    131
    132 }
    133
    134
    135
    136