@@ -52,10 +52,10 @@ pub enum RetrieveError {
5252impl IntoResponse for RetrieveError {
5353 fn into_response ( self ) -> Response {
5454 match self {
55- RetrieveError :: Backend { source } => {
55+ Self :: Backend { source } => {
5656 ( StatusCode :: INTERNAL_SERVER_ERROR , source. to_string ( ) ) . into_response ( )
5757 }
58- RetrieveError :: Unimplemented => Response :: builder ( )
58+ Self :: Unimplemented => Response :: builder ( )
5959 . status ( StatusCode :: NOT_IMPLEMENTED )
6060 . body ( Body :: from ( "This transaction is not implemented." ) )
6161 . unwrap ( ) ,
@@ -64,6 +64,7 @@ impl IntoResponse for RetrieveError {
6464}
6565pub struct RetrieveInstanceRequest {
6666 pub query : ResourceQuery ,
67+ pub transfer_syntax : Option < String > ,
6768}
6869
6970pub struct ThumbnailRequest {
@@ -157,6 +158,33 @@ where
157158 }
158159}
159160
161+ /// Extracts the transfer-syntax parameter from an Accept header value.
162+ ///
163+ /// According to <https://dicom.nema.org/medical/dicom/current/output/chtml/part18/sect_8.7.3.5.2.html>
164+ /// the syntax is: transfer-syntax-mtp = OWS ";" OWS %s"transfer-syntax=" ts-value
165+ ///
166+ /// Examples:
167+ /// - "application/dicom; transfer-syntax=1.2.840.10008.1.2.4.50"
168+ /// - "multipart/related; type=\"application/dicom\"; transfer-syntax=1.2.840.10008.1.2.4.50"
169+ fn extract_transfer_syntax_from_accept ( accept_header : & str ) -> Option < String > {
170+ // Split by semicolons to get individual parameters
171+ for part in accept_header. split ( ';' ) {
172+ let trimmed = part. trim ( ) ;
173+ // Look for the transfer-syntax parameter
174+ if let Some ( value) = trimmed. strip_prefix ( "transfer-syntax=" ) {
175+ let value = value. trim ( ) ;
176+ // The value might be quoted or unquoted
177+ let transfer_syntax = if value. starts_with ( '"' ) && value. ends_with ( '"' ) {
178+ value. trim_matches ( '"' )
179+ } else {
180+ value
181+ } ;
182+ return Some ( transfer_syntax. to_string ( ) ) ;
183+ }
184+ }
185+ None
186+ }
187+
160188impl < S > FromRequestParts < S > for RetrieveInstanceRequest
161189where
162190 AppState : FromRef < S > ,
@@ -169,7 +197,21 @@ where
169197 . await
170198 . map_err ( PathRejection :: into_response) ?;
171199
172- Ok ( Self { query } )
200+ let accept = parts
201+ . headers
202+ . get ( ACCEPT )
203+ . map ( |h| String :: from ( h. to_str ( ) . unwrap_or_default ( ) ) ) ;
204+
205+ // Extract the requested transfer-syntax from the Accept header if present
206+ // https://dicom.nema.org/medical/dicom/current/output/chtml/part18/sect_8.7.3.5.2.html
207+ let transfer_syntax = accept
208+ . as_ref ( )
209+ . and_then ( |accept_str| extract_transfer_syntax_from_accept ( accept_str) ) ;
210+
211+ Ok ( Self {
212+ query,
213+ transfer_syntax,
214+ } )
173215 }
174216}
175217
@@ -456,6 +498,59 @@ mod tests {
456498 ) ;
457499 }
458500
501+ #[ test]
502+ fn test_extract_transfer_syntax_from_accept ( ) {
503+ // Test simple case
504+ assert_eq ! (
505+ extract_transfer_syntax_from_accept(
506+ "application/dicom; transfer-syntax=1.2.840.10008.1.2.4.50"
507+ ) ,
508+ Some ( "1.2.840.10008.1.2.4.50" . to_string( ) )
509+ ) ;
510+
511+ // Test with extra whitespace
512+ assert_eq ! (
513+ extract_transfer_syntax_from_accept(
514+ "application/dicom; transfer-syntax=1.2.840.10008.1.2.4.50"
515+ ) ,
516+ Some ( "1.2.840.10008.1.2.4.50" . to_string( ) )
517+ ) ;
518+
519+ // Test wildcard
520+ assert_eq ! (
521+ extract_transfer_syntax_from_accept( "application/dicom; transfer-syntax=*" ) ,
522+ Some ( "*" . to_string( ) )
523+ ) ;
524+
525+ // Test multipart/related with type parameter
526+ assert_eq ! (
527+ extract_transfer_syntax_from_accept( "multipart/related; type=\" application/dicom\" ; transfer-syntax=1.2.840.10008.1.2.4.50" ) ,
528+ Some ( "1.2.840.10008.1.2.4.50" . to_string( ) )
529+ ) ;
530+
531+ // Test with quoted value (though not typical for transfer-syntax)
532+ assert_eq ! (
533+ extract_transfer_syntax_from_accept(
534+ "application/dicom; transfer-syntax=\" 1.2.840.10008.1.2.4.50\" "
535+ ) ,
536+ Some ( "1.2.840.10008.1.2.4.50" . to_string( ) )
537+ ) ;
538+
539+ // Test without transfer-syntax parameter
540+ assert_eq ! (
541+ extract_transfer_syntax_from_accept( "application/dicom" ) ,
542+ None
543+ ) ;
544+
545+ // Test with other parameters but no transfer-syntax
546+ assert_eq ! (
547+ extract_transfer_syntax_from_accept(
548+ "multipart/related; type=\" application/dicom\" ; boundary=example"
549+ ) ,
550+ None
551+ ) ;
552+ }
553+
459554 #[ test]
460555 fn parse_rendered_query_params ( ) {
461556 let uri =
0 commit comments