Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  proxy.rs

  Sprache: Rust
 

use crate::error::Error;
use crate::ParsedRequest;
use base64::engine::general_purpose::STANDARD;
use base64::engine::Engine;

/// Kind of proxy connection (Basic, Digest, etc)
#[derive(Clone, PartialEq, Eq, Debug)]
pub(crateenum ProxyKind {
    Basic,
}

/// Proxy configuration. Only HTTP CONNECT proxies are supported (no SOCKS or
/// HTTPS).
///
/// When credentials are provided, the Basic authentication type is used for
/// Proxy-Authorization.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Proxy {
    pub(crate) server: String,
    pub(crate) port: u32,
    pub(crate) user: Option<String>,
    pub(crate) password: Option<String>,
    pub(crate) kind: ProxyKind,
}

impl Proxy {
    fn parse_creds(creds: &str) -> (Option<String>, Option<String>) {
        if let Some((user, pass)) = split_once(creds, ":") {
            (Some(user.to_string()), Some(pass.to_string()))
        } else {
            (Some(creds.to_string()), None)
        }
    }

    fn parse_address(host: &str) -> Result<(String, Option<u32>), Error> {
        if let Some((host, port)) = split_once(host, ":") {
            let port = port.parse::<u32>().map_err(|_| Error::BadProxy)?;
            Ok((host.to_string(), Some(port)))
        } else {
            Ok((host.to_string(), None))
        }
    }

    /// Creates a new Proxy configuration.
    ///
    /// Supported proxy format is:
    ///
    /// ```plaintext
    /// [http://][user[:password]@]host[:port]
    /// ```
    ///
    /// The default port is 8080, to be changed to 1080 in minreq 3.0.
    ///
    /// # Example
    ///
    /// ```
    /// let proxy = minreq::Proxy::new("user:password@localhost:1080").unwrap();
    /// let request = minreq::post("http://example.com").with_proxy(proxy);
    /// ```
    ///
    pub fn new<S: AsRef<str>>(proxy: S) -> Result<Self, Error> {
        let proxy = proxy.as_ref();
        let authority = if let Some((proto, auth)) = split_once(proxy, "://") {
            if proto != "http" {
                return Err(Error::BadProxy);
            }
            auth
        } else {
            proxy
        };

        let ((user, password), host) = if let Some((userinfo, host)) = rsplit_once(authority, "@") {
            (Proxy::parse_creds(userinfo), host)
        } else {
            ((None, None), authority)
        };

        let (host, port) = Proxy::parse_address(host)?;

        Ok(Self {
            server: host,
            user,
            password,
            port: port.unwrap_or(8080),
            kind: ProxyKind::Basic,
        })
    }

    pub(cratefn connect(&self, proxied_req: &ParsedRequest) -> String {
        let authorization = if let Some(user) = &self.user {
            match self.kind {
                ProxyKind::Basic => {
                    let creds = if let Some(password) = &self.password {
                        STANDARD.encode(format!("{}:{}", user, password))
                    } else {
                        STANDARD.encode(user)
                    };
                    format!("Proxy-Authorization: Basic {}\r\n", creds)
                }
            }
        } else {
            String::new()
        };
        let host = &proxied_req.url.host;
        let port = proxied_req.url.port.port();
        format!(
            "CONNECT {}:{} HTTP/1.1\r\n{}\r\n",
            host, port, authorization
        )
    }

    pub(cratefn verify_response(response: &[u8]) -> Result<(), Error> {
        let response_string = String::from_utf8_lossy(response);
        let top_line = response_string.lines().next().ok_or(Error::ProxyConnect)?;
        let status_code = top_line.split_whitespace().nth(1).ok_or(Error::BadProxy)?;

        match status_code {
            "200" => Ok(()),
            "401" | "407" => Err(Error::InvalidProxyCreds),
            _ => Err(Error::BadProxy),
        }
    }
}

#[allow(clippy::manual_split_once)]
/// Replacement for str::split_once until MSRV is at least 1.52.0.
fn split_once<'a>(string: &'a str, pattern: &str) -> Option<(&'a str, &'a str)> {
    let mut parts = string.splitn(2, pattern);
    let first = parts.next()?;
    let second = parts.next()?;
    Some((first, second))
}

#[allow(clippy::manual_split_once)]
/// Replacement for str::rsplit_once until MSRV is at least 1.52.0.
fn rsplit_once<'a>(string: &'a str, pattern: &str) -> Option<(&'a str, &'a str)> {
    let mut parts = string.rsplitn(2, pattern);
    let second = parts.next()?;
    let first = parts.next()?;
    Some((first, second))
}

#[cfg(test)]
mod tests {
    use super::Proxy;

    #[test]
    fn parse_proxy() {
        let proxy = Proxy::new("user:p@ssw0rd@localhost:9999").unwrap();
        assert_eq!(proxy.user, Some(String::from("user")));
        assert_eq!(proxy.password, Some(String::from("p@ssw0rd")));
        assert_eq!(proxy.server, String::from("localhost"));
        assert_eq!(proxy.port, 9999);
    }

    #[test]
    fn parse_regular_proxy_with_protocol() {
        let proxy = Proxy::new("http://localhost:1080").unwrap();
        assert_eq!(proxy.user, None);
        assert_eq!(proxy.password, None);
        assert_eq!(proxy.server, String::from("localhost"));
        assert_eq!(proxy.port, 1080);
    }
}

Messung V0.5 in Prozent
C=75 H=92 G=83

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002