Odd NSURLRequest behavior when URL refers to a subdirectory

Something strange happened today, which perhaps has a simple explanation.

If I create an NSURLRequest using an NSURL that was originally built relative to the base url, which is a subdirectory, the NSURLRequest removes that subdirectory.

It's easier to explain with code:

// create a base URL to work with
NSURL *baseUrl = [NSURL URLWithString:@"http://www.google.com/sub"];

// create a URL relative to the base URL
NSURL *url1 = [NSURL URLWithString:@"/foo/bar" relativeToURL:baseUrl];

// create a NSURLRequest using this first URL
NSURLRequest *mangled_req = [[NSURLRequest alloc] initWithURL:url1];
NSLog(@"url1: %@", url1);
NSLog(@"mangled_req: %@", mangled_req);

// now create another URL that puts the base URL together with the relative path
NSURL *url2 = [NSURL URLWithString:@"http://www.google.com/sub/foo/bar"];

// and create a NSURLRequest, which should be the same as above
NSURLRequest *correct_req = [[NSURLRequest alloc] initWithURL:url2];
NSLog(@"url2: %@", url2);
NSLog(@"correct_req: %@", correct_req);

      

The result demonstrates the point:

2013-01-25 11:55:37.386 url1: /foo/bar -- http://www.google.com/sub
2013-01-25 11:55:37.408 mangled_req: <NSURLRequest http://www.google.com/foo/bar>
2013-01-25 11:55:37.409 url2: http://www.google.com/sub/foo/bar
2013-01-25 11:55:37.409 correct_req: <NSURLRequest http://www.google.com/sub/foo/bar>

      

Note that "mangled_req" omits / sub.

This is annoying me right now because I'm using AFNetworking and want to switch between the localhost for testing (which naturally has my web app in a subdirectory) and the remote server (which it doesn't).

Of course there are workarounds, but it seems strange to me that I should be doing something wrong.

+3


source to share


1 answer


NSURL

behaves correctly and your assumptions about how URLs work are wrong. A "relative" URL that starts with a forward slash, as /foo/bar

always means relative to the host, not relative to an existing path. So if I add /foo/bar

as a relative url to any url scheme://host/path/1/2/3/whatever

, I always get back scheme://host/foo/bar

. A prefix /

on a path means that the path is absolute.



Of course, if you fix it so that your URL is relative foo/bar

, you find that you still have a problem because the original URL doesn't have a trailing slash. Just as if I clicked on the link pointing to somefile.html

while visiting http://host.com/foo/index.html

, I end with http://host.com/foo/somefile.html

instead http://host.com/foo/index.html/somefile.html

, NSURL

removes the last path component if it doesn't have a trailing slash.

+8


source







All Articles