C# SQL Server CLR Request error on functions GET and POST - c#

I followed the GitHub documentation to implement the http requests with the CURL extension, work in SQL Server 2008 R2, Visual Studio 2010 and .NET 3.5.
I managed to compile and sign correctly the .dll in visual studio, to then create the schemas and functions in SQL Server, since everything works correctly, I can perform GET and POST from SQL Server, however, when wanting to perform a GET or a POST at SABA API, it generates a series of errors.
A .NET Framework error occurred during execution of user-defined
routine or aggregate "XGET": System.Net.WebException: The underlying
connection was closed: An unexpected error occurred on a send. --->
System.IO.IOException: Received an unexpected EOF or 0 bytes from the
transport stream. System.IO.IOException: at
System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset,
Int32 count) at System.Net.Security.SslState.StartReadFrame(Byte[]
buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer,
AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslState.CheckCompletionBeforatextReceive(ProtocolTokat
message, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslState.StartSatdBlob(Byte[] incoming, Int32
count, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslState.ForceAuthattication(Boolean receiveFirst,
Byte[] buffer, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslState.ProcessAuthattication(LazyAsyncResult
lazyResult) at
System.Net.TlsStream.CallProcessAuthattication(Object state) at
System.Threading.ExecutionContext.runTryCode(Object userData) at
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode
code, CleanupCode backoutCode, Object userData) at
System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state) at
System.Net.TlsStream.ProcessAuthattication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32
size) at System.Net.ConnectStream.WriteHeaders(Boo ...
System.Net.WebException: at
System.Net.WebCliatt.DownloadDataInternal(Uri address, WebRequest&
request) at System.Net.WebCliatt.DownloadString(Uri address) ...
This is the code of the Assembly
using Microsoft.SqlServer.Server;
using System;
using System.Data.SqlTypes;
using System.Net;
using System.Threading;
public static class Curl
{
[SqlFunction]
[return: SqlFacet(MaxSize = -1)]
public static SqlChars Get(SqlChars H, SqlChars url)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
var client = new WebClient();
AddHeader(H, client);
return new SqlChars(
client.DownloadString(
Uri.EscapeUriString(url.ToSqlString().Value)
).ToCharArray());
}
[SqlProcedure]
public static void Post(SqlChars H, SqlChars d, SqlChars url)
{
var client = new WebClient();
AddHeader(H, client);
if (d.IsNull)
throw new ArgumentException("You must specify data that will be sent to the endpoint", "#d");
var response =
client.UploadString(
Uri.EscapeUriString(url.ToSqlString().Value),
d.ToSqlString().Value
);
SqlContext.Pipe.Send("Request is executed. " + response);
}
[SqlProcedure]
public static void PostWithRetry(SqlChars H, SqlChars d, SqlChars url)
{
var client = new WebClient();
AddHeader(H, client);
if (d.IsNull)
throw new ArgumentException("You must specify data that will be sent to the endpoint", "#d");
int i = RETRY_COUNT;
string response = "";
do try
{
response =
client.UploadString(
Uri.EscapeUriString(url.ToSqlString().Value),
d.ToSqlString().Value
);
i = -1;
break;
}
catch (Exception ex)
{
SqlContext.Pipe.Send("Error:\t" + ex.Message + ". Waiting " + DELAY_ON_ERROR + "ms.");
i--;
Thread.Sleep(DELAY_ON_ERROR);
}
while (i > 0);
if (i == -1)
SqlContext.Pipe.Send("Request is executed." + response);
}
static readonly int RETRY_COUNT = 3;
static readonly int DELAY_ON_ERROR = 50;
public static bool IsNullOrWhiteSpace(this string theString)
{
if (theString == null)
{
return false;
}
if (theString.Trim() == string.Empty)
{
return false;
}
return true;
}
private static void AddHeader(SqlChars H, WebClient client)
{
if (!H.IsNull)
{
string header = H.ToString();
if (!IsNullOrWhiteSpace(header))
client.Headers.Add(HttpRequestHeader.UserAgent, header);
}
}
};
And this how to use in SQL Query
declare #hkey nvarchar(4000) = 'SabaCertificate: 31336132353061666330315E235E756F6E6555E6261536974655E235E656E5F55535E235E536162615E235E24414021463393C69358BE384802BA1BBEAD3B4661862F193021435F7E28A30F7540FE661B9C5F30FDB06C';
declare #endpoint nvarchar(1000) = 'https://libertad-api.sabacloud.com/v1/location?count=10&startPage=1';
select curl.xget(#hkey, #endpoint)
I already test it in PostMan, entering the Header of SabaCertificate, and if it throws a result at me, however, when the certificate is not correct it also throws a response and it is not shown.
Bad Request Example:
{"errorCode":123,"errorMessage":"Invalid or expired Certificate"}
But it also does not give me the answer of the certificate error, that I have to change in my WebClient for this to work.
Added to this I think the certificate is too big because sometimes I get this error:
The identifier that starts with 'SabaCertificate:
31336132353061666330315E235E756F6E6555E6261536974655E235E656E5F55535E235E536162615E235E24414021463393C69358BE384802BA1BBEAD3B4661862F193021435F7E28A30F7540FE661B9C5F30FDB06C'
is too long. Maximum length is 128.

One definite problem in the code is a slight change you made to the original code. In your AddHeader method you have the following line:
client.Headers.Add(HttpRequestHeader.UserAgent, header);
You need to remove the HttpRequestHeader.UserAgent because the code is now creating a "UserAgent" header with a value of whatever you pass in, which is "SabaCertificate: 31336132....".
You will also need to change the security protocols that you are setting as they are not correct. You should try:
ServicePointManager.SecurityProtocol |= (SecurityProtocolType)3072; // TLS 1.2
Since you are using .NET 3.5 via SQL Server 2008 R2, you cannot specify SecurityProtocolType.Tls12 since that value had not yet been added to the enum in Framework Version 3.5, so you have to use the numeric value as shown above. Please keep in mind that the actual ability to do the security protocol is a function of the underlying OS, so it is possible that an older version of Windows / Windows Server does not support TLS 1.2, or might need a registry setting changed in order to do so. You will have to play around with that if you continue to get similar errors from System.Net.TlsStream.
Also, the following error:
The identifier that starts with 'SabaCertificate: 31336...30FDB06C' is too long. Maximum length is 128.
is from user-error. An "identifier" is an item name within SQL Server (objects, Logins, variables, etc). This means that you are doing something different (and wrong) when that error happens, but I can't see how it could be coming from your code, at least not the Get method, as that has no internal interaction with the database.

Related

SmtpClient.Dispose throws System.IO.IOException

My code sends e-mails like this:
private void DispatchMail(MailMessage mailMessage)
{
using (var smtpClient = new SmtpClient())
{
smtpClient.Send(mailMessage);
}
}
The MailMessage instances are very simple with a HTML body and no attachments.
The configuration of the SmtpClient is in web.config like this:
<system.net>
<mailSettings>
<smtp from="yourmail#gmail.com">
<network host="mailprovider.org" port="587" enableSsl="true" userName="username#host" password="secret" />
</smtp>
</mailSettings>
</system.net>
Whenever the method DispatchMail is called, the mail is actually sent to the recipient, however I get an exception in the implicitly called SmtpClient.Dispose method.
Exception: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Security._SslStream.StartFrameBody(Int32 readBytes, Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security._SslStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security._SslStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.TlsStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.Mail.SmtpPooledStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.Stream.Dispose()
at System.Net.ConnectionPool.Destroy(PooledStream pooledStream)
at System.Net.ConnectionPool.ForceCleanup()
at System.Net.ConnectionPoolManager.CleanupConnectionPool(ServicePoint servicePoint, String groupName)
at System.Net.Mail.SmtpClient.Dispose(Boolean disposing)
at System.Net.Mail.SmtpClient.Dispose()
at QueuedMailDispatcherService.DispatchMail(MailMessage mailMessage)
Inner exception: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
Is this a bug in the .NET Framework 4.5.2 or am I mismanaging the life-cycle of the SMTP client?
The SMTP server in question responds as "Microsoft ESMTP MAIL Service".
Update
First I dismissed this problem since it only happened on my machine, but then it happened on the production machine running same code but with release configuration.
Since this error happens intermittently I have decided to modify the method to use a two-level exception handling strategy where any exception occurring when Dispose is called is ignored.
When I was able to catch this error and step through the framework source it seemed like the offset parameter was corrupted (it was several MB higher than the buffer.Length) somewhere between System.Net.Sockets.NetworkStream.Read and System.Net.Sockets.Socket.Receive. However further inspection of the source does not imply that the offset would be changed. In fact System.Net.Security._SslStream.StartFrameHeader sets offset to 5 higher up in the call stack. This leads me to believe that one of the following things happened:
The debugged machine level code was not matching the source I stepped through in Visual Studio
Some kind of memory corruption (however the problem has persisted through one reboot and on two different machines both in debug and release configuration)
I was actually debugging two different threads without realizing it
There is some kind of difficult rare race condition going on
There is some kind of optimization going wrong, maybe in combination with the race condition
The SMTP server implementation or the network transmission is not reliable during SMTP Quit, however it is a well known SMTP server software and I cannot see why this problem would be intermittent also it does not explain the out of bound offset value.
Try the below sample:
using System.Net.Mail;
private void DispatchMail(string to)
{
var mail = new MailMessage
{
Subject = "subject",
From = new MailAddress(#"sender email", #"sender name")
};
mail.To.Add(to);
mail.Body = "your message body";
var smtp = new SmtpClient(#"smtp mail server address");
smtp.Port = 587;
smtp.Credentials = new System.Net.NetworkCredential("username", "password");
smtp.EnableSsl = true;
smtp.Send(mail);
mail.Dispose();
smtp.Dispose();
}
you can do something like this
var fromAddress = new MailAddress("fromAddress", "My Name");
var toAddress = new MailAddress("gtoAddress ", "Mr Test");
const string fromPassword = "fromPassword";
string subject = "hello";
string body = "how are you doing?";
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword),
Timeout = 20000
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body
})
{
smtp.Send(message);
}
and enable less secure apps on your Gmail account here

VSTO Outlook Plugin - HttpClient.PostAsync fails without fiddler

I unfortunately had Fiddler running for the whole time I was developing this feature in the plugin and since deploying to clients I found that it will not work for anyone - unless they run fiddler as well! It also does not work on my development machine if I stop running Fiddler.
The main error is Error while copying content to a stream.. So I investigated the possibility of the data I'm POSTing being released by the GC before it finished hitting the server (That, to me, explained why running Fiddler solved it - as I believe the request gets sent to Fiddler first, and then Fiddler sends it to the server). However I couldn't find anything to support that this might be the problem. I have tried making sure it holds onto the data but I don't feel like I'm going down the right route.
The code is roughly like this:
HttpClientHandler httpHandler = new HttpClientHandler { UseDefaultCredentials = true };
var client = new HttpClient(httpHandler, false);
client.BaseAddress = new Uri(BaseUrl + "api/job/PostTest");
var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture));
content.Add(new StringContent(mailItem.HTMLBody, Encoding.UTF8), "BodyHtml");
// content.Add()'s... Omitted for brevity
var response = client.PostAsync(BaseUrl + "api/job/PostTest", content);
response.ContinueWith(prevTask => {
if (prevTask.Result.IsSuccessStatusCode)
{
System.Diagnostics.Debug.WriteLine("Was success");
}
else
{
System.Diagnostics.Debug.WriteLine("Was Error");
}
}, System.Threading.Tasks.TaskContinuationOptions.OnlyOnRanToCompletion);
response.ContinueWith(prevTask =>{
MessageBox.Show(prevTask.Exception.ToString());
}, System.Threading.Tasks.TaskContinuationOptions.OnlyOnFaulted);
The full exception details are:
System.AggregateException: One or more errors occurred. ---> System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.Net.WebException: The request was aborted: The request was canceled.
at System.Net.ConnectStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
--- End of inner exception stack trace ---
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
at System.Net.Http.StreamToStreamCopy.StartRead()
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
---> (Inner Exception #0) System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.Net.WebException: The request was aborted: The request was canceled.
at System.Net.ConnectStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
--- End of inner exception stack trace ---
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
at System.Net.Http.StreamToStreamCopy.StartRead()
--- End of inner exception stack trace ---<---
If anyone could point me to some resources that help me or point out where I'm going wrong that would help a lot!
When developing our IronBox Outlook plugin we ran into this issue. What we found was that within the VSTO context, the ServicePointManager supported security protocols was only Tls and Ssl3 (which was not going to work with our API which supported only TLS 1.2 or better).
You can check this easily from within your VSTO code like this (here's an example from when we hooked into Application.ItemSend event):
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// Handle event when item is sent
this.Application.ItemSend += Application_ItemSend;
}
private void Application_ItemSend(object Item, ref bool Cancel)
{
foreach (var c in (SecurityProtocolType[])Enum.GetValues(typeof(SecurityProtocolType)))
{
if (ServicePointManager.SecurityProtocol.HasFlag(c))
{
Debug.WriteLine(c.ToString());
}
}
Cancel = false;
}
We solved it by setting the ServicePointManager.SecurityProtocol property to support Tls12 like this:
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
Hope this helps someone someday,
Kevin
After much searching and much messing about I've not been able to solve this problem using HttpClient so instead what I've done is using WebClient. In case someone else has this problem in the future I'm posting what I ended up using:
System.Net.WebClient wc = new System.Net.WebClient();
wc.Headers.Add("Content-Type", String.Format("multipart/form-data; boundary=\"{0}\"", multipartFormBoundary));
wc.UseDefaultCredentials = true;
try
{
var wcResponse = wc.UploadData(BaseUrl + "api/job/PostJobEmailNote", byteArray);
}
catch(Exception e)
{
// response status code was not in 200's
}
I think problem may be with using anonymous function that returns void. They're a little bit problematic. Changing my lambda to one that returns bools fixed the issue for me.

C# Async File Download throws System.IO Exception [duplicate]

The following code throws a IOException with the message: "The specified registry key does not exist."
HttpClient client = new HttpClient();
Uri uri = new Uri("http://www.google.com");
client.GetAsync(uri);
This is just in a console app in Main. It looks like the error is being thrown by mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode, string str). I have no idea why this error is being thrown or how to start debugging it.
Edit stack trace:
at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)
It's just 1 line and there is no inner exxception etc..
The call stack is:
mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode, string str) + 0x189 bytes
mscorlib.dll!Microsoft.Win32.RegistryKey.GetValueKind(string name) + 0x7f bytes
System.dll!System.Net.HybridWebProxyFinder.InitializeFallbackSettings() + 0x9e bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.dll!System.Net.AutoWebProxyScriptEngine.AutoWebProxyScriptEngine(System.Net.WebProxy proxy, bool useRegistry) + 0xd0 bytes
System.dll!System.Net.WebProxy.UnsafeUpdateFromRegistry() + 0x2c bytes
System.dll!System.Net.Configuration.DefaultProxySectionInternal.DefaultProxySectionInternal(System.Net.Configuration.DefaultProxySection section) + 0x1d8 bytes
System.dll!System.Net.Configuration.DefaultProxySectionInternal.GetSection() + 0xec bytes
System.dll!System.Net.WebRequest.InternalDefaultWebProxy.get() + 0xcc bytes
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri uri, System.Net.ServicePoint servicePoint) + 0xdf bytes
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri uri, bool returnResponseOnFailureStatusCode, string connectionGroupName, System.Action<System.IO.Stream> resendRequestContent) + 0x2b bytes
System.Net.Http.dll!System.Net.Http.HttpClientHandler.CreateAndPrepareWebRequest(System.Net.Http.HttpRequestMessage request) + 0x59 bytes
System.Net.Http.dll!System.Net.Http.HttpClientHandler.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + 0xf4 bytes
System.Net.Http.dll!System.Net.Http.HttpMessageInvoker.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + 0x4f bytes
System.Net.Http.dll!System.Net.Http.HttpClient.SendAsync(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) + 0x13e bytes
System.Net.Http.dll!System.Net.Http.HttpClient.GetAsync(System.Uri requestUri, System.Net.Http.HttpCompletionOption completionOption) + 0xc bytes
ConsoleServiceTest.exe!ConsoleServiceTest.Program.Main(string[] args) Line 20 + 0x17 bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x5a bytes
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x285 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x9 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x57 bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x51 bytes
[Native to Managed Transition]
It seems that this is caused by a recent security update for the .NET Framework: MS12-074: Vulnerabilities in .NET Framework could allow remote code execution: November 13, 2012 (KB 2745030)
It all boils down to the following code in the web proxy resolution:
[RegistryPermission(SecurityAction.Assert, Read=#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework")]
private static void InitializeFallbackSettings()
{
allowFallback = false;
try
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\.NETFramework"))
{
try
{
if (key.GetValueKind("LegacyWPADSupport") == RegistryValueKind.DWord)
{
allowFallback = ((int) key.GetValue("LegacyWPADSupport")) == 1;
}
}
catch (UnauthorizedAccessException)
{
}
catch (IOException)
{
}
}
}
catch (SecurityException)
{
}
catch (ObjectDisposedException)
{
}
}
As you can see it checks for a specific registry key mentioned in the KB article. Also you should note that the exception is caught internally, but you see it because you have enabled First Chance Exceptions in the debug options of Visual Studio.
If you want to not see this exception you should add the specified registry key with value 0:
Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0
and for 32-bit processes on 64-bit machines:
Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0
I agree with Ligaz's answer, and I've logged a Connect issue about this bug: https://connect.microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception-on-the-first-call#details
Save the following into a .reg file and import it into the registry to prevent this error from being raised:
Windows Registry Editor Version 5.00
; The following value prevents an IOException from being thrown and caught
; by System.Net.HybridWebProxyFinder.InitializeFallbackSettings() (in System.dll)
; when WebRequest.Create is first called. By default the "LegacyWPADSupport"
; value doesn't exist, and when InitializeFallbackSettings calls GetValueKind,
; an IOException is thrown. This adds the value with its default of false to
; prevent the exception.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"LegacyWPADSupport"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
"LegacyWPADSupport"=dword:00000000
For whatever reason, your HttpClient code is looking for proxy settings in the registry and cannot open the key. A look through the code shows that it attempts to open HKCU and then go to one of the following keys in order:
"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
"HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
One of these three is potentially the key your process has no access to, why I am not sure. One possible fix is to disable Automatically Detect Proxy Settings.
Otherwise, you'll need to figure out exactly what key it is loading and we'll do that with two steps.
Enable System.Net logging.
Download and run Procmon, filtering on registry access for your application, like so:
Once opened, disable capturing if enabled (the magnifying glass should have a red X through it).
Start filtering on your processes name.
Unselect all options except Registry Entries
Enable capturing (click the magnifying glass)
Run your application
Find the offending entry in the log, double click to see which key it was opening
Once you determine the offending key, you can work to figure out why your application does not have access to it. Perhaps, if the name of your application is any indication, the user account your service is running under lacks access to the registry key.

Invoke The stream does not support reading

I have a c# network application where alot of anonymous users connect to (game service).
Now I check the logs and occasionally I see this exception:
[10:30:18.21352] System.Int32 Read(Byte[], Int32, Int32): The stream does not support reading.
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at BusinessLayer.Listener.ListenerWorker.ProcessClient(Object obj) in File.cs:line 141
This error comes from a NetworkStream object, now I am trying to reproduce the problem, but how? How can I get this exception?
I tried disconnecting myself, but that just gives a timeout, tried other things, but cannot get it to work.
Maybe somebody has an idea?
Contents of the file is:
private static void ProcessClient(
Object obj)
{
ISession session = (ISession)obj;
NetworkStream networkStream = null;
try
{
DebugUtility.SetThreadName("Worker: {0}", session.Name);
networkStream = session.TcpClient.GetStream();
networkStream.ReadTimeout = Config.ReadTimeout;
// Loop received packets (blocks untill next packet)
Int32 packetSize;
Byte[] buffer = new Byte[session.PacketSize];
while ((packetSize = networkStream.Read(buffer, 0, buffer.Length)) != 0)
{
// Get String from packet bytes
String packet = Encoding.UTF8.GetString(buffer, 0, packetSize);
// Check if packet has data
if (String.IsNullOrEmpty(packet))
continue;
// Log biggest received package
DebugUtility.CheckMaxPacketSize(session.Name, packet.Length);
// Handle packet (in new thread)
Logger.DebugLog("Received: {0}", packet);
ThreadPool.QueueUserWorkItem(session.HandlePacket, packet);
}
}
catch (Exception ex)
{
Logger.LogException(ex);
}
finally
{
if (networkStream != null)
networkStream.Close();
if (session != null)
session.Disconnect();
}
}
What arguments are you passing in the
System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
method. Are you using any of NetworkStream.Length or NetworkStream.Position properties.
i.e is it somthing like (not exactly)
System.Net.Sockets.NetworkStream.Read(buffer, stream.Position, stream.Length)
then as explained in MSDN documentation use of NetworkStream.Length and NetworkStream.Position properties will always throw a NotSupportedException as its not currently Supported.

An established connection was aborted by the software in your host machine

Sorry if this is a bit long winded but I thought better to post more than less.
This is also my First post here, so please forgive.
I have been trying to figure this one out for some time. and to no avail, hoping there is a genius out there who has encountered this before.
This is an intermittent problem and has been hard to reproduce.
The code that I am running simply calls a web service
The Web Service call is in a loop (so we could be doing this a lot, 1500 times or more)
Here is the code that is causing the error:
HttpWebRequest groupRequest = null;
WebResponse groupResponse = null;
try
{
XmlDocument doc = new XmlDocument();
groupRequest = (HttpWebRequest)HttpWebRequest.Create(String.Format(Server.HtmlDecode(Util.GetConfigValue("ImpersonatedSearch.GroupLookupUrl")),userIntranetID));
groupRequest.Proxy = null;
groupRequest.KeepAlive = false;
groupResponse = groupRequest.GetResponse();
doc.Load(groupResponse.GetResponseStream());
foreach (XmlElement nameElement in doc.GetElementsByTagName(XML_GROUP_NAME))
{
foreach (string domain in _groupDomains )
{
try
{
string group = new System.Security.Principal.NTAccount(domain, nameElement.InnerText).Translate(typeof(System.Security.Principal.SecurityIdentifier)).Value;
impersonationChain.Append(";").Append(group);
break;
}
catch{}
} // loop through
}
}
catch (Exception groupLookupException)
{
throw new ApplicationException(String.Format(#"Impersonated Search ERROR: Could not find groups for user<{0}\{1}>", userNTDomain, userIntranetID), groupLookupException);
}
finally
{
if ( groupResponse != null )
{
groupResponse.Close();
}
}
Here is the error that happens sometimes:
Could not find groups for user<DOMAIN\auser> ---> System.IO.IOException: Unable to read
data from the transport connection: An established connection was aborted by the
software in your host machine. ---> System.Net.Sockets.SocketException: An established
connection was aborted by the software in your host machine at
System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags
socketFlags) at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32
size) --- End of inner exception stack trace --- at System.Net.ConnectStream.Read(Byte[]
buffer, Int32 offset, Int32 size) at System.Xml.XmlTextReaderImpl.ReadData() at
System.Xml.XmlTextReaderImpl.ParseDocumentContent() at
System.Xml.XmlLoader.LoadDocSequence
(XmlDocument parentDoc) at System.Xml.XmlDocument.Load(XmlReader reader) at
System.Xml.XmlDocument.Load(Stream inStream) at
MyWebServices.ImpersonatedSearch.PerformQuery(QueryParameters parameters,
String userIntranetID, String userNTDomain)--- End of inner exception stack trace
---at MyWebServices.ImpersonatedSearch.PerformQuery(QueryParameters parameters, String userIntranetID, String userNTDomain)
--- End of inner exception stack trace ---
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message,
WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName,
Object[] parameters) at MyProgram. MyWebServices.ImpersonatedSearch.PerformQuery
(QueryParameters parameters, String userIntranetID, String userNTDomain)
at MyProgram.MyMethod()
Sorry that was alot of code to read through.
This happens about 30 times out of around 1700
You're probably hitting a timeout. First of all, turn the keepalive back on. Second, check the timestamps on the request and reply. If there is a firewall between the sender and receiver, make sure that it isn't closing the connection because of idle timeout. I've had both these problems in the past, although with generic socket programming, not DB stuff.

Categories

Resources