为什么 HttpClient 使用 HTTPS 比 HTTP 快得多?
Why is HttpClient so much faster with HTTPS over HTTP?
前几天我正在调查一个奇怪的错误,在该错误中规范化 URL 会导致我的应用程序大幅减速 300%:
if (!TryNormalize(uri, out uri))
throw new ArgumentException("URL is not a valid YouTube URL!");
string pageSource;
using (var http = new HttpClient())
pageSource = await http.GetStringAsync(uri);
当 TryNormalize
被注释掉时,GetStringAsync
大约需要 0.5 秒才能完成。然而,当它未被注释时,下载该字符串最多需要 2 秒。事实证明,TryNormalize
为它处理的所有 URL 添加了前缀 "http://"
,并添加额外的 S
解决了问题。
话虽如此,为什么会这样?据我了解,HTTPS 应该更慢,因为字符串在从服务器传输之前必须加密,而 HTTP 不提供这样的选项。即使我不是 HTTP 专家,300% 似乎也是一个相当大的减速。我在这里遗漏了什么吗?
编辑: TryNormalize
的源代码:
public static bool TryNormalize(string videoUri, out string normalized)
{
normalized = null;
var builder = new StringBuilder(videoUri);
videoUri = builder.Replace("youtu.be/", "youtube.com/watch?v=")
.Replace("youtube.com/embed/", "youtube.com/watch?v=")
.Replace("/v/", "/watch?v=")
.Replace("/watch#", "/watch?")
.ToString();
string value;
if (!Query.TryGetParamValue("v", videoUri, out value))
return false;
normalized = "http://youtube.com/watch?v=" + value; // replacing with HTTPS here results in 1.5s speedup
return true;
}
这是因为当您使用 youtube url 的变体时,有很多重定向。例如,导航到 http://youtu.be/O3UBOOZw-FE
会导致两次重定向。(请参阅 Location header)
1.
HTTP/1.1 302 Found
Date: Fri, 21 Aug 2015 16:52:40 GMT
Server: gwiseguy/2.0
Location: http://www.youtube.com/watch?v=O3UBOOZw-FE&feature=youtu.be
Content-Length: 0
Content-Type: text/html
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
2.
HTTP/1.1 301 Moved Permanently
Date: Fri, 21 Aug 2015 16:52:40 GMT
Server: gwiseguy/2.0
Content-Type: text/html; charset=utf-8
X-Content-Type-Options: nosniff
Expires: Tue, 27 Apr 1971 19:44:06 EST
Content-Length: 0
Cache-Control: no-cache
X-XSS-Protection: 1; mode=block; report=https://www.google.com/appserve/security-bugs/log/youtube
Location: https://www.youtube.com/watch?v=O3UBOOZw-FE&feature=youtu.be
X-Frame-Options: SAMEORIGIN
直到你最终得到 url https://www.youtube.com/watch?v=O3UBOOZw-FE&feature=youtu.be
由于这些重定向是由 HttpClient
自动处理的,您只能看到 3 个请求的最终结果。
前几天我正在调查一个奇怪的错误,在该错误中规范化 URL 会导致我的应用程序大幅减速 300%:
if (!TryNormalize(uri, out uri))
throw new ArgumentException("URL is not a valid YouTube URL!");
string pageSource;
using (var http = new HttpClient())
pageSource = await http.GetStringAsync(uri);
当 TryNormalize
被注释掉时,GetStringAsync
大约需要 0.5 秒才能完成。然而,当它未被注释时,下载该字符串最多需要 2 秒。事实证明,TryNormalize
为它处理的所有 URL 添加了前缀 "http://"
,并添加额外的 S
解决了问题。
话虽如此,为什么会这样?据我了解,HTTPS 应该更慢,因为字符串在从服务器传输之前必须加密,而 HTTP 不提供这样的选项。即使我不是 HTTP 专家,300% 似乎也是一个相当大的减速。我在这里遗漏了什么吗?
编辑: TryNormalize
的源代码:
public static bool TryNormalize(string videoUri, out string normalized)
{
normalized = null;
var builder = new StringBuilder(videoUri);
videoUri = builder.Replace("youtu.be/", "youtube.com/watch?v=")
.Replace("youtube.com/embed/", "youtube.com/watch?v=")
.Replace("/v/", "/watch?v=")
.Replace("/watch#", "/watch?")
.ToString();
string value;
if (!Query.TryGetParamValue("v", videoUri, out value))
return false;
normalized = "http://youtube.com/watch?v=" + value; // replacing with HTTPS here results in 1.5s speedup
return true;
}
这是因为当您使用 youtube url 的变体时,有很多重定向。例如,导航到 http://youtu.be/O3UBOOZw-FE
会导致两次重定向。(请参阅 Location header)
1.
HTTP/1.1 302 Found
Date: Fri, 21 Aug 2015 16:52:40 GMT
Server: gwiseguy/2.0
Location: http://www.youtube.com/watch?v=O3UBOOZw-FE&feature=youtu.be
Content-Length: 0
Content-Type: text/html
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
2.
HTTP/1.1 301 Moved Permanently
Date: Fri, 21 Aug 2015 16:52:40 GMT
Server: gwiseguy/2.0
Content-Type: text/html; charset=utf-8
X-Content-Type-Options: nosniff
Expires: Tue, 27 Apr 1971 19:44:06 EST
Content-Length: 0
Cache-Control: no-cache
X-XSS-Protection: 1; mode=block; report=https://www.google.com/appserve/security-bugs/log/youtube
Location: https://www.youtube.com/watch?v=O3UBOOZw-FE&feature=youtu.be
X-Frame-Options: SAMEORIGIN
直到你最终得到 url https://www.youtube.com/watch?v=O3UBOOZw-FE&feature=youtu.be
由于这些重定向是由 HttpClient
自动处理的,您只能看到 3 个请求的最终结果。