View Javadoc
1   /*
2    * Copyright 2013 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.http;
17  
18  import io.netty.buffer.ByteBuf;
19  import io.netty.buffer.Unpooled;
20  
21  
22  /**
23   * Default implementation of a {@link FullHttpResponse}.
24   */
25  public class DefaultFullHttpResponse extends DefaultHttpResponse implements FullHttpResponse {
26      private static final int HASH_CODE_PRIME = 31;
27      private final ByteBuf content;
28      private final HttpHeaders trailingHeaders;
29      private final boolean validateHeaders;
30  
31      public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status) {
32          this(version, status, Unpooled.buffer(0));
33      }
34  
35      public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status, ByteBuf content) {
36          this(version, status, content, false);
37      }
38  
39      public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status, boolean validateHeaders) {
40          this(version, status, Unpooled.buffer(0), validateHeaders, false);
41      }
42  
43      public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status, boolean validateHeaders,
44                                     boolean singleFieldHeaders) {
45          this(version, status, Unpooled.buffer(0), validateHeaders, singleFieldHeaders);
46      }
47  
48      public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status,
49                                     ByteBuf content, boolean singleFieldHeaders) {
50          this(version, status, content, true, singleFieldHeaders);
51      }
52  
53      public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status,
54                                     ByteBuf content, boolean validateHeaders, boolean singleFieldHeaders) {
55          super(version, status, validateHeaders, singleFieldHeaders);
56          if (content == null) {
57              throw new NullPointerException("content");
58          }
59          this.content = content;
60          trailingHeaders = new DefaultHttpHeaders(validateHeaders, singleFieldHeaders);
61          this.validateHeaders = validateHeaders;
62      }
63  
64      @Override
65      public HttpHeaders trailingHeaders() {
66          return trailingHeaders;
67      }
68  
69      @Override
70      public ByteBuf content() {
71          return content;
72      }
73  
74      @Override
75      public int refCnt() {
76          return content.refCnt();
77      }
78  
79      @Override
80      public FullHttpResponse retain() {
81          content.retain();
82          return this;
83      }
84  
85      @Override
86      public FullHttpResponse retain(int increment) {
87          content.retain(increment);
88          return this;
89      }
90  
91      @Override
92      public FullHttpResponse touch() {
93          content.touch();
94          return this;
95      }
96  
97      @Override
98      public FullHttpResponse touch(Object hint) {
99          content.touch(hint);
100         return this;
101     }
102 
103     @Override
104     public boolean release() {
105         return content.release();
106     }
107 
108     @Override
109     public boolean release(int decrement) {
110         return content.release(decrement);
111     }
112 
113     @Override
114     public FullHttpResponse setProtocolVersion(HttpVersion version) {
115         super.setProtocolVersion(version);
116         return this;
117     }
118 
119     @Override
120     public FullHttpResponse setStatus(HttpResponseStatus status) {
121         super.setStatus(status);
122         return this;
123     }
124 
125     /**
126      * Copy this object
127      *
128      * @param copyContent
129      * <ul>
130      * <li>{@code true} if this object's {@link #content()} should be used to copy.</li>
131      * <li>{@code false} if {@code newContent} should be used instead.</li>
132      * </ul>
133      * @param newContent
134      * <ul>
135      * <li>if {@code copyContent} is false then this will be used in the copy's content.</li>
136      * <li>if {@code null} then a default buffer of 0 size will be selected</li>
137      * </ul>
138      * @return A copy of this object
139      */
140     private FullHttpResponse copy(boolean copyContent, ByteBuf newContent) {
141         DefaultFullHttpResponse copy = new DefaultFullHttpResponse(
142                 protocolVersion(), status(),
143                 copyContent ? content().copy() :
144                     newContent == null ? Unpooled.buffer(0) : newContent);
145         copy.headers().set(headers());
146         copy.trailingHeaders().set(trailingHeaders());
147         return copy;
148     }
149 
150     @Override
151     public FullHttpResponse copy(ByteBuf newContent) {
152         return copy(false, newContent);
153     }
154 
155     @Override
156     public FullHttpResponse copy() {
157         return copy(true, null);
158     }
159 
160     @Override
161     public FullHttpResponse duplicate() {
162         DefaultFullHttpResponse duplicate = new DefaultFullHttpResponse(protocolVersion(), status(),
163                 content().duplicate(), validateHeaders);
164         duplicate.headers().set(headers());
165         duplicate.trailingHeaders().set(trailingHeaders());
166         return duplicate;
167     }
168 
169     @Override
170     public int hashCode() {
171         int result = 1;
172         result = HASH_CODE_PRIME * result + content().hashCode();
173         result = HASH_CODE_PRIME * result + trailingHeaders().hashCode();
174         result = HASH_CODE_PRIME * result + super.hashCode();
175         return result;
176     }
177 
178     @Override
179     public boolean equals(Object o) {
180         if (!(o instanceof DefaultFullHttpResponse)) {
181             return false;
182         }
183 
184         DefaultFullHttpResponse other = (DefaultFullHttpResponse) o;
185 
186         return super.equals(other) &&
187                content().equals(other.content()) &&
188                trailingHeaders().equals(other.trailingHeaders());
189     }
190 
191     @Override
192     public String toString() {
193         return HttpMessageUtil.appendFullResponse(new StringBuilder(256), this).toString();
194     }
195 }