upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-05-06 10:42:02 +0100
committerDanConwayDev <DanConwayDev@protonmail.com>2025-05-06 10:51:23 +0100
commitb2df89a1f57c136d710962439a86e90fa5249400 (patch)
treeb546f9ab7d723352676f174f6444b5f0b7dafcb3
parenta744f4aae9ffee9dd246090bef486b09433778d0 (diff)
fix(clone_url): fix custom ports
only use custom port on specified protocol (ie. http, https or ssh) ignore custom port on when trying other protocols specify `ssh://` prefix when using custom port as otherwise it can be ignored
-rw-r--r--src/lib/git/nostr_url.rs127
1 files changed, 86 insertions, 41 deletions
diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs
index fe58962..a9b08eb 100644
--- a/src/lib/git/nostr_url.rs
+++ b/src/lib/git/nostr_url.rs
@@ -428,10 +428,12 @@ impl CloneUrl {
428 428
429 url.set_path(&self.path); 429 url.set_path(&self.path);
430 430
431 // Set the port if present 431 // Set custom port
432 if let Some(port) = self.port { 432 if let Some(port) = self.port {
433 url.set_port(Some(port)) 433 if protocols_match(&self.protocol, protocol) {
434 .map_err(|_| anyhow!("failed to add port"))?; 434 url.set_port(Some(port))
435 .map_err(|_| anyhow!("failed to add port"))?;
436 }
435 } 437 }
436 438
437 // Set the query parameters if present 439 // Set the query parameters if present
@@ -451,7 +453,9 @@ impl CloneUrl {
451 "ssh://", 453 "ssh://",
452 format!("{}@", user.as_deref().unwrap_or("git")).as_str(), 454 format!("{}@", user.as_deref().unwrap_or("git")).as_str(),
453 ); 455 );
454 if !contains_port(&formatted_url) { 456 if url.port().is_some() {
457 formatted_url = format!("ssh://{}", formatted_url);
458 } else {
455 formatted_url = replace_first_occurrence(&formatted_url, '/', ':'); 459 formatted_url = replace_first_occurrence(&formatted_url, '/', ':');
456 } 460 }
457 } else if *protocol == ServerProtocol::Unspecified { 461 } else if *protocol == ServerProtocol::Unspecified {
@@ -547,6 +551,12 @@ fn strip_credentials(url: &str) -> String {
547 url.to_string() // Return the original URL if no credentials are found 551 url.to_string() // Return the original URL if no credentials are found
548} 552}
549 553
554fn protocols_match(a: &ServerProtocol, b: &ServerProtocol) -> bool {
555 let https = [ServerProtocol::Https, ServerProtocol::UnauthHttps];
556 let http = [ServerProtocol::Http, ServerProtocol::UnauthHttp];
557 https.contains(a) && https.contains(b) || http.contains(a) && http.contains(b) || a.eq(b)
558}
559
550#[cfg(test)] 560#[cfg(test)]
551mod tests { 561mod tests {
552 use super::*; 562 use super::*;
@@ -604,14 +614,63 @@ mod tests {
604 assert_eq!(result, "git@github.com:user/repo.git"); 614 assert_eq!(result, "git@github.com:user/repo.git");
605 } 615 }
606 616
607 #[test] 617 mod only_includes_custom_port_on_specified_protocol {
608 fn format_as_ssh_includes_port() { 618 use super::*;
609 let result = "https://github.com:1000/user/repo.git" 619
610 .parse::<CloneUrl>() 620 #[test]
611 .unwrap() 621 fn format_as_http_includes_custom_http_port() {
612 .format_as(&ServerProtocol::Ssh, &None) 622 let result = "https://github.com:1000/user/repo.git"
613 .unwrap(); 623 .parse::<CloneUrl>()
614 assert_eq!(result, "git@github.com:1000/user/repo.git"); 624 .unwrap()
625 .format_as(&ServerProtocol::Https, &None)
626 .unwrap();
627 assert_eq!(result, "https://github.com:1000/user/repo.git");
628 }
629
630 #[test]
631 fn format_as_ssh_excludes_custom_http_port() {
632 let result = "https://github.com:1000/user/repo.git"
633 .parse::<CloneUrl>()
634 .unwrap()
635 .format_as(&ServerProtocol::Ssh, &None)
636 .unwrap();
637 assert_eq!(result, "git@github.com:user/repo.git");
638 }
639
640 #[test]
641 fn format_as_ssh_includes_custom_ssh_port() {
642 // 29418 is the port used by gerrit and seen used by gitea instances
643 let result = "ssh://git@github.com:29418/user/repo.git"
644 .parse::<CloneUrl>()
645 .unwrap()
646 .format_as(&ServerProtocol::Ssh, &None)
647 .unwrap();
648 // need this format
649 assert_eq!(result, "ssh://git@github.com:29418/user/repo.git");
650 }
651
652 #[test]
653 fn format_as_http_excludes_custom_ssh_port() {
654 let result = "ssh://git@github.com:29418/user/repo.git"
655 .parse::<CloneUrl>()
656 .unwrap()
657 .format_as(&ServerProtocol::Https, &None)
658 .unwrap();
659 // need this format
660 assert_eq!(result, "https://github.com/user/repo.git");
661 }
662
663 #[test]
664 fn always_format_ssh_with_port_with_prefix() {
665 // 29418 is the port used by gerrit and seen used by gitea instances
666 let result = "git@github.com:29418/user/repo.git"
667 .parse::<CloneUrl>()
668 .unwrap()
669 .format_as(&ServerProtocol::Ssh, &None)
670 .unwrap();
671 // need this format
672 assert_eq!(result, "ssh://git@github.com:29418/user/repo.git");
673 }
615 } 674 }
616 675
617 #[test] 676 #[test]
@@ -641,13 +700,13 @@ mod tests {
641 use super::*; 700 use super::*;
642 701
643 #[test] 702 #[test]
644 fn port() { 703 fn port_ignored() {
645 let result = "github.com:1000/user/repo.git" 704 let result = "github.com:1000/user/repo.git"
646 .parse::<CloneUrl>() 705 .parse::<CloneUrl>()
647 .unwrap() 706 .unwrap()
648 .format_as(&ServerProtocol::Https, &None) 707 .format_as(&ServerProtocol::Https, &None)
649 .unwrap(); 708 .unwrap();
650 assert_eq!(result, "https://github.com:1000/user/repo.git"); 709 assert_eq!(result, "https://github.com/user/repo.git");
651 } 710 }
652 711
653 #[test] 712 #[test]
@@ -687,10 +746,7 @@ mod tests {
687 .unwrap() 746 .unwrap()
688 .format_as(&ServerProtocol::Https, &None) 747 .format_as(&ServerProtocol::Https, &None)
689 .unwrap(); 748 .unwrap();
690 assert_eq!( 749 assert_eq!(result, "https://github.com/repo.git?version=1.0#section1");
691 result,
692 "https://github.com:2222/repo.git?version=1.0#section1"
693 );
694 } 750 }
695 } 751 }
696 752
@@ -794,26 +850,6 @@ mod tests {
794 } 850 }
795 851
796 #[test] 852 #[test]
797 fn port_specified_with_path() {
798 let result = "user@github.com:2222/repo.git"
799 .parse::<CloneUrl>()
800 .unwrap()
801 .format_as(&ServerProtocol::Https, &None)
802 .unwrap();
803 assert_eq!(result, "https://github.com:2222/repo.git");
804 }
805
806 #[test]
807 fn port_specified_without_path() {
808 let result = "user@github.com:2222"
809 .parse::<CloneUrl>()
810 .unwrap()
811 .format_as(&ServerProtocol::Https, &None)
812 .unwrap();
813 assert_eq!(result, "https://github.com:2222");
814 }
815
816 #[test]
817 fn path_with_fragment() { 853 fn path_with_fragment() {
818 let result = "user1@github.com:/user/repo.git#readme" 854 let result = "user1@github.com:/user/repo.git#readme"
819 .parse::<CloneUrl>() 855 .parse::<CloneUrl>()
@@ -834,17 +870,26 @@ mod tests {
834 } 870 }
835 871
836 #[test] 872 #[test]
837 fn port_with_parameters_and_fragment() { 873 fn port_with_parameters_and_fragment_ssh() {
838 let result = "user@github.com:2222/repo.git?version=1.0#section1" 874 let result = "user@github.com:2222/repo.git?version=1.0#section1"
839 .parse::<CloneUrl>() 875 .parse::<CloneUrl>()
840 .unwrap() 876 .unwrap()
841 .format_as(&ServerProtocol::Https, &None) 877 .format_as(&ServerProtocol::Ssh, &None)
842 .unwrap(); 878 .unwrap();
843 assert_eq!( 879 assert_eq!(
844 result, 880 result,
845 "https://github.com:2222/repo.git?version=1.0#section1" 881 "ssh://git@github.com:2222/repo.git?version=1.0#section1"
846 ); 882 );
847 } 883 }
884 #[test]
885 fn port_with_parameters_and_fragment_https() {
886 let result = "user@github.com:2222/repo.git?version=1.0#section1"
887 .parse::<CloneUrl>()
888 .unwrap()
889 .format_as(&ServerProtocol::Https, &None)
890 .unwrap();
891 assert_eq!(result, "https://github.com/repo.git?version=1.0#section1");
892 }
848 } 893 }
849 894
850 #[test] 895 #[test]