diff --git a/ChangeLog b/ChangeLog index 7136c3b1a..6312e59d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2025-03-21 Earl Robsham + * Headers/Foundation/NSURLHandle.h: + * Sources/externs.m: + * Source/GSHTTPURLHandle.m: + * Source/NSURLProtocol.m: + Updates `Authorization` header generation to include the query parameters (if present). + Brings the implementation inline with MacOS. + Also adds the `GSDigestURIOmitsQuery` key for use with ` -[NSHTTPURLHandle writeProperty:forKey:]` / `+[NSURLProtocol setProperty:forKey:inRequest:]` to toggle off this updated behavior. + 2025-03-08 Richard Frith-Macdonald * Headers/GNUstepBase/GSObjCRuntime.h: diff --git a/Headers/Foundation/NSURLHandle.h b/Headers/Foundation/NSURLHandle.h index 3f37071c8..68bf6250b 100644 --- a/Headers/Foundation/NSURLHandle.h +++ b/Headers/Foundation/NSURLHandle.h @@ -114,6 +114,14 @@ GS_EXPORT NSString * const GSHTTPPropertyKeyFileKey; */ GS_EXPORT NSString * const GSHTTPPropertyPasswordKey; +/** + * Key for passing to [NSURLHandle]'s and [NSHTTPURLProtocol]'s + * propertyForKey.. methods. Specifying @YES will + * signal Digest Authentication logic to always omit the 'query' portion of the + * URI when generating the `Authorization` header. + */ +GS_EXPORT NSString * const GSDigestURIOmitsQuery; + #endif /** diff --git a/Source/GSHTTPURLHandle.m b/Source/GSHTTPURLHandle.m index 95ea45b50..7e85bb853 100644 --- a/Source/GSHTTPURLHandle.m +++ b/Source/GSHTTPURLHandle.m @@ -535,6 +535,8 @@ - (void) bgdApply: (NSString*)basic GSHTTPAuthentication *authentication; NSURLCredential *cred; NSString *method; + NSString *path; + NSNumber *omitQuery; /* Create credential from user and password stored in the URL. * Returns nil if we have no username or password. @@ -572,9 +574,19 @@ - (void) bgdApply: (NSString*)basic } } + omitQuery = [request objectForKey:GSDigestURIOmitsQuery]; + if ([[u query] length] == 0 || [omitQuery boolValue]) + { + path = [u pathWithEscapes]; + } + else + { + path = [NSString stringWithFormat:@"%@?%@", [u pathWithEscapes], [u query]]; + } + auth = [authentication authorizationForAuthentication: nil method: method - path: [u pathWithEscapes]]; + path: path]; /* If authentication is nil then auth will also be nil */ if (auth != nil) @@ -837,7 +849,9 @@ - (void) bgdRead: (NSNotification*) not NSString *ac; GSHTTPAuthentication *authentication; NSString *method; + NSString *path; NSString *auth; + NSNumber *omitQuery; ac = [ah value]; space = [GSHTTPAuthentication @@ -891,9 +905,19 @@ - (void) bgdRead: (NSNotification*) not } } + omitQuery = [request objectForKey:GSDigestURIOmitsQuery]; + if ([[url query] length] == 0 || [omitQuery boolValue]) + { + path = [url pathWithEscapes]; + } + else + { + path = [NSString stringWithFormat:@"%@?%@", [url pathWithEscapes], [url query]]; + } + auth = [authentication authorizationForAuthentication: ac method: method - path: [url pathWithEscapes]]; + path: path]; if (auth != nil) { [self writeProperty: auth forKey: @"Authorization"]; diff --git a/Source/NSURLProtocol.m b/Source/NSURLProtocol.m index 339cf7873..a7ed3a69a 100644 --- a/Source/NSURLProtocol.m +++ b/Source/NSURLProtocol.m @@ -1399,6 +1399,7 @@ - (void) _got: (NSStream*)stream if (_credential != nil) { GSHTTPAuthentication *authentication; + NSNumber *omitQuery; /* Get information about basic or * digest authentication. @@ -1410,10 +1411,14 @@ - (void) _got: (NSStream*)stream /* Generate authentication header value for the * authentication type in the challenge. */ + omitQuery = [this->request _propertyForKey:GSDigestURIOmitsQuery]; auth = [authentication authorizationForAuthentication: hdr method: [this->request HTTPMethod] - path: [url pathWithEscapes]]; + path: [[url query] length] == 0 || [omitQuery boolValue] ? + [url pathWithEscapes] : + [NSString stringWithFormat:@"%@?%@", [url pathWithEscapes], [url query]] + ]; } if (auth == nil) diff --git a/Source/externs.m b/Source/externs.m index 13b558760..abbc6351a 100644 --- a/Source/externs.m +++ b/Source/externs.m @@ -562,6 +562,7 @@ GS_DECLARE NSString* const GSHTTPPropertyCertificateFileKey = @"GSHTTPPropertyCertificateFileKey"; GS_DECLARE NSString* const GSHTTPPropertyKeyFileKey = @"GSHTTPPropertyKeyFileKey"; GS_DECLARE NSString* const GSHTTPPropertyPasswordKey = @"GSHTTPPropertyPasswordKey"; +GS_DECLARE NSString* const GSDigestURIOmitsQuery = @"GSDigestURIOmitsQuery"; /* NSURLProtectionSpace */ GS_DECLARE NSString* const NSURLProtectionSpaceFTPProxy = @"ftp";