![JAR search and dependency download from the Maven repository](/logo.png)
com.adobe.xfa.protocol.HttpForm Maven / Gradle / Ivy
Show all versions of aem-sdk-api Show documentation
/*
* 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;
}
}