System net http httprequestexception an error occurred while sending the request

Description randomly fails, sometimes they do all work correctly. System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.IO.IOException: The response ende...

Description

randomly fails, sometimes they do all work correctly.

System.Net.Http.HttpRequestException: An error occurred while sending the request.
 ---> System.IO.IOException: The response ended prematurely.
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
   at Essensoft.AspNetCore.Payment.WeChatPay.V2.Extensions.HttpClientExtensions.PostAsync[T](HttpClient client, IWeChatPayRequest`1 request, IDictionary`2 textParams)
   at Essensoft.AspNetCore.Payment.WeChatPay.V2.WeChatPayClient.ExecuteAsync[T](IWeChatPayRequest`1 request, WeChatPayOptions options)
   at lambda_method72(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

Configuration


.NET SDK (reflecting any global.json):
 Version:   5.0.101
 Commit:    d05174dc5a

Runtime Environment:
 OS Name:     debian
 OS Version:  10
 OS Platform: Linux
 RID:         debian.10-x64
 Base Path:   /usr/share/dotnet/sdk/5.0.101/

Host (useful for support):
  Version: 5.0.1
  Commit:  b02e13abab

.NET SDKs installed:
  5.0.101 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 5.0.1 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 5.0.1 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

  • Remove From My Forums
  • Question

  • HI

    This exception is bothering me since many days now. I am trying to send a POST call to a Last.fm API method. But whenever I send a call, I get the following exception —  «An exception of type ‘System.Net.Http.HttpRequestException’ occurred in mscorlib.dll
    but was not handled in user code».
    Additional information: An error occurred while sending the request. If I print out the exception it says —

    System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly.

    My GET calls to the authentication API of last.fm are working fine.

    I am attaching a code snippet:

    private async void Collection_Click_1(object sender, RoutedEventArgs e)
            {
    /* .
       .
       .
    */
    
    HttpClient Cli = new HttpClient();
    string track_updateNowPlaying = "method=track.updateNowPlaying&track=" + id3.Title + "&artist=" +id3.Artist + "&album=" + id3.Album + "&api_key=" + lfm_api_key + "&api_sig=" + updtrack_sig + "&sk=" + Globalv.session_key;
    
    HttpContent tunp =new StringContent(track_updateNowPlaying);
    
    try
    {
        //getting exception in the following line
        HttpResponseMessage upd_now_playing = await cli.PostAsync(new Uri("http://ws.audioscrobbler.com/2.0/", UriKind.RelativeOrAbsolute), tunp);
    
    }
    catch(Exception ex) {textblock.text = ex.ToString();}
    }
    
    private async void LoginBtn_Click_1(object sender, RoutedEventArgs e) //this function is called before collection_click_1 function
    {
    /* .
       .
       .
    */
        HttpClient cli = new HttpClient();
        string auth_request = "http://ws.audioscrobbler.com/2.0/?method=auth.getMobileSession&username=" + UsernameTBx.Text + "&authToken=" + lfm_authToken + "&api_key=" + lfm_api_key + "&api_sig=" + lfm_api_sig;
    
        HttpResponseMessage auth = await cli.GetAsync(auth_request); //this works fine...
    
    }

    Need some help here.


    -Sagar

    • Edited by

      Wednesday, April 4, 2012 9:26 PM

Answers

  • Hi

    I guess I figured it out. I’m keeping the post for others to refer.

    The case was that Last.fm servers do not accept Expect:100Continue in the header field. So I had to explicitly change it to false. Last.fm hasn’t mentioned this issue clearly in their documentation. Took long to figure out…

    Had to add the following:

    HttpClient cli = new HttpClient(); cli.DefaultRequestHeaders.ExpectContinue = false;


    -Sagar

    • Marked as answer by
      Matt SmallMicrosoft employee, Moderator
      Friday, April 6, 2012 6:15 PM

Recently, I came across an interesting problem. Whenever we run my ASP.NET Core application in Development environment, I get the below exception.

Details about the setup:

The below template was used:

Angular project template with ASP.NET core — https://docs.microsoft.com/en-us/aspnet/core/client-side/spa/angular?view=aspnetcore-2.2&tabs=visual… along with AAD integration.

When we publish this application in Azure App Service, it works fine. But when we run the same application in Visual Studio, it fails with the below error.

CaptureError.JPG

An unhandled exception occurred while processing the request.IOException: The server returned an invalid or unrecognized response.
System.Net.Http.HttpConnection.FillAsync()HttpRequestException: An error occurred while sending the request.
System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)HttpRequestException: Failed to proxy the request to http://localhost:54232/, because the request to the proxy target failed. Check that the proxy target server is running and accepting requests to http://localhost:54232/.The underlying exception message was 'An error occurred while sending the request.'.Check the InnerException for more details.
Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.PerformProxyRequest(HttpContext context, HttpClient httpClient, Task<Uri> baseUriTask, CancellationToken applicationStoppingToken, bool proxy404s)·      Stack 
·      Query 
·      Cookies 
·      Headers

IOException: The server returned an invalid or unrecognized response.

System.Net.Http.HttpConnection.FillAsync()
System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(bool foldedHeadersAllowed)
System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)Show raw exception details

HttpRequestException: An error occurred while sending the request.

System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, bool doRequestAuth, CancellationToken cancellationToken)
System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, bool doRequestAuth, CancellationToken cancellationToken)
System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task<HttpResponseMessage> sendTask, HttpRequestMessage request, CancellationTokenSource cts, bool disposeCts)
Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.PerformProxyRequest(HttpContext context, HttpClient httpClient, Task<Uri> baseUriTask, CancellationToken applicationStoppingToken, bool proxy404s)Show raw exception details

HttpRequestException: Failed to proxy the request to http://localhost:54232/, because the request to the proxy target failed. Check that the proxy target server is running and accepting requests to http://localhost:54232/. The underlying exception message was 'An error occurred while sending the request.'.Check the InnerException for more details.

Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.PerformProxyRequest(HttpContext context, HttpClient httpClient, Task<Uri> baseUriTask, CancellationToken applicationStoppingToken, bool proxy404s)
Microsoft.AspNetCore.Builder.SpaProxyingExtensions+<>c__DisplayClass2_0+<<UseProxyToSpaDevelopmentServer>b__0>d.MoveNext()
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)Show raw exception details

It took almost a whole day for me to narrow down the problem:

  • The AAD auth settings and configurations both in the azure portal as well as the app is correct.
  • The auth flow is same between the working and non-working scenarios.
  • We compared the headers, cookies, tokens etc. very closely between working and non-working cases and nothing is different.
  • We captured the log statement from the .net core and har file and cookie sent and received are all the same.
  • The concerning error was misleading “The server returned an invalid or unrecognized response.”, digging further we identified it was actually a HTTP 400 error underneath.

Sample log file:

Host: localhost:44341
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
upgrade-insecure-requests: 1
MS-ASPNETCORE-TOKEN: c34057dc-48b2-408b-ab2d-c4c768ebecc7
X-Forwarded-For: [::1]:54863
X-Forwarded-Proto: https
X-P2P-PeerDist: Version=1.1
X-P2P-PeerDistEx: MinContentInformation=1.0, MaxContentInformation=2.0Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44341/ 
LoggingConnectionAdapter:Debug: WriteAsync[101] 48 54 54 50 2F 31 2E 31 20 34 30 30 20 42 61 64 20 52 65 71 75 65 73 74 0D 0A 44 61 74 65 3A 20 57 65 64 2C 20 30 33 20 41 70 72 20 32 30 31 39 20 31 39 3A 35 30 3A 32 37 20 47 4D 54 0D 0A 53 65 72 76 65 72 3A 20 4B 65 73 74 72 65 6C 0D 0A 43 6F 6E 74 65 6E 74 2D 4C 65 6E 67 74 68 3A 20 30 0D 0A 0D 0A
HTTP/1.1 400 Bad Request
Date: Wed, 03 Apr 2019 19:50:27 GMT
Server: Kestrel
Content-Length: 0Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 1046.4958ms 400

The actual issue:

We identified that, in development, requests are proxied to the Angular development server that gets started as a background process which is a Node.JS server which has a header limit of ~8kb. Hence, it is failing with 400 error.

Refer: https://nodejs.org/en/blog/vulnerability/november-2018-security-releases/#denial-of-service-with-lar…

Recommendation:

  • So, if you want to use AAD auth in development environment you’re going to need to slim down the cookie, likely by filtering out unneeded claims. There’re some related docs here:

         Refer: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/additional-claims?view=a…

  • Also, we can install latest Nodejs that supports increasing the header size.

         Refer: https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V10.md

Note: This issue impacts any project template that uses the following.

ASP.NET core + Angular + AAD (OAuth)

ASP.NET core + React + AAD (OAuth)

Содержание

  1. What I Broke – Programming and Web Development
  2. Let’s take a look at what I’ve broken today
  3. Http gRPC with .NET Core and Docker – Error starting gRPC call. System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.IO.IOException: The response ended prematurely.
  4. An error occurred while sending the request. #711
  5. Comments
  6. What I Broke – Programming and Web Development
  7. Let’s take a look at what I’ve broken today
  8. Http gRPC with .NET Core and Docker – Error starting gRPC call. System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.IO.IOException: The response ended prematurely.
  9. System net http httprequestexception an error occurred while sending the request
  10. Answered by:
  11. Question
  12. Http Request Exception Class
  13. Definition
  14. Constructors
  15. Properties
  16. Methods
  17. Events

What I Broke – Programming and Web Development

Let’s take a look at what I’ve broken today

Http gRPC with .NET Core and Docker – Error starting gRPC call. System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.IO.IOException: The response ended prematurely.

I’ve been mucking around with gRPC today while using .NET Core and Docker. I have two Microservices in the setup, one server and one client. Because these services will only be communicating internally I intended to use HTTP instead of HTTPS. Unfortunately, I hit the following error while attempting to set this up:

According Microsoft’s eshoponcontainers documentation there are a few extra steps for getting this to work:

Using gRPC without TLS
gRPC works with HTTP/2 only. Usually when a client connects to a server, the connection is done using HTTP1.1 and promoted to HTTP/2 only if both, server and client, support HTTP/2. This promotion is performed using a protocol negotiation, usually implemented using ALPN protocol which requires TLS.

In order to get it to work you need to add the following to your server :

.ConfigureKestrel(options =>
<
options.Listen(IPAddress.Any, 5001, listenOptions =>
<
listenOptions.Protocols = HttpProtocols.Http2;
>);
>);
>);

You then need to explicitly allow HTTP/2 without TLS when creating the client:

Источник

An error occurred while sending the request. #711

If I refresh a page particularly if it is still loading I get a 502 error. Is there any way I can capture exceptions and prevent the 502 from being seen in the browser? The errors can be any of these:

The text was updated successfully, but these errors were encountered:

One way I have managed to supress it is by changing the EndPointDefaults in the Kestrel config on the destination to Http1

Issue created from discussion #710

I’m not able to reproduce this. The client reports an aborted request, it does not receive the 502 response. A 502 is what we’d return if the proxy request failed before the response started, but a client browser refresh aborts the client request so the 502 response is never received.

Let’s get some baseline data.
What version of YARP are you using?
What version of .NET Core is this?
What kind of request is in progress, and what is it doing that’s taking long enough for you to refresh the browser before it’s done loading?
Can you simplify your config to only the relevant settings?
Please share the proxy logs, turned up to Debug for everything.

Using YARP 1.0.0-preview.8.21065.1

Framework version net5.0

I found out it’s not actually caused by a browser refresh (though doing this does cause a 502 aproximately half of the time though I did not press refresh at all this time round).

Behind YARP is a web application built using React with Apollo GraphQL client talking through YARP to consume an authenticated GraphQL Api.

Both the application and api are hosted in Kestrel. Apollo client is set to poll graphQL for changes every 2 seconds and this works fine when I remove YARP and go directly to the destination endpoint and also works via YARP if I configure Kestrel to explicitly use Http1.

I simplified the YARP config by removing header stuff from the Route transforms.

This is the Kestrel config I have on the GraphQL Api.

Here’s the full debug log from YARP up until the exception is caught.

Источник

What I Broke – Programming and Web Development

Let’s take a look at what I’ve broken today

Http gRPC with .NET Core and Docker – Error starting gRPC call. System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.IO.IOException: The response ended prematurely.

I’ve been mucking around with gRPC today while using .NET Core and Docker. I have two Microservices in the setup, one server and one client. Because these services will only be communicating internally I intended to use HTTP instead of HTTPS. Unfortunately, I hit the following error while attempting to set this up:

According Microsoft’s eshoponcontainers documentation there are a few extra steps for getting this to work:

Using gRPC without TLS
gRPC works with HTTP/2 only. Usually when a client connects to a server, the connection is done using HTTP1.1 and promoted to HTTP/2 only if both, server and client, support HTTP/2. This promotion is performed using a protocol negotiation, usually implemented using ALPN protocol which requires TLS.

In order to get it to work you need to add the following to your server :

.ConfigureKestrel(options =>
<
options.Listen(IPAddress.Any, 5001, listenOptions =>
<
listenOptions.Protocols = HttpProtocols.Http2;
>);
>);
>);

You then need to explicitly allow HTTP/2 without TLS when creating the client:

Источник

System net http httprequestexception an error occurred while sending the request

This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.

Answered by:

Question

I ported some of my Windows 8.1 code to Windows 10 Universal Windows.

Whenever I try to use HttpClient or HttpWebRequest with Network Credentials I get the following exception (this used to work perfectly in WindowsRT 8.1):

System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.NotSupportedException: This IRandomAccessStream does not support the GetInputStreamAt method because it requires cloning and this stream does not support cloning.
at System.IO.NetFxToWinRtStreamAdapter.ThrowCloningNotSuported(String methodName)
at System.IO.NetFxToWinRtStreamAdapter.GetInputStreamAt(UInt64 position)
— End of stack trace from previous location where exception was thrown —
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpHandlerToFilter. d__1.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpClientHandler. d__1.MoveNext()
— End of inner exception stack trace —
at System.Net.Http.HttpClientHandler. d__1.MoveNext()
— End of stack trace from previous location where exception was thrown —

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()

Can anyone reproduce this problem ? Are network credentials no longer supported in Windows 10 Universal Windows ? Is this a bug ?
This is a very serious problem for our company. Any help would be appreciated

Example code for a service with NTLM authentication (using HttpClient):

var networkCredential = new NetworkCredential (username, password, domain);

HttpClientHandler handler = new HttpClientHandler ()

Источник

Http Request Exception Class

Definition

Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.

A base class for exceptions thrown by the HttpClient and HttpMessageHandler classes.

Constructors

Initializes a new instance of the HttpRequestException class.

Initializes a new instance of the HttpRequestException class with a specific message that describes the current exception.

Initializes a new instance of the HttpRequestException class with a specific message that describes the current exception and an inner exception.

Initializes a new instance of the HttpRequestException class with a specific message that describes the current exception, an inner exception, and an HTTP status code.

Properties

Gets a collection of key/value pairs that provide additional user-defined information about the exception.

(Inherited from Exception) HelpLink

Gets or sets a link to the help file associated with this exception.

(Inherited from Exception) HResult

Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception.

(Inherited from Exception) InnerException

Gets the Exception instance that caused the current exception.

(Inherited from Exception) Message

Gets a message that describes the current exception.

(Inherited from Exception) Source

Gets or sets the name of the application or the object that causes the error.

(Inherited from Exception) StackTrace

Gets a string representation of the immediate frames on the call stack.

(Inherited from Exception) StatusCode

Gets the HTTP status code to be returned with the exception.

Gets the method that throws the current exception.

(Inherited from Exception)

Methods

Determines whether the specified object is equal to the current object.

(Inherited from Object) GetBaseException()

When overridden in a derived class, returns the Exception that is the root cause of one or more subsequent exceptions.

(Inherited from Exception) GetHashCode()

Serves as the default hash function.

(Inherited from Object) GetObjectData(SerializationInfo, StreamingContext)

When overridden in a derived class, sets the SerializationInfo with information about the exception.

(Inherited from Exception) GetType()

Gets the runtime type of the current instance.

(Inherited from Exception) MemberwiseClone()

Creates a shallow copy of the current Object.

(Inherited from Object) ToString()

Creates and returns a string representation of the current exception.

(Inherited from Exception)

Events

Occurs when an exception is serialized to create an exception state object that contains serialized data about the exception.

Источник

HttpClient handles redirects automatically. When you send a request, if the response contains a redirect status code (3xx) and redirect location, then it’ll send a new request to the redirect location.

You can turn off this auto-redirect behavior by passing in an HttpClientHandler with AllowAutoRedirect=false. This prevents it from following redirects automatically, and allows you to handle redirects manually if you want:

var handler = new HttpClientHandler() { AllowAutoRedirect = false }; var client = new HttpClient(handler); var response = await client.GetAsync("http://api.isevenapi.xyz/api/iseven/7/"); Console.WriteLine($"Status code = {(int)response.StatusCode}"); Console.WriteLine($"Redirect location = {response.Headers.Location}");

Code language: C# (cs)

Reminder: Be sure to reuse a single instance of HttpClient.

This outputs the following:

Status code = 301 Redirect location = https://api.isevenapi.xyz/api/iseven/7/

Code language: plaintext (plaintext)

This is an example of a typical HTTP to HTTPS redirect.

Default redirect behavior

HttpClient uses the RedirectHandler class for dealing with redirects. I’ll explain the default behavior below.

Redirect conditions

It will redirect based on the following conditions:

  • Response.StatusCode is 300, 301, 303, 303, 307, or 308.
  • Response.Headers.Location (URI) is populated. Note: It can handle absolute and relative URIs.
  • It will not do an insecure HTTPS to HTTP redirect.

It will do up to 50 redirects (configurable).

If you get a redirect response code (3xx) back at the end, this means the redirect conditions were not met, it exceeded the max redirect attempts, or there’s something wrong in the redirect data. If this is happening to you, you can troubleshoot it by turning off auto-redirects and examining the response(s).

Original request headers and content

The original request headers (except the auth header) and content are retained and sent in redirect requests. Query string parameters aren’t retained automatically.

If you’re handling redirects manually, you could combine the original query string parameters with the redirect location URI (perhaps using a UriBuilder).

Note: HttpClient internally reuses the same HttpRequestMessage object for redirects. If you try to do this yourself, you’ll get an exception “Cannot send the same request message multiple times.” The framework uses the internal MarkAsRedirected() method to be able to reuse the same request object repeatedly. If you really want to reuse the same request object yourself, you can use reflection to call the internal method. It’s probably simpler to just create a new request object.

Forced GETs

For certain combinations of status codes and HTTP methods, it will send the redirect as a GET instead of using the original HTTP method. For example, if you get a 302 response code when doing a POST request, it’ll do the redirect as a GET.

This is clearly a problem if the redirect location doesn’t allow a GET. In this scenario, you’d get the following misleading exception:

System.Net.Http.HttpRequestException: Response status code does not indicate success: 405 (Method Not Allowed).

It’s misleading because you sent a POST request, which was allowed. It sent a redirect request as a GET, which was disallowed. It’d only be obvious if you knew a redirect happened. It would be much more clear if the error message said something about it failing during a redirect attempt.

I’m not sure about the reasoning behind this Forced GET behavior. This is a pretty good example of why it might be better to disable auto-redirects. That way you avoid unintended behavior like this.

Check if a request was automatically redirected

One simple way to check if your request got automatically redirected is by comparing the original request URI with the response’s request URI. If they’re different, it got redirected.

var client = new HttpClient(); var requestUri = new Uri("http://api.isevenapi.xyz/api/iseven/7/"); var response = await client.GetAsync(requestUri); if (requestUri != response.RequestMessage.RequestUri) { Console.WriteLine($"Request was redirected to {response.RequestMessage.RequestUri}"); }

Code language: C# (cs)

Note: This is a heuristic.

This outputs the following:

Request was redirected to https://api.isevenapi.xyz/api/iseven/7/

Code language: plaintext (plaintext)

Limit the number of redirects

By default, HttpClient will do up to 50 redirects. You can control this with the HttpClientHandler.MaxAutomaticRedirections setting.

Here’s an example:

var handler = new HttpClientHandler() { MaxAutomaticRedirections = 1 }; var client = new HttpClient(handler); var response = await client.GetAsync("https://localhost:12345/movies/find"); response.EnsureSuccessStatusCode();

Code language: C# (cs)

When this exceeds the max redirect attempts, it’ll return the response from the last redirect request it attempted. Since this response will have a 3xx status code, EnsureSuccessStatusCode() will throw an exception.

HTTP to HTTPS redirects fails locally

I have an ASP.NET Core web API running locally. It’s configured to do HTTP to HTTPS redirects. To test redirect behavior, I sent the following request:

var client = new HttpClient(); var response = await client.GetAsync("http://localhost:12345/movies/find");

Code language: C# (cs)

It fails with the following exception:

System.Net.Http.HttpRequestException: An error occurred while sending the request.
—> System.IO.IOException: The response ended prematurely.

This error doesn’t have to do with HttpClient’s auto-redirect behavior. The error is happening before that. I also tried using Postman and got the same error. So this problem isn’t specific to HttpClient. I also tried running the web API in a local Windows Sandbox and had the same issue.

This is mostly just a heads up. I didn’t dig deeper into this. If you’re just wanting to test HTTP to HTTPS redirects, be sure the programs (client and web API) are on different machines. And if you have two programs on the same machine that need to talk, use HTTPS (to make HTTP to HTTPS redirects a non-issue).

A last week I wrote about fixing some problems between Git and Team Foundation Server 2018 when TFS is configured to use a self-signed SSL certificate for HTTPS.  Well, after I got that part working, I found a new problem while trying to configure a TFS build agent that would talk to my self-signed SSL certificate TFS machine.

When you are installing the TFS build agent on Windows, there are two steps: 1) download and extract the build agent zip and 2) run config.cmd to configure the agent.  (Want a walk-through for installing the TFS build agent?  Check out my TFS install guide.)  With the self-signed SSL cert TFS, I kept getting an error on the config.cmd portion of the agent install that simply said “an error occurred while sending the request“.

C:agent>config.cmd

>> Connect:

Enter server URL > https://demo18-tfs
Enter authentication type (press enter for Integrated) >
Connecting to server ...
An error occurred while sending the request.
Failed to connect. Try again or ctrl-c to quit
Enter server URL >

The solution was simple and all that needed to happen was to add the self-signed certificate to the trusted root certificate store.  After that the installation runs as expected.  Basically, the TFS agent configuration script was having the same problem with that self-signed SSL certificate as Git was.

The instructions for how to get the certificates and install them, check out my blog post on fixing Git and self-signed SSL certificates.  The script that fixes this problem is 03-import-iis-self-signed-cert-from-file.ps1.  After you’ve run 03-import-iis-self-signed-cert-from-file.ps1, you can re-run config.cmd to configure the TFS build agent and it should work.

HINT: Definitely run the build agent service as a user rather than Network Service because you’re going to need to fix a few things that will require you to log in as the build user account.

The Build Agent Service Won’t Run

Ok.  So you’ve got the agent service configured.  You start the agent service and if you look at the list of Windows Services (services.msc), the service is running.  But if you go to the Agent Pool in TFS, that agent isn’t running.  That’s not good.

If you look at the logs (c:agent_diagAgent_*.log), you see an error that says

[2017-12-19 20:55:26Z ERR VisualStudioServices] GET request to https://demo18-tfs/_apis/connectionData?connectOptions=1&lastChangeId=-1&lastChangeId64=-1 failed. System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.Net.Http.WinHttpException: A security error occurred
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.WinHttpHandler.<StartRequest>d__105.MoveNext()
— End of inner exception stack trace —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.Common.VssHttpMessageHandler.<SendAsync>d__17.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.Common.VssHttpRetryMessageHandler.<SendAsync>d__4.MoveNext()

Guess what?  Same problem again.  The self-signed certificate isn’t trusted.

Log in to your build machine as your build agent user account and then run 03-import-iis-self-signed-cert-from-file.ps1. This will add the TFS self-signed root cert to the trusted root certificates for the build user’s account.

Restart the build agent service.  If you go to the agent pools, the build agent should be running.

Another Piece of Advice

Git is probably broken right now for the build agent user account.  If you want Git to work with your new build server, you’re going to need to configure your build agent to run as an actual user account (not Network Service) because you’re going to need to fix the Git certificate problems.  After you’ve installed the build agent, you’ll almost definitely need to log in as the build user and then run 03-import-iis-self-signed-cert-from-file.ps1 and 04-update-gitconfig-and-add-cert-to-ca-bundle.ps1 in order to make Git happy.  In order to make 04-update-gitconfig-and-add-cert-to-ca-bundle.ps1 work, you’ll probably need to change the cert path to be “C:agentexternalsgitmingw64sslcertsca-bundle.crt”.

I hope this helps.

-Ben

— Build agent configuration got you down?  Want some help converting your XAML builds to the latest build format that works with VSTS and TFS2018?  Looking for some help with your DevOps process?  We can help.  Drop us a line at info@benday.com. 

Hi everyone,

I’ve been mucking around with gRPC today while using .NET Core and Docker. I have two Microservices in the setup, one server and one client. Because these services will only be communicating internally I intended to use HTTP instead of HTTPS. Unfortunately, I hit the following error while attempting to set this up:

Error starting gRPC call. System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.IO.IOException: The response ended prematurely.

According Microsoft’s eshoponcontainers documentation there are a few extra steps for getting this to work:

Using gRPC without TLS
gRPC works with HTTP/2 only. Usually when a client connects to a server, the connection is done using HTTP1.1 and promoted to HTTP/2 only if both, server and client, support HTTP/2. This promotion is performed using a protocol negotiation, usually implemented using ALPN protocol which requires TLS.

In order to get it to work you need to add the following to your server :

.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup()

.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
});

You then need to explicitly allow HTTP/2 without TLS when creating the client:

AppContext.SetSwitch(“System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport”, true);
AppContext.SetSwitch(“System.Net.Http.SocketsHttpHandler.Http2Support”, true);

// The port number(5001) must match the port of the gRPC server.
var channel = GrpcChannel.ForAddress(endpoint, new GrpcChannelOptions { LoggerFactory = loggerFactory });
var client = new CatalogService.Catalog.CatalogClient(channel);

Note that the AppContext.SetSwitch statements need to appear before the client is created to work. There’s also a bit of an overview on the following page: https://github.com/dotnet-architecture/eShopOnContainers/wiki/gRPC

The following stackoverflow post also helped with the ordering issue: https://stackoverflow.com/a/58053460/522859

Понравилась статья? Поделить с друзьями:
  • System information was not obtained because of msinfo32 execution error перевод
  • System indexoutofrangeexception как исправить
  • System halted pcie training error
  • System halted because a fatal error related to the memory was detected
  • System freinage defaillant ситроен с4 ошибка