在 HttpWebRequest 导致 404 - Not Found 后不久发出 RestClient 请求
Making a RestClient request shortly after HttpWebRequest leads to 404 - Not Found
我的应用程序正在向某些政府的服务发送一些数据。
工作流程是首先在他们的 REST(JSON) 服务上进行身份验证以获取身份验证令牌,然后将实际数据+令牌发送到他们的 SOAP 服务。
问题是,如果我在最后一个 soap 请求后快速连续调用身份验证服务,他们的 REST 服务将 return“404 – 未找到”HTML 而不是 JSON 回应。
这是发送验证请求的代码:
RestClient client = new RestClient(ret.Url);
AuthRequestToken requestToken = new AuthRequestToken();
requestToken.userLoginDetails.organisationCode = _organizationCode;
requestToken.userLoginDetails.userId = _username;
requestToken.userLoginDetails.password = _password;
ret.RequestJson = requestToken.ToString();
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("cache-control", "no-cache");
request.AddParameter("application/json", ret.RequestJson, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
这是发送 SOAP 请求的代码:
HttpWebRequest webRequest = CreateWebRequest(envelope);
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream responseStream = webResponse.GetResponseStream())
{
using (StreamReader rd = new StreamReader(responseStream))
{
ret.ResponseXML = rd.ReadToEnd();
}
responseStream.Close();
}
}
这是 CreateWebRequest() 方法
private HttpWebRequest CreateWebRequest(XElement content)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(_url);
//webRequest.Headers.Add("SOAPAction", action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
using (Stream stream = webRequest.GetRequestStream())
{
content.Save(stream);
}
return webRequest;
}
RestClient 是从 https://restsharp.dev/
下载的 RestSharp 库中的 class
使用 TcpView 或 netstat -abn 我可以看到在任何请求(RestClient 或 HttpWebRequest)之后,连接将保持 ESTABLISHED 状态长达 5-30 秒。
99% 的时间一切正常,除了在特定情况下,当我在最后一个 HttpWebRequest 之后的 5-30 秒内发出 RestClient 请求时,在连接从 ESTABLISHED 切换到 CLOSE_WAIT 之前。
我应该提到这段代码在几天前运行良好。在此之前,他们的身份验证服务与他们的 SOAP 服务使用不同的 IP 地址。现在他们在同一个 IP 地址上,甚至可能在同一个物理服务器上。
在他们切换服务器之前,我曾经在每个 SOAP 请求之前调用身份验证请求,并且它工作正常,但是自从这个错误开始发生后,我修改了我的代码以仅偶尔进行身份验证并且对一堆使用相同的令牌SOAP 请求。这大大减少了出现此错误的机会,但我仍然偶尔会在流量高时遇到它。
在我看来,RestClient 和 HttpWebRequest 在后台使用相同的套接字,其中之一没有正确清理。似乎 RestClient 从 HttpWebRequest 继承了一些垃圾,因为该服务的“404 - 未找到”return 看起来与我故意导航到身份验证服务的错误 URL 时相同。
也有可能我没有正确处理或关闭某些东西,但我尝试关闭我能找到的每个流、客户端或连接,并在各处注入 'using',但似乎无济于事。
我尝试联系政府的技术支持,但根据我以前的经验判断,他们甚至需要几周时间才能帮我联系到能够理解问题的人。
这是 404 HTML 我得到:
<!doctype html>
<html lang="en">
<head>
<title>HTTP Status 404 – Not Found</title>
<style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style>
</head>
<body>
<h1>HTTP Status 404 – Not Found</h1>
<hr class="line" />
<p>
<b>Type</b> Status Report</p>
<p>
<b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p>
<hr class="line" />
<h3>Apache Tomcat/9.0.35</h3>
</body>
</html>
你有什么建议可以防止这种情况发生吗?
正如我所说,我目前有一些变通办法,可以在有机会时刷新令牌,甚至在必要时延迟常规请求,但我希望尽可能不使用变通办法,尤其是因为我不知道套接字超时是什么。在大多数计算机上为 5 秒,但在某些无线网络上它会保持 ESTABLISHED 将近一分钟。
如果重要的话,两个服务都在 HTTPS 上。
谢谢!
我通过制作一个小型控制台应用程序解决了这个问题,该应用程序通过命令行参数接收凭据,连接到其余服务并returns标准输出中的令牌。
父应用程序在后台定期调用此 exe,并从标准输出中读取一个新令牌。
我的应用程序正在向某些政府的服务发送一些数据。 工作流程是首先在他们的 REST(JSON) 服务上进行身份验证以获取身份验证令牌,然后将实际数据+令牌发送到他们的 SOAP 服务。
问题是,如果我在最后一个 soap 请求后快速连续调用身份验证服务,他们的 REST 服务将 return“404 – 未找到”HTML 而不是 JSON 回应。
这是发送验证请求的代码:
RestClient client = new RestClient(ret.Url);
AuthRequestToken requestToken = new AuthRequestToken();
requestToken.userLoginDetails.organisationCode = _organizationCode;
requestToken.userLoginDetails.userId = _username;
requestToken.userLoginDetails.password = _password;
ret.RequestJson = requestToken.ToString();
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("cache-control", "no-cache");
request.AddParameter("application/json", ret.RequestJson, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
这是发送 SOAP 请求的代码:
HttpWebRequest webRequest = CreateWebRequest(envelope);
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream responseStream = webResponse.GetResponseStream())
{
using (StreamReader rd = new StreamReader(responseStream))
{
ret.ResponseXML = rd.ReadToEnd();
}
responseStream.Close();
}
}
这是 CreateWebRequest() 方法
private HttpWebRequest CreateWebRequest(XElement content)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(_url);
//webRequest.Headers.Add("SOAPAction", action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
using (Stream stream = webRequest.GetRequestStream())
{
content.Save(stream);
}
return webRequest;
}
RestClient 是从 https://restsharp.dev/
下载的 RestSharp 库中的 class使用 TcpView 或 netstat -abn 我可以看到在任何请求(RestClient 或 HttpWebRequest)之后,连接将保持 ESTABLISHED 状态长达 5-30 秒。
99% 的时间一切正常,除了在特定情况下,当我在最后一个 HttpWebRequest 之后的 5-30 秒内发出 RestClient 请求时,在连接从 ESTABLISHED 切换到 CLOSE_WAIT 之前。
我应该提到这段代码在几天前运行良好。在此之前,他们的身份验证服务与他们的 SOAP 服务使用不同的 IP 地址。现在他们在同一个 IP 地址上,甚至可能在同一个物理服务器上。
在他们切换服务器之前,我曾经在每个 SOAP 请求之前调用身份验证请求,并且它工作正常,但是自从这个错误开始发生后,我修改了我的代码以仅偶尔进行身份验证并且对一堆使用相同的令牌SOAP 请求。这大大减少了出现此错误的机会,但我仍然偶尔会在流量高时遇到它。
在我看来,RestClient 和 HttpWebRequest 在后台使用相同的套接字,其中之一没有正确清理。似乎 RestClient 从 HttpWebRequest 继承了一些垃圾,因为该服务的“404 - 未找到”return 看起来与我故意导航到身份验证服务的错误 URL 时相同。
也有可能我没有正确处理或关闭某些东西,但我尝试关闭我能找到的每个流、客户端或连接,并在各处注入 'using',但似乎无济于事。
我尝试联系政府的技术支持,但根据我以前的经验判断,他们甚至需要几周时间才能帮我联系到能够理解问题的人。
这是 404 HTML 我得到:
<!doctype html>
<html lang="en">
<head>
<title>HTTP Status 404 – Not Found</title>
<style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style>
</head>
<body>
<h1>HTTP Status 404 – Not Found</h1>
<hr class="line" />
<p>
<b>Type</b> Status Report</p>
<p>
<b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p>
<hr class="line" />
<h3>Apache Tomcat/9.0.35</h3>
</body>
</html>
你有什么建议可以防止这种情况发生吗?
正如我所说,我目前有一些变通办法,可以在有机会时刷新令牌,甚至在必要时延迟常规请求,但我希望尽可能不使用变通办法,尤其是因为我不知道套接字超时是什么。在大多数计算机上为 5 秒,但在某些无线网络上它会保持 ESTABLISHED 将近一分钟。
如果重要的话,两个服务都在 HTTPS 上。
谢谢!
我通过制作一个小型控制台应用程序解决了这个问题,该应用程序通过命令行参数接收凭据,连接到其余服务并returns标准输出中的令牌。
父应用程序在后台定期调用此 exe,并从标准输出中读取一个新令牌。