Fix for bug introduced by adding OSX compatibility for the -path method of

NSURL.  This was causing loading of URLs where the path ends in a slash to
fail (load the wrong URL).


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@28548 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2009-08-26 16:48:15 +00:00
parent ae54787ec6
commit 5975ccf95f
7 changed files with 146 additions and 68 deletions

View file

@ -1,3 +1,18 @@
2009-08-26 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/NSURL.h:
* Headers/Additions/GNUstepBase/GSCategories.h:
* Source/NSURL.m:
* Source/Additions/GSCategories.m:
Add new -fulPath method to do what -path used to do, because for OSX
compatibility the -path method now returns a path without any
trailing slash, making it impossible to reconsitute a URL string
from its individual parts :-(
* Source/GSHTTPURLHandle.m:
* Source/NSURLProtocol.m:
Use the new -fullPath method to build the request line sent to the
remote web server.
2009-08-25 Richard Frith-Macdonald <rfm@gnu.org>
* Version: bump to 1.19.2

View file

@ -331,6 +331,10 @@ typedef enum _NSGNUstepStringEncoding
+ (id)newLockAt:(id *)location;
@end
@interface NSURL (GSCategories)
- (NSString*) fullPath;
@end
/* ------------------------------------------------------------------------
* Functions
*/

View file

@ -119,6 +119,12 @@ GS_EXPORT NSString* const NSURLFileScheme;
#endif /* GS_API_MACOSX */
@interface NSURL (GSCategories)
/** Returns the full path for this URL including any trailing slash.
*/
- (NSString*) fullPath;
@end
#if defined(__cplusplus)
}
#endif

View file

@ -1606,3 +1606,25 @@ executablePath(NSFileManager *mgr, NSString *path)
}
@end
@implementation NSURL (GSCategories)
- (NSString*) fullPath
{
NSRange r;
NSString *s;
s = [self absoluteString];
if ((r = [s rangeOfString: @";"]).length > 0)
{
s = [s substringFromIndex: r.location];
}
else if ((r = [s rangeOfString: @"?"]).length > 0)
{
s = [s substringFromIndex: r.location];
}
r = [s rangeOfString: @"//"];
s = [s substringFromIndex: NSMaxRange(r)];
r = [s rangeOfString: @"/"];
s = [s substringFromIndex: r.location];
return s;
}
@end

View file

@ -511,7 +511,7 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data)
auth = [authentication authorizationForAuthentication: nil
method: method
path: [u path]];
path: [u fullPath]];
/* If authentication is nil then auth will also be nil
*/
if (auth != nil)
@ -728,7 +728,7 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data)
auth = [authentication authorizationForAuthentication: ac
method: method
path: [url path]];
path: [url fullPath]];
if (auth != nil)
{
[self writeProperty: auth forKey: @"Authorization"];
@ -900,7 +900,7 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data)
if (debug)
NSLog(@"%@ %p %s", NSStringFromSelector(_cmd), self, keepalive?"K":"");
path = [[u path] stringByTrimmingSpaces];
path = [[u fullPath] stringByTrimmingSpaces];
if ([path length] == 0)
{
path = @"/";
@ -1487,7 +1487,7 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data)
method = @"GET";
}
}
path = [[u path] stringByTrimmingSpaces];
path = [[u fullPath] stringByTrimmingSpaces];
if ([path length] == 0)
{
path = @"/";

View file

@ -1242,6 +1242,92 @@ static unsigned urlAlign;
return fragment;
}
- (char*) _path: (char*)buf
{
char *ptr = buf;
char *tmp = buf;
if (myData->pathIsAbsolute == YES)
{
if (myData->hasNoPath == NO)
{
*tmp++ = '/';
}
strcpy(tmp, myData->path);
}
else if (_baseURL == nil)
{
strcpy(tmp, myData->path);
}
else if (*myData->path == 0)
{
if (baseData->hasNoPath == NO)
{
*tmp++ = '/';
}
strcpy(tmp, baseData->path);
}
else
{
char *start = baseData->path;
char *end = strrchr(start, '/');
if (end != 0)
{
*tmp++ = '/';
strncpy(tmp, start, end - start);
tmp += end - start;
}
*tmp++ = '/';
strcpy(tmp, myData->path);
}
unescape(buf, buf);
#if defined(__MINGW32__)
/* On windows a file URL path may be of the form C:\xxx (ie we should
* not insert the leading slash).
* Also the vertical bar symbol may have been used instead of the
* colon, so we need to convert that.
*/
if (myData->isFile == YES)
{
if (ptr[1] && isalpha(ptr[1]))
{
if (ptr[2] == ':' || ptr[2] == '|')
{
if (ptr[3] == '\0' || ptr[3] == '/' || ptr[3] == '\\')
{
ptr[2] = ':';
ptr++;
}
}
}
}
#endif
return ptr;
}
- (NSString*) fullPath
{
NSString *path = nil;
/*
* If this scheme is from a URL without generic format, there is no path.
*/
if (myData->isGeneric == YES)
{
unsigned int len = (_baseURL ? strlen(baseData->path) : 0)
+ strlen(myData->path) + 3;
char buf[len];
char *ptr;
ptr = [self _path: buf];
path = [NSString stringWithUTF8String: ptr];
}
return path;
}
/**
* Returns the host portion of the receiver or nil if there is no
* host supplied in the URL.<br />
@ -1412,74 +1498,19 @@ static unsigned urlAlign;
unsigned int len = (_baseURL ? strlen(baseData->path) : 0)
+ strlen(myData->path) + 3;
char buf[len];
char *ptr = buf;
char *tmp = buf;
char *ptr;
char *tmp;
if (myData->pathIsAbsolute == YES)
{
if (myData->hasNoPath == NO)
{
*tmp++ = '/';
}
strcpy(tmp, myData->path);
}
else if (_baseURL == nil)
{
strcpy(tmp, myData->path);
}
else if (*myData->path == 0)
{
if (baseData->hasNoPath == NO)
{
*tmp++ = '/';
}
strcpy(tmp, baseData->path);
}
else
{
char *start = baseData->path;
char *end = strrchr(start, '/');
ptr = [self _path: buf];
if (end != 0)
{
*tmp++ = '/';
strncpy(tmp, start, end - start);
tmp += end - start;
}
*tmp++ = '/';
strcpy(tmp, myData->path);
}
unescape(buf, buf);
/* Remove any trailing '/' from the path for MacOS-X compatibility.
*/
tmp = buf + strlen(buf) - 1;
if (tmp > buf && *tmp == '/')
tmp = ptr + strlen(ptr) - 1;
if (tmp > ptr && *tmp == '/')
{
*tmp = '\0';
}
#if defined(__MINGW32__)
/* On windows a file URL path may be of the form C:\xxx (ie we should
* not insert the leading slash).
* Also the vertical bar symbol may have been used instead of the
* colon, so we need to convert that.
*/
if (myData->isFile == YES)
{
if (ptr[1] && isalpha(ptr[1]))
{
if (ptr[2] == ':' || ptr[2] == '|')
{
if (ptr[3] == '\0' || ptr[3] == '/' || ptr[3] == '\\')
{
ptr[2] = ':';
ptr++;
}
}
}
}
#endif
path = [NSString stringWithUTF8String: ptr];
}
return path;

View file

@ -614,7 +614,7 @@ static NSURLProtocol *placeholder = nil;
/* Perform a redirect if the path is empty.
* As per MacOs-X documentation.
*/
if ([[[this->request URL] path] length] == 0)
if ([[[this->request URL] fullPath] length] == 0)
{
NSString *s = [[this->request URL] absoluteString];
NSURL *url;
@ -1058,7 +1058,7 @@ static NSURLProtocol *placeholder = nil;
auth = [authentication
authorizationForAuthentication: hdr
method: [this->request HTTPMethod]
path: [url path]];
path: [url fullPath]];
}
if (auth == nil)
@ -1274,7 +1274,7 @@ static NSURLProtocol *placeholder = nil;
[m appendString: [this->request HTTPMethod]];
[m appendString: @" "];
u = [this->request URL];
s = [u path];
s = [u fullPath];
if ([s hasPrefix: @"/"] == NO)
{
[m appendString: @"/"];
@ -1692,7 +1692,7 @@ static NSURLProtocol *placeholder = nil;
NSURLResponse *r;
NSData *data = [NSData data]; // no data
// we could pass different content depending on the [url path]
// we could pass different content depending on the url path
r = [[NSURLResponse alloc] initWithURL: [this->request URL]
MIMEType: @"text/html"
expectedContentLength: 0