All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.xfa.protocol.HttpForm Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright 2005 Adobe Systems Incorporated All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains the property of
 * Adobe Systems Incorporated and its suppliers, if any. The intellectual and
 * technical concepts contained herein are proprietary to Adobe Systems
 * Incorporated and its suppliers and may be covered by U.S. and Foreign
 * Patents, patents in process, and are protected by trade secret or copyright
 * law. Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained from
 * Adobe Systems Incorporated.
 */
package com.adobe.xfa.protocol;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.adobe.xfa.ut.ExFull;
import com.adobe.xfa.ut.FindBugsSuppress;
import com.adobe.xfa.ut.MsgFormat;
import com.adobe.xfa.ut.ResId;
import com.adobe.xfa.ut.Resolver;
import com.adobe.xfa.ut.StringHolder;
import com.adobe.xfa.ut.StringUtils;



/**
 * The class HttpForm is designed to post form data to an HTTP(S)
 * server.
 * The data being posted can be in one of three formats:
 * 
    *
  • content type: application/x-www-form-urlencoded. * posting urlencoded name-value pairs, *
  • content type: MIME-type. * for posting user-specified content, and *
  • content type: multipart/form-data. * for posting multipart data. *
* *

Here's a snippet of code illustrating the post of * name value pairs. *

 *     HttpForm oForm = new HttpForm();
 *     oForm.SetEncodingType(HttpForm.PostEncodingType.URL_ENCODING);
 *     oForm.AddNameValuePair("fubar", "not yet");
 *     oForm.AddNameValuePair("name", "value");
 *     oForm.AddNameValuePair("submit", "now");
 *     oForm.Post("http://tools_build/scripts/ReadAll.asp");
 *     int nStatus = oForm.GetResponseCode();
 *     String sContentType = oForm.GetResponseType();
 *     String sGotten = oForm.GetResponse();
 *     ...
 * 
* *

Here's another snippet of code illustrating the post of * data in a user-specified content type and character set. *

 *     HttpForm oForm = new HttpForm();
 *     String sSent = 
 *         "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
 *         "<form>" +
 *         "<name first=\"\u00D4l\u00EAg\" last=\"\u00DC\u00C7ml\u00E6t\"" +
 *         "</name>" +
 *         "</form>";
 *     oForm.SetEncodingType(HttpForm.PostEncodingType.USER_ENCODING);
 *     oForm.AddEncodedData(sSent.getBytes("UTF-8"), "text/xml", "utf-8");
 *     oForm.Post("http://tools_build/scripts/ReadAll.asp");
 *     int nStatus = oForm.GetResponseCode();
 *     String sContentType = oForm.GetResponseType();
 *     String sGotten = oForm.GetResponse();
 *     ...
 * 
* *

Here's another snippet of code illustrating the post of * multipart data in a user-specified content type and character set. *

 *     HttpForm oForm = new HttpForm();
 *     oForm.SetEncodingType(HttpForm.PostEncodingType.MULTIPART_ENCODING);
 *     oForm.AddMultipartData(Protocol.SectionDataOption.SECTION_CONTENT_NAME, "fubar".getBytes("US-ASCII"));
 *     oForm.AddMultipartData(Protocol.SectionDataOption.SECTION_CONTENT_VALUE, "not!".getBytes("US-ASCII"));
 *     oForm.AddMultipartData(Protocol.SectionDataOption.SECTION_END, null);
 *     oForm.AddMultipartData(Protocol.SectionDataOption.SECTION_CONTENT_FILE, "protocol/test.html".getBytes("US-ASCII"));
 *     oForm.AddMultipartData(Protocol.SectionDataOption.SECTION_END, null);
 *     oForm.AddMultipartData(Protocol.SectionDataOption.SECTION_CONTENT_NAME, "lotto".getBytes("US-ASCII"));
 *     oForm.AddMultipartData(Protocol.SectionDataOption.SECTION_CONTENT_FILE, "protocol/lotto.wsdl".getBytes("US-ASCII"));
 *     oForm.AddMultipartData(Protocol.SectionDataOption.SECTION_END, null);
 *     oForm.Post(sUrl);
 *     int nStatus = oForm.GetResponseCode();
 *     String sContentType = oForm.GetResponseType();
 *     String sGotten = oForm.GetResponse();
 *     ...
 * 
* * Author: * Mike P. Tardif * * @exclude from published api. */ public class HttpForm { /** @exclude from published api. */ public enum PostEncodingType { UNKNOWN_ENCODING, // used internally as a sentinel. URL_ENCODING, // application/x-www-form-urlencoded. USER_ENCODING, // user specified content type. MULTIPART_ENCODING,// multipart/form-data. LAST_ENCODING // used internally as a sentinel. } public static final int ChunkSize = (1024 * 4); public static final int MixedSize = (1024 / 32); private PostEncodingType meEncoding = PostEncodingType.UNKNOWN_ENCODING; private String msContentType; private String msCharSet; private Map msHeaderMap; // for post data. private ByteArrayOutputStream mPairs; private ByteArrayOutputStream mChunk; private List moMulti; // for post responses. private byte[] mRespData; private int mnRespCode; private String msRespType; /** * The default c'tor -- instantiate a HttpForm object. */ public HttpForm() { } /** * Set encoding type. One of *
    *
  • URL_ENCODING * for posting urlencoded name-value pairs -- * (content type: application/x-www-form-urlencoded), *
  • USER_ENCODING * for posting user-specified content, and *
  • MULTIPART_ENCODING * for posting multipart data -- * (content type: multipart/form-data) *
* *

Resetting this property clears any previously accumulated * form data. * *

Should be called before AddData() is called. * @param ePostEncodingType the encoding type */ public void setEncodingType(PostEncodingType ePostEncodingType) { meEncoding = ePostEncodingType; moMulti = null; msCharSet = null; mChunk = null; msContentType = null; if (msHeaderMap != null) msHeaderMap.clear(); if (mPairs != null) mPairs.reset(); msRespType = null; mnRespCode = 0; } /** * Add the given (non-urlencoded) name=value pair to the form * data being accumulated. The name=value pair will be suitably * urlencoded, and appended to the data being posted. * *

This method can be called repeatedly to add to the form's * data whenever the encoding-type is * application/x-www-form-urlencoded. * @param name the name * @param value the value */ @FindBugsSuppress(code="NP") public void addNameValuePair(String name, String value) { assert(meEncoding != PostEncodingType.MULTIPART_ENCODING); if (StringUtils.isEmpty(msContentType)) msContentType = "text/plain"; byte[] encodedName = null; byte[] encodedValue = null; try { encodedName = ProtocolUtils.urlEncode(name).getBytes("US-ASCII"); encodedValue = ProtocolUtils.urlEncode(value).getBytes("US-ASCII"); } catch (UnsupportedEncodingException ignored) { // Not possible - US-ASCII is always supported } try { if (mPairs == null) mPairs = new ByteArrayOutputStream(); else mPairs.write('&'); mPairs.write(encodedName); mPairs.write('='); mPairs.write(encodedValue); } catch (IOException ignored) { // not possible } } /** * Add the given encoded data to the form data being accumulated. * The encoded data will be appended to the data being posted * provided the content type doesn't change. * *

This method can be called repeatedly to add to the form's data. * @param encodedData the encoded data to add * @param sContentType optional content type for the data * @param sCharSet optional character set for the data */ public void addEncodedData(byte[] encodedData, String sContentType, String sCharSet) { assert(meEncoding != PostEncodingType.MULTIPART_ENCODING); if (StringUtils.isEmpty(msContentType) && !StringUtils.isEmpty(sContentType)) msContentType = sContentType; if (StringUtils.isEmpty(msCharSet) && !StringUtils.isEmpty(sCharSet)) msCharSet = sCharSet; if (encodedData != null) { if (mChunk == null) mChunk = new ByteArrayOutputStream(); try { mChunk.write(encodedData); } catch (IOException ignored) { // not possible } } } /** * Add a key-value pair to the header data *

This method can be called repeatedly to add to the header data. * @param sKey the header type (Content-Type, charset etc.) * @param sValue the header value */ public void addHeaderData(String sKey, String sValue) { if (msHeaderMap == null) msHeaderMap = new HashMap(); msHeaderMap.put(sKey, sValue); } /** * Add the given multipart section to the form data being accumulated. * *

This method can be called repeatedly to add to the form's data * whenever the encoding-type is multipart/form-data. * Each call creates a separate section of multipart data. * *

The section description will allow the user to specify any one * of: *

    *
  • the content name, *
  • the content type, *
  • the content origin (memory or file), *
  • the content length. *
for each section. * @param eOption the section type * @param value the value */ public void addMultipartData(Protocol.SectionDataOption eOption, byte[] value) { Protocol.MultiPartDesc oDesc = new Protocol.MultiPartDesc(eOption, value); if (moMulti == null) moMulti = new ArrayList(); moMulti.add(oDesc); } /** * Post accumulated form data to a designated URL. * @param sUrl The designated URL */ public void post(String sUrl) { assert(meEncoding != PostEncodingType.UNKNOWN_ENCODING); StringHolder sScheme = new StringHolder(); StringHolder sUser = new StringHolder(); StringHolder sPwd = new StringHolder(); StringHolder sHost = new StringHolder(); StringHolder sPort = new StringHolder(); StringHolder sPath = new StringHolder(); Resolver.crackUrl(sUrl, sScheme, sUser, sPwd, sHost, sPort, sPath); Protocol oProtocol = Resolver.getProtocol(sScheme.value); if (oProtocol == null) { throw new ExFull(new MsgFormat(ResId.STREAM_PROTOCOL_NOT_AVAIL)); } Protocol.PostRsvp oRsvp = null; if (meEncoding == PostEncodingType.URL_ENCODING) { Protocol.SimplePostData oData = new Protocol.SimplePostData(mPairs.toByteArray()); mPairs = null; // // Post data to url and get response. // oRsvp = oProtocol.post(oData, sUrl); } else if (meEncoding == PostEncodingType.USER_ENCODING && mChunk != null && mChunk.size() > 0) { Protocol.SimplePostData oData = new Protocol.SimplePostData(mChunk.toByteArray()); StringBuilder sHead = new StringBuilder(); if (StringUtils.isEmpty(msContentType)) { sHead.append("application/octet-stream"); } else { sHead.append(msContentType); if (!StringUtils.isEmpty(msCharSet)) sHead.append("; charset=").append(msCharSet); } oData.headerMap.put("Content-Type", sHead.toString()); if ((msHeaderMap != null) && (msHeaderMap.size() > 0)) { oData.headerMap.putAll(msHeaderMap); } // // Post data to url and get response. // oRsvp = oProtocol.post(oData, sUrl); mChunk = null; } else if ((meEncoding == PostEncodingType.MULTIPART_ENCODING) && (moMulti != null)) { // // Post data to url and get response. // oRsvp = oProtocol.post(moMulti, sUrl); } // // Squirrel away responses. // if (oRsvp != null) { mnRespCode = oRsvp.nCode; msRespType = oRsvp.sType; mRespData = oRsvp.data; if (oRsvp.exception != null) { throw oRsvp.exception; // throw exception after response data populated } } } /** * Get the data response from the last post. This excludes * all response headers. * *

Calling this method is only meaningful after a Post(). * * @return the response data */ @FindBugsSuppress(code="EI") public byte[] getResponse() { return mRespData; } /** * Get the status code response from the last post. * *

Calling this method is only meaningful after a Post(). * @return the response code */ public int getResponseCode() { return mnRespCode; } /** * Get the content type response from the last post. * *

Calling this method is only meaningful after a Post(). * @return the response type */ public String getResponseType() { return msRespType; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy