Repository: netty/netty
Issue: DefaultHttpResponse does not implement equals and hashCode to cover response status

### Expected behavior
Two DefaultHttpResponse instances with different response status should not be considered equal. Headers and HTTP version are already covered in DefaultHttpMessage. DefaultFullHttpResponse also covers content and trailing headers. I would assume the response status is considered as well.

### Actual behavior
Response status is ignored by equals and hashCode. DefaultHttpResponse does not override those methods.

### Steps to reproduce
Run example below.

### Minimal yet complete reproducer code
```java
import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;

class ResponseStatusEquality
{
  public static void main(String... args)
  {
    var ok = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    var notFound = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND);
    if (ok.equals(notFound)) {
      throw new AssertionError(); // should not throw!
    }
  }
}
```

### Netty version
4.1.25.Final

### JVM version (e.g. `java -version`)
openjdk version "10.0.1" 2018-04-17
OpenJDK Runtime Environment (build 10.0.1+10)
OpenJDK 64-Bit Server VM (build 10.0.1+10, mixed mode)

### OS version (e.g. `uname -a`)
Linux 4.16.10

Issue comments:
sounds like a bug to me... looking now
@ewie thanks for reporting, fixed by https://github.com/netty/netty/pull/7965

Pull request review comments:
Assert the hash codes are equal as well.

Patch that resolved the issue:
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponse.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponse.java
index 86858108a27..d5b7cf0b7b9 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponse.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponse.java
@@ -105,4 +105,23 @@ public HttpResponse setProtocolVersion(HttpVersion version) {
     public String toString() {
         return HttpMessageUtil.appendResponse(new StringBuilder(256), this).toString();
     }
+
+    @Override
+    public int hashCode() {
+        int result = 1;
+        result = 31 * result + status.hashCode();
+        result = 31 * result + super.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof DefaultHttpResponse)) {
+            return false;
+        }
+
+        DefaultHttpResponse other = (DefaultHttpResponse) o;
+
+        return status.equals(other.status()) && super.equals(o);
+    }
 }


Test patch:
diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpResponseTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpResponseTest.java
new file mode 100644
index 00000000000..0a466c6bff9
--- /dev/null
+++ b/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpResponseTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2018 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.netty.handler.codec.http;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+public class DefaultHttpResponseTest {
+
+   @Test
+    public void testNotEquals() {
+        HttpResponse ok = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
+        HttpResponse notFound = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND);
+        assertNotEquals(ok, notFound);
+        assertNotEquals(ok.hashCode(), notFound.hashCode());
+   }
+
+    @Test
+    public void testEquals() {
+        HttpResponse ok = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
+        HttpResponse ok2 = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
+        assertEquals(ok, ok2);
+        assertEquals(ok.hashCode(), ok2.hashCode());
+    }
+}