/*==========================================================================*\ | $Id: MultipartBuilder.java,v 1.1 2010/03/02 18:38:53 aallowat Exp $ |*-------------------------------------------------------------------------*| | Copyright (C) 2006-2009 Virginia Tech | | This file is part of Web-CAT Electronic Submitter. | | Web-CAT is free software; you can redistribute it and/or modify | it under the terms of the GNU General Public License as published by | the Free Software Foundation; either version 2 of the License, or | (at your option) any later version. | | Web-CAT is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU General Public License along | with Web-CAT; if not, see <http://www.gnu.org/licenses/>. \*==========================================================================*/ package org.webcat.submitter.internal.utility; import java.io.IOException; import java.io.OutputStream; import java.net.HttpURLConnection; import java.util.Random; //-------------------------------------------------------------------------- /** * A utility class to aid in the construction of an HTTP POST multipart * request. * * @author Tony Allevato (Virginia Tech Computer Science) * @author latest changes by: $Author: aallowat $ * @version $Revision: 1.1 $ $Date: 2010/03/02 18:38:53 $ */ public class MultipartBuilder { //~ Constructors .......................................................... // ---------------------------------------------------------- /** * Generates a new multipart request builder attached to the specified * connection. * * @param con the connection that to which the multipart request will be * sent * @throws IOException if any I/O errors occur */ public MultipartBuilder(HttpURLConnection con) throws IOException { connection = con; connection.setDoInput(true); connection.setDoOutput(true); connection.setUseCaches(false); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString); outStream = connection.getOutputStream(); } //~ Methods ............................................................... // ---------------------------------------------------------- /** * Writes a boundary separator between parts of the request. * * @throws IOException if any I/O errors occur */ private void writeBoundary() throws IOException { write("--"); write(boundaryString); } // ---------------------------------------------------------- /** * Writes a character to the request. * * @param c the character to write to the request * @throws IOException if any I/O exceptions occur */ protected void write(char c) throws IOException { outStream.write(c); } // ---------------------------------------------------------- /** * Writes a string to the request. * * @param s the String to write to the request * @throws IOException if any I/O exceptions occur */ protected void write(String s) throws IOException { outStream.write(s.getBytes()); } // ---------------------------------------------------------- /** * Writes a carriage return/line feed pair to the request. * * @throws IOException if any I/O errors occur. */ protected void newline() throws IOException { write("\r\n"); } // ---------------------------------------------------------- /** * Writes a string to the request, followed by a newline. * * @param s the String to write to the request * @throws IOException if any I/O errors occur */ protected void writeln(String s) throws IOException { write(s); newline(); } // ---------------------------------------------------------- /** * Writes the name of a part of this request. * * @param name the name of the part of the request * @throws IOException if any I/O errors occur */ private void writeName(String name) throws IOException { newline(); write("Content-Disposition: form-data; name=\""); write(name); write('"'); } // ---------------------------------------------------------- /** * Adds a parameter name/value pair to the request. * * @param name the name of the parameter * @param value the value of the parameter * @throws IOException if any I/O errors occur */ public void writeParameter(String name, String value) throws IOException { writeBoundary(); writeName(name); newline(); newline(); writeln(value); } // ---------------------------------------------------------- /** * Adds the appropriate headers for a file attachment to the request. * * @param name the name of the request parameter * @param filename the name of the file attachment * @param contentType the MIME content type of the attachment * @return the OutputStream to which the file can be written * @throws IOException if any I/O errors occur */ public OutputStream beginWriteFile(String name, String filename, String contentType) throws IOException { writeBoundary(); writeName(name); write("; filename=\""); write(filename); write('"'); newline(); write("Content-Type: "); writeln(contentType); newline(); return outStream; } // ---------------------------------------------------------- /** * Completes the file attachment operation begun by * {@link #beginWriteFile(String, String, String)}. * * @throws IOException if any I/O errors occur */ public void endWriteFile() throws IOException { newline(); } // ---------------------------------------------------------- /** * Completes the multipart request and closes the stream. * * @throws IOException if any I/O errors occur */ public void close() throws IOException { writeBoundary(); writeln("--"); outStream.close(); } // ---------------------------------------------------------- /** * Generates a string from a random long value converted to base 36 (0-9, * A-Z). * * @return a String generated from a random long value. */ private static String randomString() { return Long.toString(random.nextLong(), 36); } //~ Static/instance variables ............................................. /* The connection to which the request will be sent. */ private HttpURLConnection connection; /* The stream to which the request will be written. */ private OutputStream outStream; /* Random number generator. */ private static Random random = new Random(); /* Boundary string that separates different parts of the multipart request. */ private static final String boundaryString = "---------------------------" + randomString() + randomString() + randomString(); }