pub struct ClientAssociationOptions<'a> { /* private fields */ }Expand description
A DICOM association builder for a client node.
The final outcome is a ClientAssociation.
This is the standard way of requesting and establishing an association with another DICOM node, that one usually taking the role of a service class provider (SCP).
You can create either a blocking or non-blocking client by calling either
establish or establish_async respectively.
⚠️ Warning: It is highly recommended to set
read_timeoutandwrite_timeoutto a reasonable value for the async client since there is no default timeout onTcpStream
§Basic usage
§Synchronous API
let association = ClientAssociationOptions::new()
.with_presentation_context("1.2.840.10008.1.1", vec!["1.2.840.10008.1.2.1", "1.2.840.10008.1.2"])
.read_timeout(Duration::from_secs(60))
.write_timeout(Duration::from_secs(60))
.establish("129.168.0.5:104")?;§Asynchronous API
Include the async feature in your Cargo.toml
let association = ClientAssociationOptions::new()
.with_presentation_context("1.2.840.10008.1.1", vec!["1.2.840.10008.1.2.1", "1.2.840.10008.1.2"])
.read_timeout(Duration::from_secs(60))
.write_timeout(Duration::from_secs(60))
.establish_async("129.168.0.5:104")
.await?;§TLS Support
Enabling one of the Cargo features sync-tls or async-tls
unlocks the methods for configuring TLS.
Call tls_config and server_name
to establish the association over a secure transport connection.
§TLS in synchronous API
Include the sync-tls feature in your Cargo.toml.
§TLS in asynchronous API
Include the async-tls feature in your Cargo.toml.
§Example
use dicom_dictionary_std::uids;
use dicom_ul::{ClientAssociation, ClientAssociationOptions};
use rustls::{
ClientConfig, RootCertStore,
pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject},
};
// Loading certificates and keys for demonstration purposes
let ca_cert = CertificateDer::from_pem_slice(std::fs::read("ssl/ca.crt")?.as_ref())
.expect("Failed to load client cert");
// Server certificate -- signed by CA
let server_cert = CertificateDer::from_pem_slice(std::fs::read("ssl/server.crt")?.as_ref())
.expect("Failed to load server cert");
// Client cert and private key -- signed by CA
let client_cert = CertificateDer::from_pem_slice(std::fs::read("ssl/client.crt")?.as_ref())
.expect("Failed to load client cert");
let client_private_key = PrivateKeyDer::from_pem_slice(std::fs::read("ssl/client.key")?.as_ref())
.expect("Failed to load client private key");
// Create a root cert store for the client which includes the server certificate
let mut certs = RootCertStore::empty();
certs.add_parsable_certificates(vec![ca_cert.clone()]);
let config = ClientConfig::builder()
.with_root_certificates(certs)
.with_client_auth_cert(vec![client_cert, ca_cert], client_private_key)
.expect("Failed to create client TLS config");
let association: ClientAssociation<_> = ClientAssociationOptions::new()
.with_presentation_context(
uids::VERIFICATION,
vec![uids::EXPLICIT_VR_LITTLE_ENDIAN, uids::IMPLICIT_VR_LITTLE_ENDIAN]
)
.tls_config(config)
.read_timeout(Duration::from_secs(60))
.write_timeout(Duration::from_secs(60))
.establish_with_tls("REMOTE_DCM@129.168.0.5:104")?;For an association with the async API,
call establish_tls_async or establish_with_async_tls
instead of establish_tls or establish_with_tls.
§Presentation contexts
At least one presentation context must be specified,
using the method with_presentation_context
and supplying both an abstract syntax and list of transfer syntaxes.
A helper method with_abstract_syntax will
include by default the transfer syntaxes
Implicit VR Little Endian and Explicit VR Little Endian
in the resulting presentation context.
let association = ClientAssociationOptions::new()
.with_abstract_syntax("1.2.840.10008.1.1")
.establish("129.168.0.5:104")?;Implementations§
Source§impl<'a> ClientAssociationOptions<'a>
impl<'a> ClientAssociationOptions<'a>
Sourcepub fn calling_ae_title<T>(self, calling_ae_title: T) -> Self
pub fn calling_ae_title<T>(self, calling_ae_title: T) -> Self
Define the calling application entity title for the association, which refers to this DICOM node.
The default is THIS-SCU.
Sourcepub fn called_ae_title<T>(self, called_ae_title: T) -> Self
pub fn called_ae_title<T>(self, called_ae_title: T) -> Self
Define the called application entity title for the association, which refers to the target DICOM node.
The default is ANY-SCP.
Passing an empty string resets the AE title to the default
(or to the one passed via establish_with).
Sourcepub fn with_presentation_context<T>(
self,
abstract_syntax_uid: T,
transfer_syntax_uids: Vec<T>,
) -> Self
pub fn with_presentation_context<T>( self, abstract_syntax_uid: T, transfer_syntax_uids: Vec<T>, ) -> Self
Include this presentation context in the list of proposed presentation contexts.
Sourcepub fn with_abstract_syntax<T>(self, abstract_syntax_uid: T) -> Self
pub fn with_abstract_syntax<T>(self, abstract_syntax_uid: T) -> Self
Helper to add this abstract syntax with the default transfer syntaxes to the list of proposed presentation contexts.
Sourcepub fn max_pdu_length(self, value: u32) -> Self
pub fn max_pdu_length(self, value: u32) -> Self
Override the maximum PDU length that this application entity will admit.
Sourcepub fn strict(self, strict: bool) -> Self
pub fn strict(self, strict: bool) -> Self
Override strict mode: whether receiving PDUs must not surpass the negotiated maximum PDU length.
Sourcepub fn username_password<T, U>(self, username: T, password: U) -> Self
pub fn username_password<T, U>(self, username: T, password: U) -> Self
Sets the user identity username and password
Sourcepub fn kerberos_service_ticket<T>(self, kerberos_service_ticket: T) -> Self
pub fn kerberos_service_ticket<T>(self, kerberos_service_ticket: T) -> Self
Sets the user identity Kerberos service ticket
Sourcepub fn saml_assertion<T>(self, saml_assertion: T) -> Self
pub fn saml_assertion<T>(self, saml_assertion: T) -> Self
Sets the user identity SAML assertion
Sourcepub fn establish<A: ToSocketAddrs>(
self,
address: A,
) -> Result<ClientAssociation<TcpStream>, Error>
pub fn establish<A: ToSocketAddrs>( self, address: A, ) -> Result<ClientAssociation<TcpStream>, Error>
Initiate simple TCP connection to the given address and request a new DICOM association, negotiating the presentation contexts in the process.
Sourcepub fn establish_with(
self,
ae_address: &str,
) -> Result<ClientAssociation<TcpStream>, Error>
pub fn establish_with( self, ae_address: &str, ) -> Result<ClientAssociation<TcpStream>, Error>
Initiate the TCP connection to the given address and request a new DICOM association, negotiating the presentation contexts in the process.
This method allows you to specify the called AE title
alongside with the socket address.
See AeAddr for more details.
However, the AE title in this parameter
is overridden by any called_ae_title option
previously received.
§Example
let association = ClientAssociationOptions::new()
.with_abstract_syntax("1.2.840.10008.1.1")
// called AE title in address
.establish_with("MY-STORAGE@10.0.0.100:104")?;Sourcepub fn read_timeout(self, timeout: Duration) -> Self
pub fn read_timeout(self, timeout: Duration) -> Self
Set the read timeout for the underlying TCP socket
This is used to set both the read and write timeout.
Sourcepub fn write_timeout(self, timeout: Duration) -> Self
pub fn write_timeout(self, timeout: Duration) -> Self
Set the write timeout for the underlying TCP socket
Sourcepub fn connection_timeout(self, timeout: Duration) -> Self
pub fn connection_timeout(self, timeout: Duration) -> Self
Set the connection timeout for the underlying TCP socket
Trait Implementations§
Source§impl<'a> Clone for ClientAssociationOptions<'a>
impl<'a> Clone for ClientAssociationOptions<'a>
Source§fn clone(&self) -> ClientAssociationOptions<'a>
fn clone(&self) -> ClientAssociationOptions<'a>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<'a> Debug for ClientAssociationOptions<'a>
impl<'a> Debug for ClientAssociationOptions<'a>
Auto Trait Implementations§
impl<'a> Freeze for ClientAssociationOptions<'a>
impl<'a> RefUnwindSafe for ClientAssociationOptions<'a>
impl<'a> Send for ClientAssociationOptions<'a>
impl<'a> Sync for ClientAssociationOptions<'a>
impl<'a> Unpin for ClientAssociationOptions<'a>
impl<'a> UnsafeUnpin for ClientAssociationOptions<'a>
impl<'a> UnwindSafe for ClientAssociationOptions<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more