1 /** 2 * Copyright 2014 Internet2 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 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 /* 17 * $Header: /home/hagleyj/i2mi/grouper-misc/grouperClient/src/ext/edu/internet2/middleware/grouperClientExt/org/apache/commons/httpclient/methods/MultipartPostMethod.java,v 1.1 2008-11-30 10:57:19 mchyzer Exp $ 18 * $Revision: 1.1 $ 19 * $Date: 2008-11-30 10:57:19 $ 20 * 21 * ==================================================================== 22 * 23 * Licensed to the Apache Software Foundation (ASF) under one or more 24 * contributor license agreements. See the NOTICE file distributed with 25 * this work for additional information regarding copyright ownership. 26 * The ASF licenses this file to You under the Apache License, Version 2.0 27 * (the "License"); you may not use this file except in compliance with 28 * the License. You may obtain a copy of the License at 29 * 30 * http://www.apache.org/licenses/LICENSE-2.0 31 * 32 * Unless required by applicable law or agreed to in writing, software 33 * distributed under the License is distributed on an "AS IS" BASIS, 34 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35 * See the License for the specific language governing permissions and 36 * limitations under the License. 37 * ==================================================================== 38 * 39 * This software consists of voluntary contributions made by many 40 * individuals on behalf of the Apache Software Foundation. For more 41 * information on the Apache Software Foundation, please see 42 * <http://www.apache.org/>. 43 * 44 */ 45 46 package edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.methods; 47 48 import java.io.File; 49 import java.io.FileNotFoundException; 50 import java.io.IOException; 51 import java.io.OutputStream; 52 import java.util.ArrayList; 53 import java.util.List; 54 55 import edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.HttpConnection; 56 import edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.HttpException; 57 import edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.HttpState; 58 import edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.methods.multipart.FilePart; 59 import edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.methods.multipart.Part; 60 import edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.methods.multipart.StringPart; 61 import edu.internet2.middleware.grouperClientExt.org.apache.commons.logging.Log; 62 import edu.internet2.middleware.grouperClientExt.org.apache.commons.logging.LogFactory; 63 64 /** 65 * Implements the HTTP multipart POST method. 66 * <p> 67 * The HTTP multipart POST method is defined in section 3.3 of 68 * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC1867</a>: 69 * <blockquote> 70 * The media-type multipart/form-data follows the rules of all multipart 71 * MIME data streams as outlined in RFC 1521. The multipart/form-data contains 72 * a series of parts. Each part is expected to contain a content-disposition 73 * header where the value is "form-data" and a name attribute specifies 74 * the field name within the form, e.g., 'content-disposition: form-data; 75 * name="xxxxx"', where xxxxx is the field name corresponding to that field. 76 * Field names originally in non-ASCII character sets may be encoded using 77 * the method outlined in RFC 1522. 78 * </blockquote> 79 * </p> 80 * <p> 81 * 82 * @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a> 83 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a> 84 * @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a> 85 * @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a> 86 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> 87 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> 88 * 89 * @since 2.0 90 * 91 * @deprecated Use {@link edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity} 92 * in conjunction with {@link edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.methods.PostMethod} instead. 93 */ 94 public class MultipartPostMethod extends ExpectContinueMethod { 95 96 /** The Content-Type for multipart/form-data. */ 97 public static final String MULTIPART_FORM_CONTENT_TYPE = 98 "multipart/form-data"; 99 100 /** Log object for this class. */ 101 private static final Log LOG = LogFactory.getLog(MultipartPostMethod.class); 102 103 /** The parameters for this method */ 104 private final List parameters = new ArrayList(); 105 106 /** 107 * No-arg constructor. 108 */ 109 public MultipartPostMethod() { 110 super(); 111 } 112 113 /** 114 * Constructor specifying a URI. 115 * 116 * @param uri either an absolute or relative URI 117 */ 118 public MultipartPostMethod(String uri) { 119 super(uri); 120 } 121 122 /** 123 * Returns <tt>true</tt> 124 * 125 * @return <tt>true</tt> 126 * 127 * @since 2.0beta1 128 */ 129 protected boolean hasRequestContent() { 130 return true; 131 } 132 133 /** 134 * Returns <tt>"POST"</tt>. 135 * @return <tt>"POST"</tt> 136 */ 137 public String getName() { 138 return "POST"; 139 } 140 141 /** 142 * Adds a text field part 143 * 144 * @param parameterName The name of the parameter. 145 * @param parameterValue The value of the parameter. 146 */ 147 public void addParameter(String parameterName, String parameterValue) { 148 LOG.trace("enter addParameter(String parameterName, String parameterValue)"); 149 Part param = new StringPart(parameterName, parameterValue); 150 parameters.add(param); 151 } 152 153 /** 154 * Adds a binary file part 155 * 156 * @param parameterName The name of the parameter 157 * @param parameterFile The name of the file. 158 * @throws FileNotFoundException If the file cannot be found. 159 */ 160 public void addParameter(String parameterName, File parameterFile) 161 throws FileNotFoundException { 162 LOG.trace("enter MultipartPostMethod.addParameter(String parameterName, " 163 + "File parameterFile)"); 164 Part param = new FilePart(parameterName, parameterFile); 165 parameters.add(param); 166 } 167 168 /** 169 * Adds a binary file part with the given file name 170 * 171 * @param parameterName The name of the parameter 172 * @param fileName The file name 173 * @param parameterFile The file 174 * @throws FileNotFoundException If the file cannot be found. 175 */ 176 public void addParameter(String parameterName, String fileName, File parameterFile) 177 throws FileNotFoundException { 178 LOG.trace("enter MultipartPostMethod.addParameter(String parameterName, " 179 + "String fileName, File parameterFile)"); 180 Part param = new FilePart(parameterName, fileName, parameterFile); 181 parameters.add(param); 182 } 183 184 /** 185 * Adds a part. 186 * 187 * @param part The part to add. 188 */ 189 public void addPart (final Part part) { 190 LOG.trace("enter addPart(Part part)"); 191 parameters.add(part); 192 } 193 194 /** 195 * Returns all parts. 196 * 197 * @return an array of containing all parts 198 */ 199 public Part[] getParts() { 200 return (Part/grouperClientExt/org/apache/commons/httpclient/methods/multipart/Part.html#Part">Part[]) parameters.toArray(new Part[parameters.size()]); 201 } 202 203 /** 204 * Adds a <tt>Content-Length</tt> request header, as long as no 205 * <tt>Content-Length</tt> request header already exists. 206 * 207 * @param state current state of http requests 208 * @param conn the connection to use for I/O 209 * 210 * @throws IOException if an I/O (transport) error occurs. Some transport exceptions 211 * can be recovered from. 212 * @throws HttpException if a protocol exception occurs. Usually protocol exceptions 213 * cannot be recovered from. 214 * 215 * @since 3.0 216 */ 217 protected void addContentLengthRequestHeader(HttpState state, 218 HttpConnection conn) 219 throws IOException, HttpException { 220 LOG.trace("enter EntityEnclosingMethod.addContentLengthRequestHeader(" 221 + "HttpState, HttpConnection)"); 222 223 if (getRequestHeader("Content-Length") == null) { 224 long len = getRequestContentLength(); 225 addRequestHeader("Content-Length", String.valueOf(len)); 226 } 227 removeRequestHeader("Transfer-Encoding"); 228 } 229 230 /** 231 * Adds a <tt>Content-Type</tt> request header. 232 * 233 * @param state current state of http requests 234 * @param conn the connection to use for I/O 235 * 236 * @throws IOException if an I/O (transport) error occurs. Some transport exceptions 237 * can be recovered from. 238 * @throws HttpException if a protocol exception occurs. Usually protocol exceptions 239 * cannot be recovered from. 240 * 241 * @since 3.0 242 */ 243 protected void addContentTypeRequestHeader(HttpState state, 244 HttpConnection conn) 245 throws IOException, HttpException { 246 LOG.trace("enter EntityEnclosingMethod.addContentTypeRequestHeader(" 247 + "HttpState, HttpConnection)"); 248 249 if (!parameters.isEmpty()) { 250 StringBuffer buffer = new StringBuffer(MULTIPART_FORM_CONTENT_TYPE); 251 if (Part.getBoundary() != null) { 252 buffer.append("; boundary="); 253 buffer.append(Part.getBoundary()); 254 } 255 setRequestHeader("Content-Type", buffer.toString()); 256 } 257 } 258 259 /** 260 * Populates the request headers map to with additional 261 * {@link edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.Header headers} to be submitted to 262 * the given {@link HttpConnection}. 263 * 264 * <p> 265 * This implementation adds tt>Content-Length</tt> and <tt>Content-Type</tt> 266 * headers, when appropriate. 267 * </p> 268 * 269 * <p> 270 * Subclasses may want to override this method to to add additional 271 * headers, and may choose to invoke this implementation (via 272 * <tt>super</tt>) to add the "standard" headers. 273 * </p> 274 * 275 * @param state the {@link HttpState state} information associated with this method 276 * @param conn the {@link HttpConnection connection} used to execute 277 * this HTTP method 278 * 279 * @throws IOException if an I/O (transport) error occurs. Some transport exceptions 280 * can be recovered from. 281 * @throws HttpException if a protocol exception occurs. Usually protocol exceptions 282 * cannot be recovered from. 283 * 284 * @see #writeRequestHeaders 285 */ 286 protected void addRequestHeaders(HttpState state, HttpConnection conn) 287 throws IOException, HttpException { 288 LOG.trace("enter MultipartPostMethod.addRequestHeaders(HttpState state, " 289 + "HttpConnection conn)"); 290 super.addRequestHeaders(state, conn); 291 addContentLengthRequestHeader(state, conn); 292 addContentTypeRequestHeader(state, conn); 293 } 294 295 /** 296 * Writes the request body to the given {@link HttpConnection connection}. 297 * 298 * @param state the {@link HttpState state} information associated with this method 299 * @param conn the {@link HttpConnection connection} used to execute 300 * this HTTP method 301 * 302 * @return <tt>true</tt> 303 * 304 * @throws IOException if an I/O (transport) error occurs. Some transport exceptions 305 * can be recovered from. 306 * @throws HttpException if a protocol exception occurs. Usually protocol exceptions 307 * cannot be recovered from. 308 */ 309 protected boolean writeRequestBody(HttpState state, HttpConnection conn) 310 throws IOException, HttpException { 311 LOG.trace("enter MultipartPostMethod.writeRequestBody(HttpState state, " 312 + "HttpConnection conn)"); 313 OutputStream out = conn.getRequestOutputStream(); 314 Part.sendParts(out, getParts()); 315 return true; 316 } 317 318 /** 319 * <p>Return the length of the request body.</p> 320 * 321 * <p>Once this method has been invoked, the request parameters cannot be 322 * altered until the method is {@link #recycle recycled}.</p> 323 * 324 * @return The request content length. 325 */ 326 protected long getRequestContentLength() throws IOException { 327 LOG.trace("enter MultipartPostMethod.getRequestContentLength()"); 328 return Part.getLengthOfParts(getParts()); 329 } 330 331 332 /** 333 * Recycles the HTTP method so that it can be used again. 334 * Note that all of the instance variables will be reset 335 * once this method has been called. This method will also 336 * release the connection being used by this HTTP method. 337 * 338 * @see #releaseConnection() 339 * 340 * @deprecated no longer supported and will be removed in the future 341 * version of HttpClient 342 */ 343 public void recycle() { 344 LOG.trace("enter MultipartPostMethod.recycle()"); 345 super.recycle(); 346 parameters.clear(); 347 } 348 }