-
Notifications
You must be signed in to change notification settings - Fork 25.1k
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
Adds percent-encoding for Location headers #21057
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a comment.
try { | ||
URI uri = new URI(location.toString()); | ||
return uri.toASCIIString(); | ||
} catch (URISyntaxException ex) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using an exception for flow control should be avoided here. Is there another way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, when using an exception for flow control like this, it at a minimum needs to be commented to explain what is going on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fairly sure Location
is supposed to be a valid URI. I'd be ok with catching the exception and logging a warning for it unless we expect this to fail frequently. If we do then we shouldn't be using URI
.
try { | ||
URI uri = new URI(location.toString()); | ||
return uri.toASCIIString(); | ||
} catch (URISyntaxException ex) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fairly sure Location
is supposed to be a valid URI. I'd be ok with catching the exception and logging a warning for it unless we expect this to fail frequently. If we do then we shouldn't be using URI
.
@jasontedor, @nik9000 I've collapsed the try/catch return statements into a single return statement, commented it and added a logging statement. I don't expect the exception case to be hit at all, as the Location header should contain a valid URI. Thanks for the comments and reviews! |
locationString = uri.toASCIIString(); | ||
} catch (URISyntaxException ex) { | ||
// could not encode URI properly, using toString instead. | ||
logger.debug("Location string is not a valid URI."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add the exception to the log statement? If we really don't expect this to happen I think it should be a warn
level. If someone is able to reproduce it then they can silence it with the update settings API before we work around it.
Now that I think about it, it'd be nicer to throw the URISyntaxException
out of the method and then catch it when we go to write the location, warning there instead of here. That way we don't add the Location
header with an empty string.
dd74d08
to
5dfa3a9
Compare
@nik9000 @jasontedor I've rebased onto latest master. Returning null from this method will cause the downstream consumer to not add the 'Location' header to the response. We expect to almost never return null. |
try { | ||
URI uri = new URI(location.toString()); | ||
locationString = uri.toASCIIString(); | ||
} catch (URISyntaxException ex) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I was thinking that it'd be better to just throw the exception and catch it in the caller. That way the caller can log the warning and not add the location header.
@nik9000 I've made the change and added a test for the exception behavior. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @a2lin, I'm much happier with this now. I left a request for one more change.
|
||
public DocWriteResponse(ShardId shardId, String type, String id, long version, Result result) { | ||
this.shardId = shardId; | ||
this.type = type; | ||
this.id = id; | ||
this.version = version; | ||
this.result = result; | ||
this.logger = LogManager.getLogger(getClass()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be here. You should use ESLoggerFactory instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think this logger can be removed now (thankfully).
@@ -176,7 +182,7 @@ public RestStatus status() { | |||
* Gets the location of the written document as a string suitable for a {@code Location} header. | |||
* @param routing any routing used in the request. If null the location doesn't include routing information. | |||
*/ | |||
public String getLocation(@Nullable String routing) { | |||
public String getLocation(@Nullable String routing) throws URISyntaxException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is much better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked more closely, I think the logger can just go now.
|
||
public DocWriteResponse(ShardId shardId, String type, String id, long version, Result result) { | ||
this.shardId = shardId; | ||
this.type = type; | ||
this.id = id; | ||
this.version = version; | ||
this.result = result; | ||
this.logger = LogManager.getLogger(getClass()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think this logger can be removed now (thankfully).
@jasontedor Oops, sorry 'bout that. I've killed the logger. |
c63f339
to
d9b8b42
Compare
@jasontedor @nik9000 rebased to master. Was there something else I should have fixed? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a small thing but it looks good to me.
}; | ||
try { | ||
invalid.getLocation(null); | ||
fail("Did not correctly throw exception on invalid Location parameters"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use expectThrows
here. I also like assertion something about the exception's massage just to make sure I caught the one I expected.
d9b8b42
to
4e64ba3
Compare
@nik9000 Wow, did not know that expectThrows was a thing. Nifty. |
This looks good to me now. elasticmachine, please test this |
This should cause unicode elements in the location header to be percent-encoded, instead of being left alone. Closes #21016
Thanks for reviewing! |
This pr should cause unicode elements in the location header to be percent-encoded, instead of being left alone.
For the cases mentioned by @weltenwort in #21016, they now return:
The above responses compare favorably with the responses from a checkout of current master:
Closes #21016