diff --git a/ostp-client/src/transport/xhttp.rs b/ostp-client/src/transport/xhttp.rs index 9fff768..2fd7cce 100644 --- a/ostp-client/src/transport/xhttp.rs +++ b/ostp-client/src/transport/xhttp.rs @@ -90,8 +90,11 @@ pub async fn connect_xhttp( let req = format!( "GET /stream HTTP/1.1\r\n\ Host: {}\r\n\ + Upgrade: websocket\r\n\ + Connection: upgrade\r\n\ + Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\ + Sec-WebSocket-Version: 13\r\n\ Authorization: Bearer {}\r\n\ - Connection: keep-alive\r\n\ \r\n", http_host, auth_token ); @@ -124,8 +127,8 @@ pub async fn connect_xhttp( if buf[..header_len].windows(4).any(|w| w == b"\r\n\r\n") { break; } } let resp = String::from_utf8_lossy(&buf[..header_len]); - if !resp.starts_with("HTTP/1.1 200 OK") { - anyhow::bail!("xHTTP handshake failed: expected 200 OK, got: {}", resp.lines().next().unwrap_or("")); + if !resp.starts_with("HTTP/1.1 101 ") && !resp.starts_with("HTTP/1.1 200 ") { + anyhow::bail!("xHTTP handshake failed: expected 101 or 200, got: {}", resp.lines().next().unwrap_or("")); } if !resp.to_ascii_lowercase().contains("x-ostp-server:") { anyhow::bail!("xHTTP handshake failed: endpoint is not an OSTP server (missing X-Ostp-Server header)"); @@ -152,8 +155,8 @@ pub async fn connect_xhttp( if buf[..header_len].windows(4).any(|w| w == b"\r\n\r\n") { break; } } let resp = String::from_utf8_lossy(&buf[..header_len]); - if !resp.starts_with("HTTP/1.1 200 OK") { - anyhow::bail!("xHTTP handshake failed: expected 200 OK, got: {}", resp.lines().next().unwrap_or("")); + if !resp.starts_with("HTTP/1.1 101 ") && !resp.starts_with("HTTP/1.1 200 ") { + anyhow::bail!("xHTTP handshake failed: expected 101 or 200, got: {}", resp.lines().next().unwrap_or("")); } if !resp.to_ascii_lowercase().contains("x-ostp-server:") { anyhow::bail!("xHTTP handshake failed: endpoint is not an OSTP server (missing X-Ostp-Server header)"); diff --git a/ostp-server/src/transport/uot.rs b/ostp-server/src/transport/uot.rs index f4bf0b4..c744603 100644 --- a/ostp-server/src/transport/uot.rs +++ b/ostp-server/src/transport/uot.rs @@ -107,8 +107,8 @@ pub async fn handle_tcp_connection( anyhow::bail!("unauthorized (invalid HMAC)"); } - // Reply 200 OK - let response = "HTTP/1.1 200 OK\r\nX-Ostp-Server: 1\r\nConnection: keep-alive\r\n\r\n"; + // Reply 101 Switching Protocols + let response = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nX-Ostp-Server: 1\r\n\r\n"; stream.write_all(response.as_bytes()).await?; info!("UoT client authenticated from {}", peer_addr);