| 667 | type Response = Response<Full<Bytes>>; |
| 668 | |
| 669 | fn call(&self, req: hyper::Request<hyper::body::Incoming>) -> Self::Future { |
| 670 | let uri = req.uri(); |
| 671 | let query = uri.query().unwrap_or(""); |
| 672 | let params: std::collections::HashMap<String, String> = |
| 673 | url::form_urlencoded::parse(query.as_bytes()).into_owned().collect(); |
| 674 | debug!("## mcp: uri: {}, query: {}, params: {:?}", uri, query, params); |
| 675 | |
| 676 | let self_clone = self.clone(); |
| 677 | Box::pin(async move { |
| 678 | let error = params.get("error"); |
| 679 | let resp = if let Some(err) = error { |
| 680 | mk_response(format!( |
| 681 | "OAuth failed. Check URL for precise reasons. Possible reasons: {}.\n\ |
| 682 | If this is scope related, you can try configuring the server scopes \n\ |
| 683 | to be an empty array by adding \"oauthScopes\": [] to your server config.\n\ |
| 684 | Example: {{\"type\": \"http\", \"uri\": \"https://example.com/mcp\", \"oauthScopes\": []}}\n", |
| 685 | err |
| 686 | )) |
| 687 | } else { |
| 688 | mk_response("You can close this page now".to_string()) |
| 689 | }; |
| 690 | |
| 691 | let code = params.get("code").cloned().unwrap_or_default(); |
| 692 | let state = params.get("state").cloned().unwrap_or_default(); |
| 693 | if let Some(sender) = self_clone |
| 694 | .one_shot_sender |
| 695 | .lock() |
| 696 | .map_err(|e| LoopBackError::Poison(e.to_string()))? |
| 697 | .take() |
| 698 | { |
| 699 | sender.send((code, state)).map_err(LoopBackError::Send)?; |
| 700 | } |
| 701 | |
| 702 | resp |
| 703 | }) |
| 704 | } |
| 705 | } |
| 706 | |
| 707 | let listener = tokio::net::TcpListener::bind(socket_addr).await?; |