Came across something odd today, which perhaps has a simple explanation.
If I create an NSURLRequest using an NSURL that was originally constructed relative to a base URL that is a subdirectory, NSURLRequest removes the subdirectory.
This is much 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 output 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 the “mangled_req” omits /sub.
This is annoying me right now, because I’m using AFNetworking and want to switch between localhost for testing (which naturally has my web application in a subdirectory) and the remote server (which doesn’t).
Certainly there are workarounds, but this seems odd enough to me that I must be doing something wrong.
NSURLis behaving correctly and your assumptions about how URLs work are wrong. A “relative” URL that starts with a slash, as/foo/bardoes, always means relative to the host, not relative to the existing path. So if I add/foo/baras a relative URL to any urlscheme://host/path/1/2/3/whateverI will always get backscheme://host/foo/bar. A prefix/on the path means the path is absolute.Of course, if you fix this such that your relative URL is
foo/bar, you’ll find that you still have a problem, because your original URL did not have a trailing slash. Just as how if I click a link that points tosomefile.htmlwhile visitinghttp://host.com/foo/index.htmlI end up athttp://host.com/foo/somefile.htmlinstead ofhttp://host.com/foo/index.html/somefile.html,NSURLwill remove the last path component if it does not have a trailing slash.