Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #382: Extract headers from IPFS API requests and apply them to hijacked ones. #623

Merged
merged 3 commits into from Dec 20, 2018

Conversation

hsanjuan
Copy link
Collaborator

This commit makes the proxy extract useful fixed headers (like CORS) from
the IPFS daemon API responses and then apply them to the responses
from hijacked endpoints like /add or /repo/stat.

It does this by caching a list of headers from the first IPFS API
response which has them. If we have not performed any proxied request or
managed to obtain the headers we're interested in, this will try triggering a
request to "/api/v0/version" to obtain them first.

This should fix the issues with using Cluster proxy with IPFS Companion and
Chrome.

License: MIT
Signed-off-by: Hector Sanjuan code@hector.link

@hsanjuan hsanjuan self-assigned this Dec 18, 2018
@ghost ghost added the status/in-progress In progress label Dec 18, 2018
@ipfs-cluster ipfs-cluster deleted a comment from GitCop Dec 18, 2018
…cked ones.

This commit makes the proxy extract useful fixed headers (like CORS) from
the IPFS daemon API responses and then apply them to the responses
from hijacked endpoints like /add or /repo/stat.

It does this by caching a list of headers from the first IPFS API
response which has them. If we have not performed any proxied request or
managed to obtain the headers we're interested in, this will try triggering a
request to "/api/v0/version" to obtain them first.

This should fix the issues with using Cluster proxy with IPFS Companion and
Chrome.

License: MIT
Signed-off-by: Hector Sanjuan <code@hector.link>
@coveralls
Copy link

coveralls commented Dec 18, 2018

Coverage Status

Coverage increased (+0.09%) to 65.181% when pulling 159243d on fix/proxy-headers into 9f6a173 on master.

Copy link
Contributor

@kishansagathiya kishansagathiya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR looks good except a minor concerns about header checking

@@ -1,4 +1,4 @@
package ipfscluster
package version
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would have been nice to have a separate commit for creating the version package. But let it be as it is, it would be overkill to go back and spit the commit.

func (proxy *Server) isIPFSHeadersKnown() bool {
_, ok := proxy.ipfsHeaders.Load(ipfsHeaderList[0])
return ok
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(From looking at this and references of isIPFSHeadersKnown) It assumes that if Server header is present, remaining headers are present as well. Shouldn't we check other headers? Depending we need to check for other headers or not the name can be changed to areIPFSHeadersKnown or isServerHeaderPresent.

Suggested change
}
func (proxy *Server) areIPFSHeadersKnown() bool {
for _, header := range ipfsHeaderList {
if _, ok := proxy.ipfsHeaders.Load(header); !ok {
return !ok
}
}
return true
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a Go unwritten rule saying that boolean functions start with is? @lanzafame ?

Shouldn't we check other headers?

We can assume that if we learned about Server (or any one of them) we have learned about the rest. But maybe worth checking the whole list.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a Go unwritten rule saying that boolean functions start with is?

There is this:

"The Go Programming Language" by Donovan and Kernighan recommends in Chapter 6 that

Functions that merely access or modify internal values of a type..are called getters and setters. > However, when naming a getter method we usually omit the Get prefix. This Preference for brevity extends to all methods not just field accessors, and to other reductant prefixes as well, such as Fetch, Find and Lookup

But I wouldn't apply that to is. Though in this particular case, Known is enough of an indicator that this is a boolean predicate.

Copy link
Contributor

@kishansagathiya kishansagathiya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On trying it out, I don't see response headers with proxy endpoints, however I do see expected response headers( as in ipfsHeaderList) with ipfs endpoints. Can you check and confirm if you see the same thing?

kishan@kishansagathiya:~/$ curl -X GET http://localhost:9096/api/v0/pin/ls -v
Note: Unnecessary use of -X or --request, GET is already inferred.
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 9096 (#0)
> GET /api/v0/pin/ls HTTP/1.1
> Host: localhost:9096
> User-Agent: curl/7.58.0
> Accept: */*
> 
* Connection #0 to host localhost left intact
��f#[L��{m-�P�p9��Ѫ��#3���B�%���)��S"�~��kishan@kishansagathiya:~/$ 

@lanzafame
Copy link
Contributor

@kishansagathiya that is the wrong port number. The proxy api is on 9095. 9096 is the libp2p swarm/cluster-api port.

@lanzafame
Copy link
Contributor

$ curl http://localhost:9095/api/v0/pin/ls -v                          16:38
*   Trying ::1...
* TCP_NODELAY set
* connect to ::1 port 9095 failed: Connection refused
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 9095 (#0)
> GET /api/v0/pin/ls HTTP/1.1
> Host: localhost:9095
> User-Agent: curl/7.63.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Access-Control-Allow-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length
< Access-Control-Expose-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length
< Content-Type: application/json
< Server: ipfs-cluster/ipfsproxy/0.7.0+git862c1eb3eaaa3b6103e65b4804df0faf56b07882
< Trailer: X-Stream-Error
< Vary: Origin
< Date: Wed, 19 Dec 2018 06:38:11 GMT
< Transfer-Encoding: chunked
< 
* Connection #0 to host localhost left intact
{"Keys":{}}

@kishansagathiya
Copy link
Contributor

kishansagathiya commented Dec 19, 2018

@lanzafame

that is the wrong port number. The proxy api is on 9095. 9096 is the libp2p swarm/cluster-api port.

My bad, this is what confused me. Will have to modify that docker-compose file 😆

License: MIT
Signed-off-by: Hector Sanjuan <code@hector.link>
And do it by only loading them from the sync.Map once.

License: MIT
Signed-off-by: Hector Sanjuan <code@hector.link>
@hsanjuan
Copy link
Collaborator Author

Ok thanks for the feedback. I made it in a way that we only load the headers once from the sync.Map for every request. And if we don't have all the headers we want we will try to call /version to get them. Ready on my side.

Copy link
Contributor

@kishansagathiya kishansagathiya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Trick used in last commit to get headers from sync.Map.

I will leave merging for you

@hsanjuan hsanjuan mentioned this pull request Dec 20, 2018
@hsanjuan hsanjuan merged commit 17599da into master Dec 20, 2018
@hsanjuan hsanjuan deleted the fix/proxy-headers branch December 20, 2018 14:36
@ghost ghost removed the status/in-progress In progress label Dec 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants