1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::config;
use reqwest::{header::HeaderMap, Client};
use std::env;
use std::result;
use std::sync::{LockResult, PoisonError, RwLockReadGuard, RwLockWriteGuard};
use uname::uname;
use uuid::Uuid;

/// A method to set custom HTTP-client, e.g. to change request timeout or to set a proxy.
///
/// Error would be returned if [`RwLock`] had been poisoned.
///
/// [`RwLock`]: https://doc.rust-lang.org/std/sync/struct.RwLock.html
///
/// # Examples
///
/// ```
/// use plex_api::set_http_client;
/// use reqwest::{Client, Proxy};
/// use std::time::Duration;
///
/// set_http_client(Client::builder()
///                     .timeout(Duration::from_secs(1))
///                     .proxy(Proxy::http("http://example.com").expect("Proxy failed"))
///                     .build()
///                     .expect("Build failed")
/// ).expect("Mutex poisoned");
/// ```
pub fn set_http_client(
    c: Client,
) -> result::Result<(), PoisonError<RwLockWriteGuard<'static, Client>>> {
    let mut client = config::HTTP_CLIENT.write()?;
    *client = c;
    Ok(())
}

pub fn get_http_client() -> LockResult<RwLockReadGuard<'static, Client>> {
    config::HTTP_CLIENT.read()
}

pub fn base_headers() -> HeaderMap {
    let mut headers = HeaderMap::new();
    let i = uname().unwrap();

    let provides = *config::X_PLEX_PROVIDES.read().unwrap();
    headers.insert("X-Plex-Provides", provides.parse().unwrap());

    let mut product = *config::X_PLEX_PRODUCT.read().unwrap();
    if product == "" {
        product = config::PROJECT.unwrap_or("plex-api");
    }

    headers.insert("X-Plex-Product", product.parse().unwrap());

    let mut version = *config::X_PLEX_VERSION.read().unwrap();
    if version == "" {
        version = config::VERSION.unwrap_or("unknown");
    }

    headers.insert("X-Plex-Version", version.parse().unwrap());
    headers.insert(
        "X-Plex-Sync-Version",
        config::X_PLEX_SYNC_VERSION.read().unwrap().parse().unwrap(),
    );

    let mut platform = *config::X_PLEX_PLATFORM.read().unwrap();
    if platform == "" {
        platform = &i.sysname;
    }

    headers.insert("X-Plex-Platform", platform.parse().unwrap());

    let mut platform_version = *config::X_PLEX_PLATFORM_VERSION.read().unwrap();
    if platform_version == "" {
        platform_version = &i.release;
    }

    headers.insert("X-Plex-Platform-Version", platform_version.parse().unwrap());

    let mut client_identifier: String =
        String::from(*config::X_PLEX_CLIENT_IDENTIFIER.read().unwrap());
    if client_identifier == "" {
        let client_id = env::var("X_PLEX_CLIENT_IDENTIFIER");
        client_identifier = match client_id {
            Ok(id) => id,
            Err(_) => {
                warn!(target: "plex-api", "Generating random identifier for the machine! Set X_PLEX_CLIENT_IDENTIFIER to avoid this");
                let random_uuid = Uuid::new_v4();
                random_uuid.to_string()
            }
        };
    }

    headers.insert(
        "X-Plex-Client-Identifier",
        client_identifier.parse().unwrap(),
    );

    let mut device = *config::X_PLEX_DEVICE.read().unwrap();
    if device == "" {
        device = platform
    }

    headers.insert("X-Plex-Device", device.parse().unwrap());

    let mut device_name = *config::X_PLEX_DEVICE_NAME.read().unwrap();
    if device_name == "" {
        device_name = &i.nodename;
    }

    headers.insert("X-Plex-Device-Name", device_name.parse().unwrap());

    headers
}