Fixed thread concurrency issue on http cookie handling.

pull/3113/head
Taloth Saldono 9 years ago
parent bf3d0ed2d1
commit 103de770c3

@ -226,6 +226,29 @@ namespace NzbDrone.Common.Test.Http
ExceptionVerification.IgnoreErrors();
}
[Test]
public void should_overwrite_response_cookie()
{
var requestSet = new HttpRequest("http://eu.httpbin.org/cookies/set?my=cookie");
requestSet.AllowAutoRedirect = false;
requestSet.StoreResponseCookie = true;
requestSet.AddCookie("my", "oldcookie");
var responseSet = Subject.Get(requestSet);
var request = new HttpRequest("http://eu.httpbin.org/get");
var response = Subject.Get<HttpBinResource>(request);
response.Resource.Headers.Should().ContainKey("Cookie");
var cookie = response.Resource.Headers["Cookie"].ToString();
cookie.Should().Contain("my=cookie");
ExceptionVerification.IgnoreErrors();
}
}
public class HttpBinResource

@ -73,50 +73,81 @@ namespace NzbDrone.Common.Http
AddRequestHeaders(webRequest, request.Headers);
}
var cookieContainer = _cookieContainerCache.Get("container", () => new CookieContainer());
PrepareRequestCookies(request, webRequest);
var response = ExecuteRequest(request, webRequest);
HandleResponseCookies(request, webRequest);
stopWatch.Stop();
_logger.Trace("{0} ({1:n0} ms)", response, stopWatch.ElapsedMilliseconds);
if (request.AllowAutoRedirect && !RuntimeInfoBase.IsProduction &&
(response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.MovedPermanently ||
response.StatusCode == HttpStatusCode.Found))
{
_logger.Error("Server requested a redirect to [" + response.Headers["Location"] + "]. Update the request URL to avoid this redirect.");
}
if (!request.SuppressHttpError && response.HasHttpError)
{
_logger.Warn("HTTP Error - {0}", response);
throw new HttpException(request, response);
}
return response;
}
private void PrepareRequestCookies(HttpRequest request, HttpWebRequest webRequest)
{
lock (_cookieContainerCache)
{
var persistentCookieContainer = _cookieContainerCache.Get("container", () => new CookieContainer());
if (request.Cookies.Count != 0)
{
foreach (var pair in request.Cookies)
{
cookieContainer.Add(new Cookie(pair.Key, pair.Value, "/", request.Url.Host)
persistentCookieContainer.Add(new Cookie(pair.Key, pair.Value, "/", request.Url.Host)
{
Expires = DateTime.UtcNow.AddHours(1)
});
}
}
if (request.StoreResponseCookie)
var requestCookies = persistentCookieContainer.GetCookies(request.Url);
if (requestCookies.Count == 0 && !request.StoreResponseCookie)
{
webRequest.CookieContainer = cookieContainer;
return;
}
else
if (webRequest.CookieContainer == null)
{
webRequest.CookieContainer = new CookieContainer();
webRequest.CookieContainer.Add(cookieContainer.GetCookies(request.Url));
}
var response = ExecuteRequest(request, webRequest);
stopWatch.Stop();
_logger.Trace("{0} ({1:n0} ms)", response, stopWatch.ElapsedMilliseconds);
webRequest.CookieContainer.Add(requestCookies);
}
}
if (request.AllowAutoRedirect && !RuntimeInfoBase.IsProduction &&
(response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.MovedPermanently ||
response.StatusCode == HttpStatusCode.Found))
private void HandleResponseCookies(HttpRequest request, HttpWebRequest webRequest)
{
_logger.Error("Server requested a redirect to [" + response.Headers["Location"] + "]. Update the request URL to avoid this redirect.");
if (!request.StoreResponseCookie)
{
return;
}
if (!request.SuppressHttpError && response.HasHttpError)
lock (_cookieContainerCache)
{
_logger.Warn("HTTP Error - {0}", response);
throw new HttpException(request, response);
}
var persistentCookieContainer = _cookieContainerCache.Get("container", () => new CookieContainer());
return response;
var cookies = webRequest.CookieContainer.GetCookies(request.Url);
persistentCookieContainer.Add(cookies);
}
}
private HttpResponse ExecuteRequest(HttpRequest request, HttpWebRequest webRequest)

Loading…
Cancel
Save