firebase HTTP请求的主机头应该包含还是省略https://?

l0oc07j2  于 2023-05-01  发布在  其他
关注(0)|答案(1)|浏览(101)

我尝试使用C#中的套接字连接到Firebase真实的数据库以发送get请求,但收到400 Bad Request400 The plain HTTP request was sent to HTTPS port响应。我能够在端口443上建立到https://<mydatabase>.europe-west1.firebasedatabase.app的连接。然后我创建了下面的HTTP get请求字符串(复制了curl -v命令所示的内容),并通过套接字发送它,如下所示:

StringBuilder bob = new StringBuilder();
bob.Append("GET /.json HTTP/1.1\r\n");
bob.Append("Host: https://<mydatabase>.europe-west1.firebasedatabase.app\r\n");
bob.Append("Accept: */*\r\n\r\n");

Socket socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect("<mydatabase>.europe-west1.firebasedatabase.app", 443);
socket.Send(Encoding.UTF8.GetBytes(bob.ToString()));

然后我从socket读取,响应是这样的:

Server: nginx
Date: Sun, 19 Mar 2023 20:17:20 GMT
Content-Type: text/html
Content-Length: 150
Connection: close
Strict-Transport-Security: max-age=31556926; includeSubDomains; preload

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

我已经检查了curl和postman,它们与我的有效载荷的差异是这样的:

Host: https://<mydatabase>.europe-west1.firebasedatabase.app   // My Host header value
Host: <mydatabase>.europe-west1.firebasedatabase.app           // Host header value on curl and postman although I've provided the https:// on the url

当我在我的Host头值上省略https://时,响应会变成这样:

Server: nginx
Date: Sun, 19 Mar 2023 20:20:40 GMT
Content-Type: text/html
Content-Length: 248
Connection: close
Strict-Transport-Security: max-age=31556926; includeSubDomains; preload

<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx</center>
</body>
</html>

我能够从curl和postman获得我请求的URL https://<mydatabase>.europe-west1.firebasedatabase.app/.json的数据。所以我不明白我在这里用套接字做什么有什么不同。我会很感激任何帮助或指点,谢谢。

umuewwlo

umuewwlo1#

标题中的问题的答案是否定的。您应该只在主机名头中传递主机名:<mydatabase>.europe-west1.firebasedatabase.app
但这解决不了你的问题。您的代码向服务器发送一个纯文本http请求,但它需要TLS握手。连接到TLS端点时,您需要遵循TLS协议。
在连接远程套接字之后,您需要执行TLS握手来协商安全细节,例如使用哪种加密算法,以及建立用于tcp会话期间的临时对称加密密钥。Postman和curl在看到URL中的https时,都会透明地为您处理此问题。
你很可能不想学习TLS并自己编写低级代码。两个可能的选项是:
1.使用SslStream类 Package 套接字NetworkStream和调用AuthenticateAsClient()以执行握手。
1.使用HttpClient类,它将透明地为您处理TLS。

var client = new HttpClient();
var url = "https://<mydatabase>.europe-west1.firebasedatabase.app/.json";
var json = await client.GetStringAsync(url);

相关问题