IllegalRefCountException in FullHttp[Request|Response].hashCode()
Motivation: FullHttp[Request|Response].hashCode() uses a releasable object and in vulnerable to a IllegalRefCountException if that object has been released. Modifications: - Ensure the released object is not used. Result: No more IllegalRefCountException.
This commit is contained in:
parent
120ffaf880
commit
0d71744d5b
@ -17,15 +17,19 @@ package io.netty.handler.codec.http;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.util.IllegalReferenceCountException;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link FullHttpRequest}.
|
||||
*/
|
||||
public class DefaultFullHttpRequest extends DefaultHttpRequest implements FullHttpRequest {
|
||||
private static final int HASH_CODE_PRIME = 31;
|
||||
private final ByteBuf content;
|
||||
private final HttpHeaders trailingHeader;
|
||||
private final boolean validateHeaders;
|
||||
/**
|
||||
* Used to cache the value of the hash code and avoid {@link IllegalRefCountException}.
|
||||
*/
|
||||
private int hash;
|
||||
|
||||
public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri) {
|
||||
this(httpVersion, method, uri, Unpooled.buffer(0));
|
||||
@ -163,11 +167,23 @@ public class DefaultFullHttpRequest extends DefaultHttpRequest implements FullHt
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = HASH_CODE_PRIME * result + content().hashCode();
|
||||
result = HASH_CODE_PRIME * result + trailingHeaders().hashCode();
|
||||
result = HASH_CODE_PRIME * result + super.hashCode();
|
||||
return result;
|
||||
int hash = this.hash;
|
||||
if (hash == 0) {
|
||||
if (content().refCnt() != 0) {
|
||||
try {
|
||||
hash = 31 + content().hashCode();
|
||||
} catch (IllegalReferenceCountException ignored) {
|
||||
// Handle race condition between checking refCnt() == 0 and using the object.
|
||||
hash = 31;
|
||||
}
|
||||
} else {
|
||||
hash = 31;
|
||||
}
|
||||
hash = 31 * hash + trailingHeaders().hashCode();
|
||||
hash = 31 * hash + super.hashCode();
|
||||
this.hash = hash;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,9 +15,11 @@
|
||||
*/
|
||||
package io.netty.handler.codec.http;
|
||||
|
||||
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.util.IllegalReferenceCountException;
|
||||
|
||||
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
||||
|
||||
/**
|
||||
* Default implementation of a {@link FullHttpResponse}.
|
||||
@ -27,6 +29,10 @@ public class DefaultFullHttpResponse extends DefaultHttpResponse implements Full
|
||||
private final ByteBuf content;
|
||||
private final HttpHeaders trailingHeaders;
|
||||
private final boolean validateHeaders;
|
||||
/**
|
||||
* Used to cache the value of the hash code and avoid {@link IllegalRefCountException}.
|
||||
*/
|
||||
private int hash;
|
||||
|
||||
public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status) {
|
||||
this(version, status, Unpooled.buffer(0));
|
||||
@ -164,6 +170,40 @@ public class DefaultFullHttpResponse extends DefaultHttpResponse implements Full
|
||||
return duplicate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = this.hash;
|
||||
if (hash == 0) {
|
||||
if (content().refCnt() != 0) {
|
||||
try {
|
||||
hash = 31 + content().hashCode();
|
||||
} catch (IllegalReferenceCountException ignored) {
|
||||
// Handle race condition between checking refCnt() == 0 and using the object.
|
||||
hash = 31;
|
||||
}
|
||||
} else {
|
||||
hash = 31;
|
||||
}
|
||||
hash = 31 * hash + trailingHeaders().hashCode();
|
||||
hash = 31 * hash + super.hashCode();
|
||||
this.hash = hash;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof DefaultFullHttpResponse)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DefaultFullHttpResponse other = (DefaultFullHttpResponse) o;
|
||||
|
||||
return super.equals(other) &&
|
||||
content().equals(other.content()) &&
|
||||
trailingHeaders().equals(other.trailingHeaders());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return HttpMessageUtil.appendFullResponse(new StringBuilder(256), this).toString();
|
||||
|
Loading…
Reference in New Issue
Block a user