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

Add client module #359

Merged
merged 6 commits into from Nov 28, 2022
Merged

Add client module #359

merged 6 commits into from Nov 28, 2022

Conversation

jholdstock
Copy link
Member

@jholdstock jholdstock commented Nov 21, 2022

Export a client module - a reusable HTTP client for vspd API consumers. This will be useful for dcrwallet, dcrwebapi, and testing tools such as v3tool which will soon be moved into this repo.

The first commit on this PR is code copied directly from dcrwallet and the following commits are a few minor refactors.

@jrick - I'd appreciate a review from you on this because I'd like to see dcrwallet consume this module. I've already got a local diff for that which is working well.

@jholdstock jholdstock marked this pull request as draft November 21, 2022 09:57
client/client.go Outdated
Comment on lines 171 to 174
// Verify initial request matches server.
if !bytes.Equal(reqBody, resp.(vspResponse).Request) {
return fmt.Errorf("server response contains differing request")
}
Copy link
Member

Choose a reason for hiding this comment

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

currently in wallet, all of the POST methods do this check, but we do not perform it for GET /api/v3/vspinfo. So this looks fine as long as that is tested and works.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch. I had thoroughly tested all of the POST funcs using v3tool, but not the GET one. I've pulled that logic out of do() up into post() UPDATE: scrap that, I've just reverted back to the way it was being checked in the original code.

Copy link
Member

Choose a reason for hiding this comment

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

My only other concern with moving this wallet code into this vspd package is it now becomes harder (impossible?) for wallet to ever save the signed response from the vsp. Granted we weren't doing that yet, but in the original vspd concept, these signed responses would be recorded and could be used as proof in case a vsp voted against a user's choices.

Copy link
Member Author

Choose a reason for hiding this comment

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

Great point, ill work on that.

Copy link
Member Author

Choose a reason for hiding this comment

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

Opened #364 to implement this.


status := reply.StatusCode

if status != http.StatusOK {
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason why wallet's handling of non-400 errors is different? An issue we had run into before was where a reverse proxy was misconfigured, or vspd was not running/crashed/etc., and the 500 errors from the RP were difficult to distinguish from API errors.

Copy link
Member

Choose a reason for hiding this comment

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

or rather, we still wanted to parse the response body if vspd returned a 400 level error.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not entirely sure what the original thinking for the different handling was, but afaict the errors returned by the new code will contain either the same or more information than those returned by the old code, so I think we are covered. I've added comments to explain the logic.

Copy link
Member

Choose a reason for hiding this comment

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

I think it's probably a little more resilient to decide how to decode the response or return an error based on the HTTP status code first, rather than reading the response body first, but I think this code should work for most situations and we should still see 500 level errors in the error message as long as the reverse proxy's response body is not a JSON object.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think client should trust HTTP status for two reasons:

  • Client will need to maintain its own list of statuses which it expects vspd to return, which is annoying and liable to fall out of date.
  • Intermediary servers may return the same statuses as vspd returns, eg. RP might return 500 if vspd is down, vspd might return 500 if dcrd is down.

I just tried the "500 + JSON" scenario you described and I see that the code isnt working as I thought it would. I'll write some tests to make sure it works properly.

Copy link
Member Author

Choose a reason for hiding this comment

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

Tests added in #363

@jholdstock jholdstock marked this pull request as ready for review November 22, 2022 12:48
@dajohi dajohi merged commit 4acd57e into decred:master Nov 28, 2022
@jholdstock jholdstock deleted the httpclient2 branch September 20, 2023 08:23
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

3 participants