| Method from org.apache.commons.httpclient.HttpMethodBase Detail: |
public void abort() {
if (this.aborted) {
return;
}
this.aborted = true;
HttpConnection conn = this.responseConnection;
if (conn != null) {
conn.close();
}
}
Aborts the execution of this method. |
protected void addCookieRequestHeader(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace("enter HttpMethodBase.addCookieRequestHeader(HttpState, "
+ "HttpConnection)");
Header[] cookieheaders = getRequestHeaderGroup().getHeaders("Cookie");
for (int i = 0; i < cookieheaders.length; i++) {
Header cookieheader = cookieheaders[i];
if (cookieheader.isAutogenerated()) {
getRequestHeaderGroup().removeHeader(cookieheader);
}
}
CookieSpec matcher = getCookieSpec(state);
String host = this.params.getVirtualHost();
if (host == null) {
host = conn.getHost();
}
Cookie[] cookies = matcher.match(host, conn.getPort(),
getPath(), conn.isSecure(), state.getCookies());
if ((cookies != null) && (cookies.length > 0)) {
if (getParams().isParameterTrue(HttpMethodParams.SINGLE_COOKIE_HEADER)) {
// In strict mode put all cookies on the same header
String s = matcher.formatCookies(cookies);
getRequestHeaderGroup().addHeader(new Header("Cookie", s, true));
} else {
// In non-strict mode put each cookie on a separate header
for (int i = 0; i < cookies.length; i++) {
String s = matcher.formatCookie(cookies[i]);
getRequestHeaderGroup().addHeader(new Header("Cookie", s, true));
}
}
if (matcher instanceof CookieVersionSupport) {
CookieVersionSupport versupport = (CookieVersionSupport) matcher;
int ver = versupport.getVersion();
boolean needVersionHeader = false;
for (int i = 0; i < cookies.length; i++) {
if (ver != cookies[i].getVersion()) {
needVersionHeader = true;
}
}
if (needVersionHeader) {
// Advertise cookie version support
getRequestHeaderGroup().addHeader(versupport.getVersionHeader());
}
}
}
}
Generates Cookie request headers for those cookie s
that match the given host, port and path. |
protected void addHostRequestHeader(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace("enter HttpMethodBase.addHostRequestHeader(HttpState, "
+ "HttpConnection)");
// Per 19.6.1.1 of RFC 2616, it is legal for HTTP/1.0 based
// applications to send the Host request-header.
// TODO: Add the ability to disable the sending of this header for
// HTTP/1.0 requests.
String host = this.params.getVirtualHost();
if (host != null) {
LOG.debug("Using virtual host name: " + host);
} else {
host = conn.getHost();
}
int port = conn.getPort();
// Note: RFC 2616 uses the term "internet host name" for what goes on the
// host line. It would seem to imply that host should be blank if the
// host is a number instead of an name. Based on the behavior of web
// browsers, and the fact that RFC 2616 never defines the phrase "internet
// host name", and the bad behavior of HttpClient that follows if we
// send blank, I interpret this as a small misstatement in the RFC, where
// they meant to say "internet host". So IP numbers get sent as host
// entries too. -- Eric Johnson 12/13/2002
if (LOG.isDebugEnabled()) {
LOG.debug("Adding Host request header");
}
//appends the port only if not using the default port for the protocol
if (conn.getProtocol().getDefaultPort() != port) {
host += (":" + port);
}
setRequestHeader("Host", host);
}
Generates Host request header, as long as no Host request
header already exists. |
protected void addProxyConnectionHeader(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace("enter HttpMethodBase.addProxyConnectionHeader("
+ "HttpState, HttpConnection)");
if (!conn.isTransparent()) {
if (getRequestHeader("Proxy-Connection") == null) {
addRequestHeader("Proxy-Connection", "Keep-Alive");
}
}
}
Generates Proxy-Connection: Keep-Alive request header when
communicating via a proxy server. |
public void addRequestHeader(Header header) {
LOG.trace("HttpMethodBase.addRequestHeader(Header)");
if (header == null) {
LOG.debug("null header value ignored");
} else {
getRequestHeaderGroup().addHeader(header);
}
}
Adds the specified request header, NOT overwriting any previous value.
Note that header-name matching is case insensitive. |
public void addRequestHeader(String headerName,
String headerValue) {
addRequestHeader(new Header(headerName, headerValue));
}
Adds the specified request header, NOT overwriting any previous value.
Note that header-name matching is case insensitive. |
protected void addRequestHeaders(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace("enter HttpMethodBase.addRequestHeaders(HttpState, "
+ "HttpConnection)");
addUserAgentRequestHeader(state, conn);
addHostRequestHeader(state, conn);
addCookieRequestHeader(state, conn);
addProxyConnectionHeader(state, conn);
}
Generates all the required request header s
to be submitted via the given connection .
This implementation adds User-Agent, Host,
Cookie, Authorization, Proxy-Authorization
and Proxy-Connection headers, when appropriate.
Subclasses may want to override this method to to add additional
headers, and may choose to invoke this implementation (via
super) to add the "standard" headers.
|
public void addResponseFooter(Header footer) {
getResponseTrailerHeaderGroup().addHeader(footer);
}
Use this method internally to add footers. |
protected void addUserAgentRequestHeader(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace("enter HttpMethodBase.addUserAgentRequestHeaders(HttpState, "
+ "HttpConnection)");
if (getRequestHeader("User-Agent") == null) {
String agent = (String)getParams().getParameter(HttpMethodParams.USER_AGENT);
if (agent == null) {
agent = "Jakarta Commons-HttpClient";
}
setRequestHeader("User-Agent", agent);
}
}
Generates default User-Agent request header, as long as no
User-Agent request header already exists. |
protected void checkNotUsed() throws IllegalStateException {
if (used) {
throw new IllegalStateException("Already used.");
}
}
|
protected void checkUsed() throws IllegalStateException {
if (!used) {
throw new IllegalStateException("Not Used.");
}
}
|
public int execute(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace("enter HttpMethodBase.execute(HttpState, HttpConnection)");
// this is our connection now, assign it to a local variable so
// that it can be released later
this.responseConnection = conn;
checkExecuteConditions(state, conn);
this.statusLine = null;
this.connectionCloseForced = false;
conn.setLastResponseInputStream(null);
// determine the effective protocol version
if (this.effectiveVersion == null) {
this.effectiveVersion = this.params.getVersion();
}
writeRequest(state, conn);
this.requestSent = true;
readResponse(state, conn);
// the method has successfully executed
used = true;
return statusLine.getStatusCode();
}
Executes this method using the specified HttpConnection and
HttpState. |
void fakeResponse(StatusLine statusline,
HeaderGroup responseheaders,
InputStream responseStream) {
// set used so that the response can be read
this.used = true;
this.statusLine = statusline;
this.responseHeaders = responseheaders;
this.responseBody = null;
this.responseStream = responseStream;
}
This method is a dirty hack intended to work around
current (2.0) design flaw that prevents the user from
obtaining correct status code, headers and response body from the
preceding HTTP CONNECT method.
TODO: Remove this crap as soon as possible |
protected static String generateRequestLine(HttpConnection connection,
String name,
String requestPath,
String query,
String version) {
LOG.trace("enter HttpMethodBase.generateRequestLine(HttpConnection, "
+ "String, String, String, String)");
StringBuffer buf = new StringBuffer();
// Append method name
buf.append(name);
buf.append(" ");
// Absolute or relative URL?
if (!connection.isTransparent()) {
Protocol protocol = connection.getProtocol();
buf.append(protocol.getScheme().toLowerCase());
buf.append("://");
buf.append(connection.getHost());
if ((connection.getPort() != -1)
&& (connection.getPort() != protocol.getDefaultPort())
) {
buf.append(":");
buf.append(connection.getPort());
}
}
// Append path, if any
if (requestPath == null) {
buf.append("/");
} else {
if (!connection.isTransparent() && !requestPath.startsWith("/")) {
buf.append("/");
}
buf.append(requestPath);
}
// Append query, if any
if (query != null) {
if (query.indexOf("?") != 0) {
buf.append("?");
}
buf.append(query);
}
// Append protocol
buf.append(" ");
buf.append(version);
buf.append("\r\n");
return buf.toString();
}
Generates HTTP request line according to the specified attributes. |
public String getAuthenticationRealm() {
return this.hostAuthState.getRealm();
} Deprecated! use - #getHostAuthState()
Returns authentication realm, if it has been used during authentication process.
Otherwise returns null. |
protected String getContentCharSet(Header contentheader) {
LOG.trace("enter getContentCharSet( Header contentheader )");
String charset = null;
if (contentheader != null) {
HeaderElement values[] = contentheader.getElements();
// I expect only one header element to be there
// No more. no less
if (values.length == 1) {
NameValuePair param = values[0].getParameterByName("charset");
if (param != null) {
// If I get anything "funny"
// UnsupportedEncondingException will result
charset = param.getValue();
}
}
}
if (charset == null) {
charset = getParams().getContentCharset();
if (LOG.isDebugEnabled()) {
LOG.debug("Default charset used: " + charset);
}
}
return charset;
}
Returns the character set from the Content-Type header. |
public boolean getDoAuthentication() {
return doAuthentication;
}
Returns true if the HTTP method should automatically handle HTTP
authentication challenges (status code 401, etc.), false otherwise |
public HttpVersion getEffectiveVersion() {
return this.effectiveVersion;
}
Returns the HTTP version used with this method (may be null
if undefined, that is, the method has not been executed) |
public boolean getFollowRedirects() {
return this.followRedirects;
}
Returns true if the HTTP method should automatically follow HTTP redirects
(status code 302, etc.), false otherwise. |
public AuthState getHostAuthState() {
return this.hostAuthState;
}
|
public HostConfiguration getHostConfiguration() {
HostConfiguration hostconfig = new HostConfiguration();
hostconfig.setHost(this.httphost);
return hostconfig;
} Deprecated! no - longer applicable
|
public MethodRetryHandler getMethodRetryHandler() {
return methodRetryHandler;
} Deprecated! use - HttpMethodParams
|
abstract public String getName()
Obtains the name of the HTTP method as used in the HTTP request line,
for example "GET" or "POST". |
public HttpMethodParams getParams() {
return this.params;
}
|
public String getPath() {
return (path == null || path.equals("")) ? "/" : path;
}
Gets the path of this HTTP method.
Calling this method after the request has been executed will
return the actual path, following any redirects automatically
handled by this HTTP method. |
public AuthState getProxyAuthState() {
return this.proxyAuthState;
}
|
public String getProxyAuthenticationRealm() {
return this.proxyAuthState.getRealm();
} Deprecated! use - #getProxyAuthState()
Returns proxy authentication realm, if it has been used during authentication process.
Otherwise returns null. |
public String getQueryString() {
return queryString;
}
Gets the query string of this HTTP method. |
public int getRecoverableExceptionCount() {
return recoverableExceptionCount;
} Deprecated! no - longer used
Returns the number of "recoverable" exceptions thrown and handled, to
allow for monitoring the quality of the connection.
|
public String getRequestCharSet() {
return getContentCharSet(getRequestHeader("Content-Type"));
}
Returns the character encoding of the request from the Content-Type header. |
public Header getRequestHeader(String headerName) {
if (headerName == null) {
return null;
} else {
return getRequestHeaderGroup().getCondensedHeader(headerName);
}
}
Returns the specified request header. Note that header-name matching is
case insensitive. null will be returned if either
headerName is null or there is no matching header for
headerName. |
protected HeaderGroup getRequestHeaderGroup() {
return requestHeaders;
}
|
public Header[] getRequestHeaders() {
return getRequestHeaderGroup().getAllHeaders();
}
Returns an array of the requests headers that the HTTP method currently has |
public Header[] getRequestHeaders(String headerName) {
return getRequestHeaderGroup().getHeaders(headerName);
}
|
public byte[] getResponseBody() throws IOException {
if (this.responseBody == null) {
InputStream instream = getResponseBodyAsStream();
if (instream != null) {
long contentLength = getResponseContentLength();
if (contentLength > Integer.MAX_VALUE) { //guard below cast from overflow
throw new IOException("Content too large to be buffered: "+ contentLength +" bytes");
}
int limit = getParams().getIntParameter(HttpMethodParams.BUFFER_WARN_TRIGGER_LIMIT, 1024*1024);
if ((contentLength == -1) || (contentLength > limit)) {
LOG.warn("Going to buffer response body of large or unknown size. "
+"Using getResponseBodyAsStream instead is recommended.");
}
LOG.debug("Buffering response body");
ByteArrayOutputStream outstream = new ByteArrayOutputStream(
contentLength > 0 ? (int) contentLength : DEFAULT_INITIAL_BUFFER_SIZE);
byte[] buffer = new byte[4096];
int len;
while ((len = instream.read(buffer)) > 0) {
outstream.write(buffer, 0, len);
}
outstream.close();
setResponseStream(null);
this.responseBody = outstream.toByteArray();
}
}
return this.responseBody;
}
Returns the response body of the HTTP method, if any, as an array of bytes.
If response body is not available or cannot be read, returns null.
Buffers the response and this method can be called several times yielding
the same result each time.
Note: This will cause the entire response body to be buffered in memory. A
malicious server may easily exhaust all the VM memory. It is strongly
recommended, to use getResponseAsStream if the content length of the response
is unknown or resonably large. |
public byte[] getResponseBody(int maxlen) throws IOException {
if (maxlen < 0) throw new IllegalArgumentException("maxlen must be positive");
if (this.responseBody == null) {
InputStream instream = getResponseBodyAsStream();
if (instream != null) {
// we might already know that the content is larger
long contentLength = getResponseContentLength();
if ((contentLength != -1) && (contentLength > maxlen)) {
throw new HttpContentTooLargeException(
"Content-Length is " + contentLength, maxlen);
}
LOG.debug("Buffering response body");
ByteArrayOutputStream rawdata = new ByteArrayOutputStream(
contentLength > 0 ? (int) contentLength : DEFAULT_INITIAL_BUFFER_SIZE);
byte[] buffer = new byte[2048];
int pos = 0;
int len;
do {
len = instream.read(buffer, 0, Math.min(buffer.length, maxlen-pos));
if (len == -1) break;
rawdata.write(buffer, 0, len);
pos += len;
} while (pos < maxlen);
setResponseStream(null);
// check if there is even more data
if (pos == maxlen) {
if (instream.read() != -1)
throw new HttpContentTooLargeException(
"Content-Length not known but larger than "
+ maxlen, maxlen);
}
this.responseBody = rawdata.toByteArray();
}
}
return this.responseBody;
}
Returns the response body of the HTTP method, if any, as an array of bytes.
If response body is not available or cannot be read, returns null.
Buffers the response and this method can be called several times yielding
the same result each time.
Note: This will cause the entire response body to be buffered in memory. This method is
safe if the content length of the response is unknown, because the amount of memory used
is limited.
If the response is large this method involves lots of array copying and many object
allocations, which makes it unsuitable for high-performance / low-footprint applications.
Those applications should use #getResponseBodyAsStream() . |
public InputStream getResponseBodyAsStream() throws IOException {
if (responseStream != null) {
return responseStream;
}
if (responseBody != null) {
InputStream byteResponseStream = new ByteArrayInputStream(responseBody);
LOG.debug("re-creating response stream from byte array");
return byteResponseStream;
}
return null;
}
Returns the response body of the HTTP method, if any, as an InputStream .
If response body is not available, returns null. If the response has been
buffered this method returns a new stream object on every call. If the response
has not been buffered the returned stream can only be read once. |
public String getResponseBodyAsString() throws IOException {
byte[] rawdata = null;
if (responseAvailable()) {
rawdata = getResponseBody();
}
if (rawdata != null) {
return EncodingUtil.getString(rawdata, getResponseCharSet());
} else {
return null;
}
}
Returns the response body of the HTTP method, if any, as a String .
If response body is not available or cannot be read, returns null
The string conversion on the data is done using the character encoding specified
in Content-Type header. Buffers the response and this method can be
called several times yielding the same result each time.
Note: This will cause the entire response body to be buffered in memory. A
malicious server may easily exhaust all the VM memory. It is strongly
recommended, to use getResponseAsStream if the content length of the response
is unknown or resonably large. |
public String getResponseBodyAsString(int maxlen) throws IOException {
if (maxlen < 0) throw new IllegalArgumentException("maxlen must be positive");
byte[] rawdata = null;
if (responseAvailable()) {
rawdata = getResponseBody(maxlen);
}
if (rawdata != null) {
return EncodingUtil.getString(rawdata, getResponseCharSet());
} else {
return null;
}
}
Returns the response body of the HTTP method, if any, as a String .
If response body is not available or cannot be read, returns null
The string conversion on the data is done using the character encoding specified
in Content-Type header. Buffers the response and this method can be
called several times yielding the same result each time.
Note: This will cause the entire response body to be buffered in memory. This method is
safe if the content length of the response is unknown, because the amount of memory used
is limited.
If the response is large this method involves lots of array copying and many object
allocations, which makes it unsuitable for high-performance / low-footprint applications.
Those applications should use #getResponseBodyAsStream() . |
public String getResponseCharSet() {
return getContentCharSet(getResponseHeader("Content-Type"));
}
Returns the character encoding of the response from the Content-Type header. |
public long getResponseContentLength() {
Header[] headers = getResponseHeaderGroup().getHeaders("Content-Length");
if (headers.length == 0) {
return -1;
}
if (headers.length > 1) {
LOG.warn("Multiple content-length headers detected");
}
for (int i = headers.length - 1; i >= 0; i--) {
Header header = headers[i];
try {
return Long.parseLong(header.getValue());
} catch (NumberFormatException e) {
if (LOG.isWarnEnabled()) {
LOG.warn("Invalid content-length value: " + e.getMessage());
}
}
// See if we can have better luck with another header, if present
}
return -1;
}
|
public Header getResponseFooter(String footerName) {
if (footerName == null) {
return null;
} else {
return getResponseTrailerHeaderGroup().getCondensedHeader(footerName);
}
}
Gets the response footer associated with the given name.
Footer name matching is case insensitive.
null will be returned if either footerName is
null or there is no matching footer for footerName
or there are no footers available. If there are multiple footers
with the same name, there values will be combined with the ',' separator
as specified by RFC2616. |
public Header[] getResponseFooters() {
return getResponseTrailerHeaderGroup().getAllHeaders();
}
Returns an array of the response footers that the HTTP method currently has
in the order in which they were read. |
public Header getResponseHeader(String headerName) {
if (headerName == null) {
return null;
} else {
return getResponseHeaderGroup().getCondensedHeader(headerName);
}
}
Gets the response header associated with the given name. Header name
matching is case insensitive. null will be returned if either
headerName is null or there is no matching header for
headerName. |
protected HeaderGroup getResponseHeaderGroup() {
return responseHeaders;
}
|
public Header[] getResponseHeaders() {
return getResponseHeaderGroup().getAllHeaders();
}
Returns an array of the response headers that the HTTP method currently has
in the order in which they were read. |
public Header[] getResponseHeaders(String headerName) {
return getResponseHeaderGroup().getHeaders(headerName);
}
|
protected InputStream getResponseStream() {
return responseStream;
}
Returns a stream from which the body of the current response may be read.
If the method has not yet been executed, if responseBodyConsumed
has been called, or if the stream returned by a previous call has been closed,
null will be returned. |
protected HeaderGroup getResponseTrailerHeaderGroup() {
return responseTrailerHeaders;
}
Gets the header group storing the response trailer headers
as per RFC 2616 section 3.6.1. |
public int getStatusCode() {
return statusLine.getStatusCode();
}
Returns the response status code. |
public StatusLine getStatusLine() {
return statusLine;
}
Provides access to the response status line. |
public String getStatusText() {
return statusLine.getReasonPhrase();
}
Returns the status text (or "reason phrase") associated with the latest
response. |
public URI getURI() throws URIException {
StringBuffer buffer = new StringBuffer();
if (this.httphost != null) {
buffer.append(this.httphost.getProtocol().getScheme());
buffer.append("://");
buffer.append(this.httphost.getHostName());
int port = this.httphost.getPort();
if (port != -1 && port != this.httphost.getProtocol().getDefaultPort()) {
buffer.append(":");
buffer.append(port);
}
}
buffer.append(this.path);
if (this.queryString != null) {
buffer.append('?");
buffer.append(this.queryString);
}
String charset = getParams().getUriCharset();
return new URI(buffer.toString(), true, charset);
}
Returns the URI of the HTTP method |
public boolean hasBeenUsed() {
return used;
}
|
public boolean isAborted() {
return this.aborted;
}
Tests whether the execution of this method has been aborted |
protected boolean isConnectionCloseForced() {
return this.connectionCloseForced;
}
Tests if the connection should be force-closed when no longer needed. |
public boolean isHttp11() {
return this.params.getVersion().equals(HttpVersion.HTTP_1_1);
} Deprecated! Use - HttpMethodParams#getVersion()
Returns true if version 1.1 of the HTTP protocol should be
used per default, false if version 1.0 should be used. |
public boolean isRequestSent() {
return this.requestSent;
}
Returns true if the HTTP has been transmitted to the target
server in its entirety, false otherwise. This flag can be useful
for recovery logic. If the request has not been transmitted in its entirety,
it is safe to retry the failed method. |
public boolean isStrictMode() {
return false;
} Deprecated! Use - org.apache.commons.httpclient.params.HttpParams#setParameter(String, Object)
to exercise a more granular control over HTTP protocol strictness.
|
protected void processCookieHeaders(CookieSpec parser,
Header[] headers,
HttpState state,
HttpConnection conn) {
LOG.trace("enter HttpMethodBase.processCookieHeaders(Header[], HttpState, "
+ "HttpConnection)");
String host = this.params.getVirtualHost();
if (host == null) {
host = conn.getHost();
}
for (int i = 0; i < headers.length; i++) {
Header header = headers[i];
Cookie[] cookies = null;
try {
cookies = parser.parse(
host,
conn.getPort(),
getPath(),
conn.isSecure(),
header);
} catch (MalformedCookieException e) {
if (LOG.isWarnEnabled()) {
LOG.warn("Invalid cookie header: \""
+ header.getValue()
+ "\". " + e.getMessage());
}
}
if (cookies != null) {
for (int j = 0; j < cookies.length; j++) {
Cookie cookie = cookies[j];
try {
parser.validate(
host,
conn.getPort(),
getPath(),
conn.isSecure(),
cookie);
state.addCookie(cookie);
if (LOG.isDebugEnabled()) {
LOG.debug("Cookie accepted: \""
+ parser.formatCookie(cookie) + "\"");
}
} catch (MalformedCookieException e) {
if (LOG.isWarnEnabled()) {
LOG.warn("Cookie rejected: \"" + parser.formatCookie(cookie)
+ "\". " + e.getMessage());
}
}
}
}
}
}
|
protected void processResponseBody(HttpState state,
HttpConnection conn) {
}
|
protected void processResponseHeaders(HttpState state,
HttpConnection conn) {
LOG.trace("enter HttpMethodBase.processResponseHeaders(HttpState, "
+ "HttpConnection)");
CookieSpec parser = getCookieSpec(state);
// process set-cookie headers
Header[] headers = getResponseHeaderGroup().getHeaders("set-cookie");
processCookieHeaders(parser, headers, state, conn);
// see if the cookie spec supports cookie versioning.
if (parser instanceof CookieVersionSupport) {
CookieVersionSupport versupport = (CookieVersionSupport) parser;
if (versupport.getVersion() > 0) {
// process set-cookie2 headers.
// Cookie2 will replace equivalent Cookie instances
headers = getResponseHeaderGroup().getHeaders("set-cookie2");
processCookieHeaders(parser, headers, state, conn);
}
}
}
This method is invoked immediately after
#readResponseHeaders(HttpState,HttpConnection) and can be overridden by
sub-classes in order to provide custom response headers processing.
This implementation will handle the Set-Cookie and
Set-Cookie2 headers, if any, adding the relevant cookies to
the given HttpState .
|
protected void processStatusLine(HttpState state,
HttpConnection conn) {
}
|
protected void readResponse(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace(
"enter HttpMethodBase.readResponse(HttpState, HttpConnection)");
// Status line & line may have already been received
// if 'expect - continue' handshake has been used
while (this.statusLine == null) {
readStatusLine(state, conn);
processStatusLine(state, conn);
readResponseHeaders(state, conn);
processResponseHeaders(state, conn);
int status = this.statusLine.getStatusCode();
if ((status >= 100) && (status < 200)) {
if (LOG.isInfoEnabled()) {
LOG.info("Discarding unexpected response: " + this.statusLine.toString());
}
this.statusLine = null;
}
}
readResponseBody(state, conn);
processResponseBody(state, conn);
}
|
protected void readResponseBody(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace(
"enter HttpMethodBase.readResponseBody(HttpState, HttpConnection)");
// assume we are not done with the connection if we get a stream
InputStream stream = readResponseBody(conn);
if (stream == null) {
// done using the connection!
responseBodyConsumed();
} else {
conn.setLastResponseInputStream(stream);
setResponseStream(stream);
}
}
Read the response body from the given HttpConnection .
The current implementation wraps the socket level stream with
an appropriate stream for the type of response (chunked, content-length,
or auto-close). If there is no response body, the connection associated
with the request will be returned to the connection manager.
Subclasses may want to override this method to to customize the
processing.
|
protected void readResponseHeaders(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace("enter HttpMethodBase.readResponseHeaders(HttpState,"
+ "HttpConnection)");
getResponseHeaderGroup().clear();
Header[] headers = HttpParser.parseHeaders(
conn.getResponseInputStream(), getParams().getHttpElementCharset());
// Wire logging moved to HttpParser
getResponseHeaderGroup().setHeaders(headers);
}
Reads the response headers from the given connection .
Subclasses may want to override this method to to customize the
processing.
"It must be possible to combine the multiple header fields into one
"field-name: field-value" pair, without changing the semantics of the
message, by appending each subsequent field-value to the first, each
separated by a comma." - HTTP/1.0 (4.3)
|
protected void readStatusLine(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace("enter HttpMethodBase.readStatusLine(HttpState, HttpConnection)");
final int maxGarbageLines = getParams().
getIntParameter(HttpMethodParams.STATUS_LINE_GARBAGE_LIMIT, Integer.MAX_VALUE);
//read out the HTTP status string
int count = 0;
String s;
do {
s = conn.readLine(getParams().getHttpElementCharset());
if (s == null && count == 0) {
// The server just dropped connection on us
throw new NoHttpResponseException("The server " + conn.getHost() +
" failed to respond");
}
if (Wire.HEADER_WIRE.enabled()) {
Wire.HEADER_WIRE.input(s + "\r\n");
}
if (s != null && StatusLine.startsWithHTTP(s)) {
// Got one
break;
} else if (s == null || count >= maxGarbageLines) {
// Giving up
throw new ProtocolException("The server " + conn.getHost() +
" failed to respond with a valid HTTP response");
}
count++;
} while(true);
//create the status line from the status string
statusLine = new StatusLine(s);
//check for a valid HTTP-Version
String versionStr = statusLine.getHttpVersion();
if (getParams().isParameterFalse(HttpMethodParams.UNAMBIGUOUS_STATUS_LINE)
&& versionStr.equals("HTTP")) {
getParams().setVersion(HttpVersion.HTTP_1_0);
if (LOG.isWarnEnabled()) {
LOG.warn("Ambiguous status line (HTTP protocol version missing):" +
statusLine.toString());
}
} else {
this.effectiveVersion = HttpVersion.parse(versionStr);
}
}
|
public void recycle() {
LOG.trace("enter HttpMethodBase.recycle()");
releaseConnection();
path = null;
followRedirects = false;
doAuthentication = true;
queryString = null;
getRequestHeaderGroup().clear();
getResponseHeaderGroup().clear();
getResponseTrailerHeaderGroup().clear();
statusLine = null;
effectiveVersion = null;
aborted = false;
used = false;
params = new HttpMethodParams();
responseBody = null;
recoverableExceptionCount = 0;
connectionCloseForced = false;
hostAuthState.invalidate();
proxyAuthState.invalidate();
cookiespec = null;
requestSent = false;
} Deprecated! no - longer supported and will be removed in the future
version of HttpClient
Recycles the HTTP method so that it can be used again.
Note that all of the instance variables will be reset
once this method has been called. This method will also
release the connection being used by this HTTP method. |
public void releaseConnection() {
try {
if (this.responseStream != null) {
try {
// FYI - this may indirectly invoke responseBodyConsumed.
this.responseStream.close();
} catch (IOException ignore) {
}
}
} finally {
ensureConnectionRelease();
}
}
Releases the connection being used by this HTTP method. In particular the
connection is used to read the response(if there is one) and will be held
until the response has been read. If the connection can be reused by other
HTTP methods it is NOT closed at this point. |
public void removeRequestHeader(String headerName) {
Header[] headers = getRequestHeaderGroup().getHeaders(headerName);
for (int i = 0; i < headers.length; i++) {
getRequestHeaderGroup().removeHeader(headers[i]);
}
}
Remove the request header associated with the given name. Note that
header-name matching is case insensitive. |
public void removeRequestHeader(Header header) {
if (header == null) {
return;
}
getRequestHeaderGroup().removeHeader(header);
}
Removes the given request header. |
protected void responseBodyConsumed() {
// make sure this is the initial invocation of the notification,
// ignore subsequent ones.
responseStream = null;
if (responseConnection != null) {
responseConnection.setLastResponseInputStream(null);
// At this point, no response data should be available.
// If there is data available, regard the connection as being
// unreliable and close it.
if (shouldCloseConnection(responseConnection)) {
responseConnection.close();
} else {
try {
if(responseConnection.isResponseAvailable()) {
boolean logExtraInput =
getParams().isParameterTrue(HttpMethodParams.WARN_EXTRA_INPUT);
if(logExtraInput) {
LOG.warn("Extra response data detected - closing connection");
}
responseConnection.close();
}
}
catch (IOException e) {
LOG.warn(e.getMessage());
responseConnection.close();
}
}
}
this.connectionCloseForced = false;
ensureConnectionRelease();
}
A response has been consumed.
The default behavior for this class is to check to see if the connection
should be closed, and close if need be, and to ensure that the connection
is returned to the connection manager - if and only if we are not still
inside the execute call. |
protected void setConnectionCloseForced(boolean b) {
if (LOG.isDebugEnabled()) {
LOG.debug("Force-close connection: " + b);
}
this.connectionCloseForced = b;
}
Sets whether or not the connection should be force-closed when no longer
needed. This value should only be set to true in abnormal
circumstances, such as HTTP protocol violations. |
public void setDoAuthentication(boolean doAuthentication) {
this.doAuthentication = doAuthentication;
}
Sets whether or not the HTTP method should automatically handle HTTP
authentication challenges (status code 401, etc.) |
public void setFollowRedirects(boolean followRedirects) {
this.followRedirects = followRedirects;
}
Sets whether or not the HTTP method should automatically follow HTTP redirects
(status code 302, etc.) |
public void setHostConfiguration(HostConfiguration hostconfig) {
if (hostconfig != null) {
this.httphost = new HttpHost(
hostconfig.getHost(),
hostconfig.getPort(),
hostconfig.getProtocol());
} else {
this.httphost = null;
}
} Deprecated! no - longer applicable
|
public void setHttp11(boolean http11) {
if (http11) {
this.params.setVersion(HttpVersion.HTTP_1_1);
} else {
this.params.setVersion(HttpVersion.HTTP_1_0);
}
} Deprecated! Use - HttpMethodParams#setVersion(HttpVersion)
Sets whether version 1.1 of the HTTP protocol should be used per default. |
public void setMethodRetryHandler(MethodRetryHandler handler) {
methodRetryHandler = handler;
} Deprecated! use - HttpMethodParams
|
public void setParams(HttpMethodParams params) {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
this.params = params;
}
|
public void setPath(String path) {
this.path = path;
}
Sets the path of the HTTP method.
It is responsibility of the caller to ensure that the path is
properly encoded (URL safe). |
public void setQueryString(String queryString) {
this.queryString = queryString;
}
Sets the query string of this HTTP method. The caller must ensure that the string
is properly URL encoded. The query string should not start with the question
mark character. |
public void setQueryString(NameValuePair[] params) {
LOG.trace("enter HttpMethodBase.setQueryString(NameValuePair[])");
queryString = EncodingUtil.formUrlEncode(params, "UTF-8");
}
Sets the query string of this HTTP method. The pairs are encoded as UTF-8 characters.
To use a different charset the parameters can be encoded manually using EncodingUtil
and set as a single String. |
public void setRequestHeader(Header header) {
Header[] headers = getRequestHeaderGroup().getHeaders(header.getName());
for (int i = 0; i < headers.length; i++) {
getRequestHeaderGroup().removeHeader(headers[i]);
}
getRequestHeaderGroup().addHeader(header);
}
Sets the specified request header, overwriting any previous value.
Note that header-name matching is case insensitive. |
public void setRequestHeader(String headerName,
String headerValue) {
Header header = new Header(headerName, headerValue);
setRequestHeader(header);
}
Set the specified request header, overwriting any previous value. Note
that header-name matching is case-insensitive. |
protected void setResponseStream(InputStream responseStream) {
this.responseStream = responseStream;
}
Sets the response stream. |
public void setStrictMode(boolean strictMode) {
if (strictMode) {
this.params.makeStrict();
} else {
this.params.makeLenient();
}
} Deprecated! Use - org.apache.commons.httpclient.params.HttpParams#setParameter(String, Object)
to exercise a more granular control over HTTP protocol strictness.
Defines how strictly HttpClient follows the HTTP protocol specification
(RFC 2616 and other relevant RFCs). In the strict mode HttpClient precisely
implements the requirements of the specification, whereas in non-strict mode
it attempts to mimic the exact behaviour of commonly used HTTP agents,
which many HTTP servers expect. |
public void setURI(URI uri) throws URIException {
// only set the host if specified by the URI
if (uri.isAbsoluteURI()) {
this.httphost = new HttpHost(uri);
}
// set the path, defaulting to root
setPath(
uri.getPath() == null
? "/"
: uri.getEscapedPath()
);
setQueryString(uri.getEscapedQuery());
}
Sets the URI for this method. |
protected boolean shouldCloseConnection(HttpConnection conn) {
// Connection must be closed due to an abnormal circumstance
if (isConnectionCloseForced()) {
LOG.debug("Should force-close connection.");
return true;
}
Header connectionHeader = null;
// In case being connected via a proxy server
if (!conn.isTransparent()) {
// Check for 'proxy-connection' directive
connectionHeader = responseHeaders.getFirstHeader("proxy-connection");
}
// In all cases Check for 'connection' directive
// some non-complaint proxy servers send it instread of
// expected 'proxy-connection' directive
if (connectionHeader == null) {
connectionHeader = responseHeaders.getFirstHeader("connection");
}
// In case the response does not contain any explict connection
// directives, check whether the request does
if (connectionHeader == null) {
connectionHeader = requestHeaders.getFirstHeader("connection");
}
if (connectionHeader != null) {
if (connectionHeader.getValue().equalsIgnoreCase("close")) {
if (LOG.isDebugEnabled()) {
LOG.debug("Should close connection in response to directive: "
+ connectionHeader.getValue());
}
return true;
} else if (connectionHeader.getValue().equalsIgnoreCase("keep-alive")) {
if (LOG.isDebugEnabled()) {
LOG.debug("Should NOT close connection in response to directive: "
+ connectionHeader.getValue());
}
return false;
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Unknown directive: " + connectionHeader.toExternalForm());
}
}
}
LOG.debug("Resorting to protocol version default close connection policy");
// missing or invalid connection header, do the default
if (this.effectiveVersion.greaterEquals(HttpVersion.HTTP_1_1)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Should NOT close connection, using " + this.effectiveVersion.toString());
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Should close connection, using " + this.effectiveVersion.toString());
}
}
return this.effectiveVersion.lessEquals(HttpVersion.HTTP_1_0);
}
Tests if the connection should be closed after the method has been executed.
The connection will be left open when using HTTP/1.1 or if Connection:
keep-alive header was sent. |
public boolean validate() {
return true;
}
Returns true the method is ready to execute, false otherwise. |
protected void writeRequest(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace(
"enter HttpMethodBase.writeRequest(HttpState, HttpConnection)");
writeRequestLine(state, conn);
writeRequestHeaders(state, conn);
conn.writeLine(); // close head
if (Wire.HEADER_WIRE.enabled()) {
Wire.HEADER_WIRE.output("\r\n");
}
HttpVersion ver = getParams().getVersion();
Header expectheader = getRequestHeader("Expect");
String expectvalue = null;
if (expectheader != null) {
expectvalue = expectheader.getValue();
}
if ((expectvalue != null)
&& (expectvalue.compareToIgnoreCase("100-continue") == 0)) {
if (ver.greaterEquals(HttpVersion.HTTP_1_1)) {
// make sure the status line and headers have been sent
conn.flushRequestOutputStream();
int readTimeout = conn.getParams().getSoTimeout();
try {
conn.setSocketTimeout(RESPONSE_WAIT_TIME_MS);
readStatusLine(state, conn);
processStatusLine(state, conn);
readResponseHeaders(state, conn);
processResponseHeaders(state, conn);
if (this.statusLine.getStatusCode() == HttpStatus.SC_CONTINUE) {
// Discard status line
this.statusLine = null;
LOG.debug("OK to continue received");
} else {
return;
}
} catch (InterruptedIOException e) {
if (!ExceptionUtil.isSocketTimeoutException(e)) {
throw e;
}
// Most probably Expect header is not recongnized
// Remove the header to signal the method
// that it's okay to go ahead with sending data
removeRequestHeader("Expect");
LOG.info("100 (continue) read timeout. Resume sending the request");
} finally {
conn.setSocketTimeout(readTimeout);
}
} else {
removeRequestHeader("Expect");
LOG.info("'Expect: 100-continue' handshake is only supported by "
+ "HTTP/1.1 or higher");
}
}
writeRequestBody(state, conn);
// make sure the entire request body has been sent
conn.flushRequestOutputStream();
}
|
protected boolean writeRequestBody(HttpState state,
HttpConnection conn) throws IOException, HttpException {
return true;
}
Writes the request body to the given connection .
This method should return true if the request body was actually
sent (or is empty), or false if it could not be sent for some
reason.
This implementation writes nothing and returns true.
|
protected void writeRequestHeaders(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace("enter HttpMethodBase.writeRequestHeaders(HttpState,"
+ "HttpConnection)");
addRequestHeaders(state, conn);
String charset = getParams().getHttpElementCharset();
Header[] headers = getRequestHeaders();
for (int i = 0; i < headers.length; i++) {
String s = headers[i].toExternalForm();
if (Wire.HEADER_WIRE.enabled()) {
Wire.HEADER_WIRE.output(s);
}
conn.print(s, charset);
}
}
|
protected void writeRequestLine(HttpState state,
HttpConnection conn) throws IOException, HttpException {
LOG.trace(
"enter HttpMethodBase.writeRequestLine(HttpState, HttpConnection)");
String requestLine = getRequestLine(conn);
if (Wire.HEADER_WIRE.enabled()) {
Wire.HEADER_WIRE.output(requestLine);
}
conn.print(requestLine, getParams().getHttpElementCharset());
}
|