Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 341928

Summary: Representation of resource locations in JSON
Product: [ECD] Orion Reporter: Mark Macdonald <mamacdon>
Component: ClientAssignee: Boris Bokowski <bokowski>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: bokowski, eclipse.felipe, john.arthorne, tomasz.zarna
Version: 0.2   
Target Milestone: 0.2   
Hardware: PC   
OS: Windows 7   
Whiteboard:

Description Mark Macdonald CLA 2011-04-05 10:55:27 EDT
Orion 0.2 M6

While working on the self-hosting scenario described in [1] I ran into a cross-domain XHR issue with resources.

Suppose that the real Orion server is running at http://localhost:8080/ and we launch a site at http://127.0.0.2:8080/ which hosts the client-side JS code from an Orion user's workspace. The site forwards other requests (eg. /workspace, /file, etc) to localhost:8080 to be handled by the real server.

The resource locations returned from REST API calls will include the hostname of the real server. For example GET /workspace has this:

>  "Workspaces": [{
>    "Id": "A",
>    "LastModified": 1295888483302,
>    "Name": "MyWorkspace",
>    "Location": "http://localhost:8080/workspace/A"
>                 ^^^^^^^^^^^^^^^^^^^^^
>  }]

When JavaScript code running on 127.0.0.2:8080 tries to load http://localhost:8080/workspace/A it will fail due to the same-domain restriction.


[1] https://bugs.eclipse.org/bugs/show_bug.cgi?id=340065
Comment 1 Felipe Heidrich CLA 2011-04-05 11:36:04 EDT
I had a similar problem working with js-test-drive the other day, the difference was that I was trying to load resources from the same host but in a different port. The solution js-test-drive offered (and worked for my case) was proxy: http://code.google.com/p/js-test-driver/wiki/Proxy
Comment 2 Boris Bokowski CLA 2011-05-12 22:17:51 EDT
Fixing this is one way of enabling actual self-hosting without having to implement the ability to launch another server instance.
Comment 3 Boris Bokowski CLA 2011-05-12 22:20:39 EDT
Fixed in 58a893cb7198b96221612ad3eba02a99fc6e9efc - I hope the fix is complete, and holds :-)
Comment 4 Tomasz Zarna CLA 2011-05-13 06:35:19 EDT
The change is the most probable cause of bug 345714.
Comment 5 John Arthorne CLA 2011-05-16 10:04:15 EDT
Reopening. This isn't fixed until the tests are passing.
Comment 6 John Arthorne CLA 2011-05-16 10:18:34 EDT
I have commented out the URI rewriting for now, because all the failing tests make it difficult to do other server development:

http://git.eclipse.org/c/e4/org.eclipse.orion.server.git/commit/?id=79520e5fb30762ff17e1024baf016773b7922208

FWIW, I think what the tests are doing are pretty reasonable for a client of the server API. For example they perform a GET on URLS returned by previous calls to ensure they work. Xhr in the browser will automatically add the host/port to any request because in JavaScript there is no choice anyway. For non-JS clients, making them responsible for making all URLs absolute makes our API very unfriendly.
Comment 7 Boris Bokowski CLA 2011-05-16 10:57:41 EDT
(In reply to comment #6)
> I have commented out the URI rewriting for now, because all the failing tests
> make it difficult to do other server development:

Thanks!

> For
> non-JS clients, making them responsible for making all URLs absolute makes our
> API very unfriendly.

I agree in theory, but in practice I don't see how we can achieve self-hosting for the client-side part without making this change.

Note that the test code already uses the following pattern in a lot of places, i.e. it is adding hostname and port:

static WebRequest getPutGitIndexRequest(String location) throws UnsupportedEncodingException {
	String requestURI;
	if (location.startsWith("http://"))
		requestURI = location;
	else
		requestURI = SERVER_LOCATION + GIT_SERVLET_LOCATION + GitConstants.INDEX_RESOURCE + location;
	JSONObject dummy = new JSONObject();
	WebRequest request = new PutMethodWebRequest(requestURI, getJsonAsStream(dummy.toString()), "application/json");
	request.setHeaderField(ProtocolConstants.HEADER_ORION_VERSION, "1");
	setAuthentication(request);
	return request;
}
Comment 8 Szymon Brandys CLA 2011-05-16 11:14:54 EDT
I think that the host name should be part of the server configuration. For instance, if the host name is "http://myserver.com", all URIs returned in JSONs pointing at the server should be "http://myserver.com/[something]". 

So, if you host a server locally, and the host name is configured to "http://127.0.0.1", URIs in JSONs returned from the server should be like "http://127.0.0.1/file/myFile", even if you call GET http://localhost/file/...
Comment 9 Boris Bokowski CLA 2011-05-16 11:25:36 EDT
(In reply to comment #8)
> URIs in JSONs returned from the server should be like
> "http://127.0.0.1/file/myFile", even if you call GET http://localhost/file/...

This would not work for browser clients because of the single-origin policy.
Comment 10 John Arthorne CLA 2011-05-16 11:39:05 EDT
How about only making URLs relative if the following header is present:

X-Requested-With: XMLHttpRequest

The rationale is that with XMLHttpRequest the host/port is implied by the page making the request. For other clients we would continue to serve absolute URLs.
Comment 11 John Arthorne CLA 2011-05-16 11:44:01 EDT
By the way I double-checked that Firefox 4, Chrome 11, and IE 4 all set that header in requests from their JavaScript libraries (X-Requested-With: XMLHttpRequest).
Comment 12 Boris Bokowski CLA 2011-05-16 16:24:26 EDT
(In reply to comment #10)
> How about only making URLs relative if the following header is present:
> 
> X-Requested-With: XMLHttpRequest
> 
> The rationale is that with XMLHttpRequest the host/port is implied by the page
> making the request. For other clients we would continue to serve absolute URLs.

Done. Thanks for the idea! Can you please re-run the tests to make sure I haven't broken them again? Running the tests on MacOS X doesn't really work yet. I'll be filing a separate bug about that.