You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Todd W Lainhart <la...@us.ibm.com> on 2014/10/14 17:37:56 UTC
HttpContext and RequestConfig
HttpClient 4.3.5 / HttpCore 4.3.2
I've got an execution context, that while appears to be a single
call/response to the caller, can result in multiple network calls -
multiple CloseableHttpClient.execute(...) invocations. Those invocations
share HttpContext state, mainly for a shared cookie store. The
CloseableHttpClient has a custom RequestConfig associated to it.
One of the invocations creates a new HttpRequest object, with its own
RequestConfig that overrides the default. On subsequent invocations I was
surprised to see that the RequestConfig that I set on the request became
the shared HttpContext's RequestConfig state, which is used in subsequent
invocations. Reading the source confirms this - the request's config is
set on the "local context", which is the shared context I mentioned
earlier.
Is this the intended behavior? I can see it both ways.
I can work around this by clearing the request config on the context on
that one call, but I wanted to raise the question in case I'm missing a
concept. I'm also not finding a "clone" or "copy" of a context, which I
thought I had seen at one point.
Todd Lainhart
Rational software
IBM Corporation
550 King Street, Littleton, MA 01460-1250
1-978-899-4705
2-276-4705 (T/L)
lainhart@us.ibm.com
Re: HttpContext and RequestConfig
Posted by Oleg Kalnichevski <ol...@apache.org>.
On Wed, 2014-10-15 at 10:50 -0400, Todd W Lainhart wrote:
> Thanks Oleg -
>
> Unless I'm missing something, I was thinking that it had to be something
> along these lines:
>
> /*
> * Disable redirection for this one POST request
> */
> RequestConfig oldConfig = context.getRequestConfig();
> RequestConfig newConfig = RequestConfig.custom
> ().setRedirectsEnabled(false).build();
> context.setRequestConfig(newConfig);
>
> try {
> response = httpClient.execute(targetHost, postMethod,
> context);
> } finally {
> context.setRequestConfig(oldConfig);
> }
>
That certainly works, too.
Oleg
---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org
Re: HttpContext and RequestConfig
Posted by Todd W Lainhart <la...@us.ibm.com>.
Thanks Oleg -
Unless I'm missing something, I was thinking that it had to be something
along these lines:
/*
* Disable redirection for this one POST request
*/
RequestConfig oldConfig = context.getRequestConfig();
RequestConfig newConfig = RequestConfig.custom
().setRedirectsEnabled(false).build();
context.setRequestConfig(newConfig);
try {
response = httpClient.execute(targetHost, postMethod,
context);
} finally {
context.setRequestConfig(oldConfig);
}
>
> Well, in the worst case would this do the trick?
> ---
> class MyHttpContext implements HttpContext {
>
> private final HttpContext context;
> private RequestConfig requestConfig;
>
> public MyHttpContext(final HttpContext context) {
> super();
> this.context = Args.notNull(context, "HTTP context");
> }
>
> public Object getAttribute(final String id) {
> if (HttpClientContext.REQUEST_CONFIG.equals(id)) {
> if (this.requestConfig != null) {
> return this.requestConfig;
> } else {
> return this.context.getAttribute(id);
> }
> } else {
> return this.context.getAttribute(id);
> }
> }
>
> public Object removeAttribute(final String id) {
> if (HttpClientContext.REQUEST_CONFIG.equals(id)) {
> RequestConfig local = this.requestConfig;
> this.requestConfig = null;
> return local;
> } else {
> return this.context.removeAttribute(id);
> }
> }
>
> public void setAttribute(final String id, final Object obj) {
> if (HttpClientContext.REQUEST_CONFIG.equals(id)) {
> this.requestConfig = (RequestConfig) obj;
> } else {
> this.context.setAttribute(id, obj);
> }
> }
>
> }
> ---
>
> Oleg
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>
Re: HttpContext and RequestConfig
Posted by Oleg Kalnichevski <ol...@apache.org>.
On Wed, 2014-10-15 at 09:50 -0400, Todd W Lainhart wrote:
> >
> > What one might do instead of cloning a context is to wrap it with a
> > decorator and discard the decorator along with all local modifications.
> >
>
> Thanks. I'll have to think on this - I'm not sure that it will solve this
> problem. The problem is that I want the HttpContext passed between
> execute(...) invocations to maintain/accumulate state for those
> invocations (e.g. cookies, redirects list) - just not inherit the
> RequestConfig state on individual requests where it's been applied.
>
> -- Todd
Well, in the worst case would this do the trick?
---
class MyHttpContext implements HttpContext {
private final HttpContext context;
private RequestConfig requestConfig;
public MyHttpContext(final HttpContext context) {
super();
this.context = Args.notNull(context, "HTTP context");
}
public Object getAttribute(final String id) {
if (HttpClientContext.REQUEST_CONFIG.equals(id)) {
if (this.requestConfig != null) {
return this.requestConfig;
} else {
return this.context.getAttribute(id);
}
} else {
return this.context.getAttribute(id);
}
}
public Object removeAttribute(final String id) {
if (HttpClientContext.REQUEST_CONFIG.equals(id)) {
RequestConfig local = this.requestConfig;
this.requestConfig = null;
return local;
} else {
return this.context.removeAttribute(id);
}
}
public void setAttribute(final String id, final Object obj) {
if (HttpClientContext.REQUEST_CONFIG.equals(id)) {
this.requestConfig = (RequestConfig) obj;
} else {
this.context.setAttribute(id, obj);
}
}
}
---
Oleg
---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org
Re: HttpContext and RequestConfig
Posted by Todd W Lainhart <la...@us.ibm.com>.
>
> What one might do instead of cloning a context is to wrap it with a
> decorator and discard the decorator along with all local modifications.
>
Thanks. I'll have to think on this - I'm not sure that it will solve this
problem. The problem is that I want the HttpContext passed between
execute(...) invocations to maintain/accumulate state for those
invocations (e.g. cookies, redirects list) - just not inherit the
RequestConfig state on individual requests where it's been applied.
-- Todd
Re: HttpContext and RequestConfig
Posted by Oleg Kalnichevski <ol...@apache.org>.
On Tue, 2014-10-14 at 11:37 -0400, Todd W Lainhart wrote:
> HttpClient 4.3.5 / HttpCore 4.3.2
>
> I've got an execution context, that while appears to be a single
> call/response to the caller, can result in multiple network calls -
> multiple CloseableHttpClient.execute(...) invocations. Those invocations
> share HttpContext state, mainly for a shared cookie store. The
> CloseableHttpClient has a custom RequestConfig associated to it.
>
> One of the invocations creates a new HttpRequest object, with its own
> RequestConfig that overrides the default. On subsequent invocations I was
> surprised to see that the RequestConfig that I set on the request became
> the shared HttpContext's RequestConfig state, which is used in subsequent
> invocations. Reading the source confirms this - the request's config is
> set on the "local context", which is the shared context I mentioned
> earlier.
>
> Is this the intended behavior? I can see it both ways.
>
Hi Todd
I find it reasonable that the last request config stays in the context
and gets propagated to subsequent requests within the same context. So,
it was intended.
> I can work around this by clearing the request config on the context on
> that one call, but I wanted to raise the question in case I'm missing a
> concept. I'm also not finding a "clone" or "copy" of a context, which I
> thought I had seen at one point.
>
Deprecated HttpParams supports #copy, but I do not think HttpContext
implementations ever supported #copy or #clone.
What one might do instead of cloning a context is to wrap it with a
decorator and discard the decorator along with all local modifications.
---
public final class DefaultedHttpContext implements HttpContext {
private final HttpContext local;
private final HttpContext defaults;
public DefaultedHttpContext(final HttpContext local, final
HttpContext defaults) {
super();
this.local = Args.notNull(local, "HTTP context");
this.defaults = defaults;
}
public Object getAttribute(final String id) {
final Object obj = this.local.getAttribute(id);
if (obj == null) {
return this.defaults.getAttribute(id);
} else {
return obj;
}
}
public Object removeAttribute(final String id) {
return this.local.removeAttribute(id);
}
public void setAttribute(final String id, final Object obj) {
this.local.setAttribute(id, obj);
}
}
---
Oleg
---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org