Код: Выделить всё
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
var builder = WebApplication.CreateBuilder(args);
// Configure Kestrel for h2c (HTTP/2 without TLS)
builder.WebHost.ConfigureKestrel(options =>
{
// Listen on port 5000 for h2c (HTTP/2 without TLS)
options.ListenAnyIP(5000, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2; // Only HTTP/2 Cleartext (h2c)
});
// Optionally, listen on port 5001 for HTTP/1 and HTTP/2 with TLS
options.ListenAnyIP(5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
listenOptions.UseHttps(); // HTTP/1.x and HTTP/2 with TLS
});
// Optionally, listen on port 5002 for HTTP/1 and HTTP/2 and HTTP/3 with TLS
options.ListenAnyIP(5002, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
listenOptions.UseHttps(); // HTTP/1.x and HTTP/2 with TLS
});
options.ListenAnyIP(5003, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
});
options.ListenAnyIP(5004, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
});
options.ListenAnyIP(5005, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http3;
listenOptions.UseHttps(); // HTTP/1.x and HTTP/2 with TLS
});
options.ListenAnyIP(5006, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
listenOptions.UseHttps(); // HTTP/1.x and HTTP/2 with TLS
});
options.ListenAnyIP(5007, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1;
listenOptions.UseHttps(); // HTTP/1.x and HTTP/2 with TLS
});
});
var app = builder.Build();
app.MapGet("/", (HttpContext context) =>
{
// Check if the request is using HTTP/2 (h2c)
if (context.Request.Protocol == "HTTP/2")
{
return Results.Text("Hello from HTTP/2");
}
// Check if the request is using HTTP/2 (h2c)
if (context.Request.Protocol == "HTTP/3")
{
return Results.Text("Hello from HTTP/3");
}
return Results.Text("Hello from HTTP/1.x or HTTPS");
});
app.Run();
Код: Выделить всё
options.ListenAnyIP(5004, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
});
Код: Выделить всё
Enter the server port (default is 5004): 5004
Enter Schema: (http, https): http
Select the HTTP version:
1 - HTTP/1.1
2 - HTTP/2
3 - HTTP/3 (if supported)
2
Select the HTTP version policy:
1 - RequestVersionExact (forces the request to use the specified HTTP version)
2 - RequestVersionOrHigher (tries the specified version or higher if supported)
3 - RequestVersionOrLower (tries the specified version or lower if necessary)
2
Do you want to include the Upgrade header for h2c? (yes/no): no
Request Headers:
An error occurred: The HTTP/2 server closed the connection. HTTP/2 error code 'HTTP_1_1_REQUIRED' (0xd). (HttpProtocolError)
Код: Выделить всё
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string userInput;
do
{
// Prompt the user to specify the port number
Console.Write("Enter the server port (default is 5004): ");
string portInput = Console.ReadLine()?.Trim();
int port = string.IsNullOrEmpty(portInput) ? 5004 : int.Parse(portInput);
Console.Write("Enter Schema: (http, https): ");
string? schema = Console.ReadLine()?.Trim();
// Prompt the user to specify the HTTP version
Console.WriteLine("Select the HTTP version:");
Console.WriteLine("1 - HTTP/1.1");
Console.WriteLine("2 - HTTP/2");
Console.WriteLine("3 - HTTP/3 (if supported)");
Version httpVersion = new Version(2, 0); // Default to HTTP/2
string versionInput = Console.ReadLine()?.Trim();
switch (versionInput)
{
case "1":
httpVersion = new Version(1, 1);
break;
case "2":
httpVersion = new Version(2, 0);
break;
case "3":
httpVersion = new Version(3, 0); // Only if HTTP/3 is supported
break;
default:
Console.WriteLine("Invalid selection, using default: HTTP/2.");
break;
}
// Prompt the user to specify the HttpVersionPolicy
Console.WriteLine("Select the HTTP version policy:");
Console.WriteLine("1 - RequestVersionExact (forces the request to use the specified HTTP version)");
Console.WriteLine("2 - RequestVersionOrHigher (tries the specified version or higher if supported)");
Console.WriteLine("3 - RequestVersionOrLower (tries the specified version or lower if necessary)");
HttpVersionPolicy versionPolicy = HttpVersionPolicy.RequestVersionOrLower; // Default policy
string policyInput = Console.ReadLine()?.Trim();
switch (policyInput)
{
case "1":
versionPolicy = HttpVersionPolicy.RequestVersionExact;
break;
case "2":
versionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
break;
case "3":
versionPolicy = HttpVersionPolicy.RequestVersionOrLower;
break;
default:
Console.WriteLine("Invalid selection, using default: RequestVersionOrLower.");
break;
}
// Ask the user if they want to include the Upgrade header for HTTP/2 cleartext (h2c)
bool includeUpgradeHeader = false;
if (httpVersion == new Version(2, 0) && schema == "http")
{
Console.Write("Do you want to include the Upgrade header for h2c? (yes/no): ");
string? upgradeHeaderInput = Console.ReadLine()?.Trim().ToLower();
includeUpgradeHeader = (upgradeHeaderInput == "yes");
}
// Create a SocketsHttpHandler and configure it for HTTP/2 Cleartext (h2c)
var handler = new SocketsHttpHandler
{
// Disable SSL/TLS (Cleartext connection)
SslOptions = { RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true }
};
// Set up HttpClient with the handler
using var client = new HttpClient(handler);
try
{
// Configure the request URL based on the specified port
string url = $"{schema ?? "http"}://localhost:{port}/";
// Configure the request to use the user-specified HTTP version
var request = new HttpRequestMessage(HttpMethod.Get, url)
{
Version = httpVersion, // Use the HTTP version specified by the user
VersionPolicy = versionPolicy // Use the policy specified by the user
};
// Add the Upgrade header for HTTP/2 cleartext (h2c) if the user chooses to
if (includeUpgradeHeader)
{
request.Headers.Connection.Add("Upgrade");
request.Headers.Upgrade.Add(new System.Net.Http.Headers.ProductHeaderValue("h2"));
// Base64url-encoded empty SETTINGS frame for HTTP/2. (An actual encoded frame would be used in real apps)
request.Headers.Add("HTTP2-Settings", "AAMAAABkAAQAAP__");
}
// Print request headers
Console.WriteLine("Request Headers:");
foreach (var header in request.Headers)
{
Console.WriteLine($"{header.Key}: {string.Join(", ", header.Value)}");
}
// Send the request
var response = await client.SendAsync(request);
// Read the response content
var content = await response.Content.ReadAsStringAsync();
// Output the response status and content
Console.WriteLine($"\nStatus Code: {response.StatusCode}");
Console.WriteLine($"\nResponse Headers: {response.Headers} {response.Content.Headers}");
Console.WriteLine($"Response: {content}");
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
Console.Write("Enter 'exit' to quit or press Enter to send a request: ");
userInput = Console.ReadLine()?.Trim();
} while (userInput?.ToLower() != "exit");
}
}
Если я использую https, все работает нормально!
Если я выберу RequestVersionOrLower, он автоматически по умолчанию будет использовать http 1.1, поэтому, если это так, то какая польза от установки ListenOptions.Protocols в HttpProtocols.Http1AndHttp2AndHttp3, если по умолчанию всегда будет http 1.1 вместо http?
Это ограничение?
Подробнее здесь: https://stackoverflow.com/questions/791 ... -over-http
Мобильная версия