Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] Adding HttpWebRequest to HttpClient Migration Guide #42242

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

liveans
Copy link
Member

@liveans liveans commented Aug 19, 2024

Summary

This is still ongoing effort, created this PR to get early feedback from folks.

Fixes dotnet/runtime#92690

/cc @dotnet/ncl


Internal previews

📄 File 🔗 Preview link
docs/fundamentals/networking/http/httpclient-migrate-from-httpwebrequest.md docs/fundamentals/networking/http/httpclient-migrate-from-httpwebrequest

Copy link
Member

@rzikm rzikm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good so far, do you plan to add more complex examples showcasing how to migrate use of certificates or ConnectCallback?

@liveans
Copy link
Member Author

liveans commented Aug 20, 2024

looks good so far, do you plan to add more complex examples showcasing how to migrate use of certificates or ConnectCallback?

Yes, this is ongoing work and this is on my todo list, and I'll actually add specific links to those sections in Notes section in the table.

@BillWagner BillWagner modified the milestones: August 2024, September 2024 Sep 3, 2024
Copy link
Member

@ManickaP ManickaP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the examples for specific scenarios, it's very practical. I also like the quick reference tables with the mapping.
Overall, I like the direction here, keep going!

I left some comments, mostly about sample code. I think we should be very careful with the code as people will copy-paste this as-is.

string host = context.DnsEndPoint.Host;

DnsCache? cacheItem;
if (!dnsCache.TryGetValue(host, out cacheItem) || DateTime.Now > cacheItem.CacheExpireTime)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use DateTime.Now, it's affected by daylight saving changes!

You can use Environment.TickCount64 instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shameless plug since this is quite a bit of code for someone to copy-paste: https://github.com/MihaZupan/DnsRoundRobin

Comment on lines 312 to 314
dnsCache.TryRemove(host, out _);
cacheItem = new DnsCache(await Dns.GetHostAddressesAsync(host, cancellationToken), DateTime.Now.Add(dnsRefreshTimeout), 0);
dnsCache.TryAdd(host, cacheItem);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConnectCallback doesn't guarantee thread safety. This will work, but it might unnecessarily issue multiple DNS requests for the same host, while also unintentionally removing freshly inserted results.

Comment on lines +325 to +327
int index = cacheItem.Index;
connectAddress = cacheItem.Addresses[index];
cacheItem.IncreaseIndex();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once again, not thread-safe.

Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this, it'll be nice to have a common place we can link people to


# HttpWebRequest to HttpClient Migration Guide

This document aims to guide developers through the process of migrating from <xref:System.Net.HttpWebRequest>, <xref:System.Net.ServicePoint>, and <xref:System.Net.ServicePointManager> to <xref:System.Net.Http.HttpClient>. The migration is necessary due to the obsolescence of the older APIs and the numerous benefits offered by <xref:System.Net.Http.HttpClient>, including improved performance, better resource management, and a more modern and flexible API design. By following the steps outlined in this document, developers will be able to transition their codebases smoothly and take full advantage of the features provided by <xref:System.Net.Http.HttpClient>.
Copy link
Member

@MihaZupan MihaZupan Sep 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While mentioning performance, should we mention that it's not just a "nice to have" bump in perf by migrating?
It's really that their existing WebRequest logic's perf is likely going to completely tank once they move to Core since WebRequest is just a minimal compat layer (e.g. no connection reuse in tons of cases).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was actually thinking to add a note or warning for this, to make sure that people who reads this doc will be aware of that WebRequest is compat layer on top of HttpClient.

| `TransferEncoding` | <xref:System.Net.Http.Headers.HttpRequestHeaders.TransferEncoding> | See: [Example: Set Request Headers](#example-set-request-headers). |
| `UnsafeAuthenticatedConnectionSharing` | No equivalent API | No workaround |
| `UseDefaultCredentials` | No direct equivalent API | See: [Example: Setting SocketsHttpHandler Properties](#example-setting-socketshttphandler-properties). |
| `UserAgent` | <xref:System.Net.Http.Headers.HttpRequestHeaders.UserAgent> | See: [Example: Set Request Headers](#example-set-request-headers). |
Copy link
Member

@MihaZupan MihaZupan Sep 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: A bunch of these are for headers that have 1:1 mappings.
It might be easier to follow if those have a separate "For setting headers like MediaType, Referer, ... see [Example])".
On the other hand your list is in alphabetical order so maybe that's better 🤷‍♂️

string host = context.DnsEndPoint.Host;

DnsCache? cacheItem;
if (!dnsCache.TryGetValue(host, out cacheItem) || DateTime.Now > cacheItem.CacheExpireTime)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shameless plug since this is quite a bit of code for someone to copy-paste: https://github.com/MihaZupan/DnsRoundRobin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Document HttpClient migration from HttpWebRequest/ServicePoint(Manager)
6 participants