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(); 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 public class HttpBinResource

@ -73,50 +73,81 @@ namespace NzbDrone.Common.Http
AddRequestHeaders(webRequest, request.Headers); 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) if (request.Cookies.Count != 0)
{ {
foreach (var pair in request.Cookies) 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) 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 = new CookieContainer();
webRequest.CookieContainer.Add(cookieContainer.GetCookies(request.Url));
} }
var response = ExecuteRequest(request, webRequest); webRequest.CookieContainer.Add(requestCookies);
}
stopWatch.Stop(); }
_logger.Trace("{0} ({1:n0} ms)", response, stopWatch.ElapsedMilliseconds);
if (request.AllowAutoRedirect && !RuntimeInfoBase.IsProduction && private void HandleResponseCookies(HttpRequest request, HttpWebRequest webRequest)
(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.StoreResponseCookie)
{
return;
} }
if (!request.SuppressHttpError && response.HasHttpError) lock (_cookieContainerCache)
{ {
_logger.Warn("HTTP Error - {0}", response); var persistentCookieContainer = _cookieContainerCache.Get("container", () => new CookieContainer());
throw new HttpException(request, response);
}
return response; var cookies = webRequest.CookieContainer.GetCookies(request.Url);
persistentCookieContainer.Add(cookies);
}
} }
private HttpResponse ExecuteRequest(HttpRequest request, HttpWebRequest webRequest) private HttpResponse ExecuteRequest(HttpRequest request, HttpWebRequest webRequest)

Loading…
Cancel
Save