Я работаю над проектом, который использует API RTC и формирует аутентификацию. Я наткнулся на немного странное поведение, и я просто не могу понять этого.HttpWebRequest .GetResponse throws WebException «Операция завершена»
Сценарий, который сыграл на сегодняшний день, заключается в том, что я могу успешно запустить этот проект локально до конца. То есть, этот конкретный кусок кода может:
- Связаться с удаленным сервером и успешно пройти проверку подлинности
- После аутентификации я могу передать XML, чтобы обновить билет в RTC
Проблема начинается когда я публикую на нашем сервере IIS (7.5). Все работает нормально вплоть до последнего вызова .GetResponse, который использует метод PUT для передачи моего XML для обновления билета в RTC. Я продолжаю получать «Операция истекло».
Я потратил буквально дни, пытаясь понять, что это делает всевозможные вещи, но ничего не оказалось полезным.
В качестве теста я изменил метод PUT во втором вызове GET. И это работает! Если я использовал PUT с .AllowAutoRedirect = false, он работает так, что я получаю ответ назад, но потом ничего не происходит на стороне RTC, поэтому запрос явно игнорируется. Я также заметил, что возвращаемый статус помечен как «Найдено» вместо «ОК».
Некоторые люди думали, что на этом этапе возможно отсутствие связи между удаленным сервером и веб-сервером. Это не так, если аутентификация работает, и это происходит с тем же сервером. Я также вручную передал вызов XML/PUT с использованием RESTClient на веб-сервере, который был принят отлично.
Я просто не могу понять, почему он работает от конца до конца при запуске локально, но разыгрывается после развертывания в IIS?
Я попытался использовать трассировку журнала, и я не совсем уверен, получаю ли я от него что-нибудь полезное. Это может быть совершенно не связаны, но я могу видеть это в журнале, который генерируется на сервере IIS:
<EventData>
<Data Name="ContextId">{00000000-0000-0000-12AF-0080000000F8}</Data>
<Data Name="ModuleName">ManagedPipelineHandler</Data>
<Data Name="Notification">128</Data>
<Data Name="HttpStatus">500</Data>
<Data Name="HttpReason">Internal Server Error</Data>
<Data Name="HttpSubStatus">0</Data>
<Data Name="ErrorCode">0</Data>
<Data Name="ConfigExceptionInfo"></Data>
</EventData>
Как я уже говорил, я не уверен, если это даже связано с проблемой я имею, но вместо того, чтобы игнорировать его, я думал, что поделюсь.
код, который формирует вызов (извините стандарт кодирования, это работа, и получил грязный пробуя различные вещи, чтобы решить эту проблему)
//Setup webrequest
CookieContainer _cookies = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(getPath);
var test44 = test4.ToString();
request.CookieContainer = _cookies;
request.ContentType = "application/rdf+xml";
request.Accept = "application/rdf+xml";
request.Method = "PUT";
request.AllowAutoRedirect = true;
request.AllowWriteStreamBuffering = true;
request.Timeout = 40000;
byte[] bytes = Encoding.ASCII.GetBytes(test44);
request.ContentLength = bytes.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(bytes, 0, bytes.Length);
dataStream.Close();
//Pass request
logger.Info("Made it up to start of RTC request for secure document.");
using (HttpWebResponse getrespn = requestSecureDocument(request, "https://myserver:9100/jazz", "username", "pass", test44))
{
//Stream ReceiveStream = getrespn.GetResponseStream();
// Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
//StreamReader readStream = new StreamReader(ReceiveStream);
//response = readStream.ReadToEnd();
getrespn.Close();
}
Сегмент кода, который взаимодействует с сервером RTC (на основе, например, из: https://nkumar83.wordpress.com/2013/06/13/consuming-rtc-rational-team-concert-oslc-apis-using-c-post-1-authentication/ со своими собственными ухищрений):
public static HttpWebResponse requestSecureDocument(HttpWebRequest _requestItem, string _rtcServerURL, string _userName, string _password, string passXml)
{
try
{
//FormBasedAuth Step 1: Request the resource
HttpWebRequest _request = (HttpWebRequest)WebRequest.Create(_requestItem.RequestUri);
_request.CookieContainer = _requestItem.CookieContainer;
//store the response in _docResponse variable
HttpWebResponse _docResponse = (HttpWebResponse)_request.GetResponse();
//HttpStatusCode.OK indicates that the request succeeded
if (_docResponse.StatusCode == HttpStatusCode.OK)
{
//X-com-ibm-team... header signifies form based authentication is being used
string _rtcAuthHeader = _docResponse.Headers["X-com-ibm-team-repository-web-auth-msg"];
if ((_rtcAuthHeader != null) && _rtcAuthHeader.Equals("authrequired"))
{
_docResponse.GetResponseStream().Flush();
_docResponse.Close();
//Prepare form for authentication
HttpWebRequest _formPost = (HttpWebRequest)WebRequest.Create(_rtcServerURL + "/j_security_check");
_formPost.Method = "POST";
_formPost.Timeout = 30000;
_formPost.CookieContainer = _request.CookieContainer;
_formPost.Accept = "text/xml";
_formPost.ContentType = "application/x-www-form-urlencoded";
string _authString = "j_username=" + _userName + "&j_password=" + _password;
Byte[] _outBuffer = Encoding.UTF8.GetBytes(_authString);
_formPost.ContentLength = _outBuffer.Length;
Stream _str = _formPost.GetRequestStream();
_str.Write(_outBuffer, 0, _outBuffer.Length);
_str.Close();
//FormBasedAuth Step 2: Submit the login form and get response
HttpWebResponse _formResponse = (HttpWebResponse)_formPost.GetResponse();
_rtcAuthHeader = _formResponse.Headers["X-com.ibm-team.repository-web-auth-msg"];
//Check if auth failed
if ((_rtcAuthHeader != null) && _rtcAuthHeader.Equals("authfailed"))
{
//auth fialed
var fail = "";
}
else
{
//login successful
//FormBasedAuth Step 3: Resend the request for the protected resource
_formResponse.GetResponseStream().Flush();
_formResponse.Close();
using (HttpWebResponse getresp = (HttpWebResponse)_requestItem.GetResponse()) *** THIS IS TH LINE WHICH THROWS THE EXCEPTION ***
{
return getresp;
}
}
}
}
return _docResponse;
}
catch (WebException e)
{
var filePath = AppDomain.CurrentDomain.GetData("DataDirectory") + @"/trapA.xml";
using (StreamWriter writer = new StreamWriter(filePath, true))
{
writer.WriteLine("Message: Failed to trigger getresponse successfully: " + e);
}
}
return null;
}
Надежда кто-то может помочь: о)
Обновление только с дополнительной информацией. Я пытался получить более подробную информацию о веб-эксклюзии, то есть код состояния и описание состояния, но, как представляется, они недоступны, поскольку при попытке доступа к этим свойствам генерируется нулевая ссылка. HRESULT возвращается -2146233079. – Sulphy
Ну, я подумал, что я попробую использовать метод WebClient, чтобы он работал локально, и невероятно, что я получаю то же самое, что и при публикации на веб-сервере. Мне интересно, есть ли что-то с самим сервером, поэтому попробуем установить последний и самый большой установщик .net (v4.5.2), посмотрим, что это делает. – Sulphy
Увы, без радости: o ( – Sulphy