MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / run_ws

Function run_ws

src/environmentd/src/http/sql.rs:339–471  ·  view source on GitHub ↗
(state: WsState, user: Option<ExistingUser>, peer_addr: IpAddr, mut ws: WebSocket)

Source from the content-addressed store, hash-verified

337}
338
339async fn run_ws(state: WsState, user: Option<ExistingUser>, peer_addr: IpAddr, mut ws: WebSocket) {
340 let mut client = match init_ws(state, user, peer_addr, &mut ws).await {
341 Ok(client) => client,
342 Err(e) => {
343 // We omit most detail from the error message we send to the client, to
344 // avoid giving attackers unnecessary information during auth. AdapterErrors
345 // are safe to return because they're generated after authentication.
346 debug!("WS request failed init: {}", e);
347 let reason: Utf8Bytes = match e.downcast_ref::<AdapterError>() {
348 Some(error) => error.to_string().into(),
349 None => "unauthorized".to_string().into(),
350 };
351 let _ = ws
352 .send(Message::Close(Some(CloseFrame {
353 code: CloseCode::Protocol.into(),
354 reason,
355 })))
356 .await;
357 return;
358 }
359 };
360
361 // Successful auth, send startup messages.
362 let mut msgs = Vec::new();
363 let session = client.client.session();
364 for var in session.vars().notify_set() {
365 msgs.push(WebSocketResponse::ParameterStatus(ParameterStatus {
366 name: var.name().to_string(),
367 value: var.value(),
368 }));
369 }
370 msgs.push(WebSocketResponse::BackendKeyData(BackendKeyData {
371 conn_id: session.conn_id().unhandled(),
372 secret_key: session.secret_key(),
373 }));
374 msgs.push(WebSocketResponse::ReadyForQuery(
375 session.transaction_code().into(),
376 ));
377 for msg in msgs {
378 let _ = ws
379 .send(Message::Text(
380 serde_json::to_string(&msg).expect("must serialize").into(),
381 ))
382 .await;
383 }
384
385 // Send any notices that might have been generated on startup.
386 let notices = session.drain_notices();
387 if let Err(err) = forward_notices(&mut ws, notices).await {
388 debug!("failed to forward notices to WebSocket, {err:?}");
389 return;
390 }
391
392 loop {
393 // Handle timeouts first so we don't execute any statements when there's a pending timeout.
394 let msg = select! {
395 biased;
396

Callers 1

handle_sql_wsFunction · 0.85

Calls 15

init_wsFunction · 0.85
ReadyForQueryClass · 0.85
TextClass · 0.85
to_stringFunction · 0.85
forward_noticesFunction · 0.85
run_ws_requestFunction · 0.85
send_ws_responseFunction · 0.85
notify_setMethod · 0.80
unhandledMethod · 0.80
secret_keyMethod · 0.80
transaction_codeMethod · 0.80
expectMethod · 0.80

Tested by

no test coverage detected