diff --git a/src/internal/auth.rs b/src/internal/auth.rs index 4cb56db90..293d7245c 100644 --- a/src/internal/auth.rs +++ b/src/internal/auth.rs @@ -59,7 +59,16 @@ impl HostScope { /// Scope of a request URL (returns None for non-token-eligible schemes). pub fn from_request_url(url: &url::Url) -> Option { - Self::from_url(url).ok() + // Request URLs necessarily contain repository and protocol paths, while + // stored credentials are scoped only to the origin host and port. + // Normalize the request to the origin before applying the strict host + // parser; otherwise every Git Smart HTTP request silently misses the + // stored token and push/fetch falls through to a 401 prompt. + let mut origin = url.clone(); + origin.set_path("/"); + origin.set_query(None); + origin.set_fragment(None); + Self::from_url(&origin).ok() } fn from_url(url: &url::Url) -> Result { diff --git a/src/internal/protocol/https_client.rs b/src/internal/protocol/https_client.rs index 54f29c4b8..4b3287173 100644 --- a/src/internal/protocol/https_client.rs +++ b/src/internal/protocol/https_client.rs @@ -4,7 +4,7 @@ use std::{io::Error as IoError, ops::Deref, sync::Mutex, time::Duration}; use futures_util::{StreamExt, TryStreamExt}; use git_internal::errors::GitError; -use reqwest::{Body, RequestBuilder, Response, StatusCode, header::CONTENT_TYPE}; +use reqwest::{RequestBuilder, Response, StatusCode, header::CONTENT_TYPE}; use url::Url; use super::{ @@ -464,10 +464,7 @@ impl HttpsClient { Ok(result) } - pub async fn send_pack + Clone>( - &self, - data: T, - ) -> Result { + pub async fn send_pack(&self, data: bytes::Bytes) -> Result { // INVARIANT: "git-receive-pack" is a valid relative URL onto self.url. let receive_pack_url = self .url @@ -477,6 +474,12 @@ impl HttpsClient { self.client .post(receive_pack_url.clone()) .header(CONTENT_TYPE, "application/x-git-receive-pack-request") + .header( + reqwest::header::ACCEPT, + "application/x-git-receive-pack-result", + ) + .header(reqwest::header::USER_AGENT, "git/2.43.0 libra") + .header(reqwest::header::CONTENT_LENGTH, data.len()) .body(data.clone()) }) .await