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  import io.netty.util.IllegalReferenceCountException;
21  import static io.netty.util.internal.ObjectUtil.checkNotNull;
22  
23  /**
24   * Default implementation of {@link FullHttpRequest}.
25   */
26  public class DefaultFullHttpRequest extends DefaultHttpRequest implements FullHttpRequest {
27      private final ByteBuf content;
28      private final HttpHeaders trailingHeader;
29  
30      /**
31       * Used to cache the value of the hash code and avoid {@link IllegalReferenceCountException}.
32       */
33      private int hash;
34  
35      public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri) {
36          this(httpVersion, method, uri, Unpooled.buffer(0));
37      }
38  
39      public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri, ByteBuf content) {
40          this(httpVersion, method, uri, content, true);
41      }
42  
43      public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri, boolean validateHeaders) {
44          this(httpVersion, method, uri, Unpooled.buffer(0), validateHeaders);
45      }
46  
47      public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri,
48                                    ByteBuf content, boolean validateHeaders) {
49          super(httpVersion, method, uri, validateHeaders);
50          this.content = checkNotNull(content, "content");
51          trailingHeader = new DefaultHttpHeaders(validateHeaders);
52      }
53  
54      public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri,
55              ByteBuf content, HttpHeaders headers, HttpHeaders trailingHeader) {
56          super(httpVersion, method, uri, headers);
57          this.content = checkNotNull(content, "content");
58          this.trailingHeader = checkNotNull(trailingHeader, "trailingHeader");
59      }
60  
61      @Override
62      public HttpHeaders trailingHeaders() {
63          return trailingHeader;
64      }
65  
66      @Override
67      public ByteBuf content() {
68          return content;
69      }
70  
71      @Override
72      public int refCnt() {
73          return content.refCnt();
74      }
75  
76      @Override
77      public FullHttpRequest retain() {
78          content.retain();
79          return this;
80      }
81  
82      @Override
83      public FullHttpRequest retain(int increment) {
84          content.retain(increment);
85          return this;
86      }
87  
88      @Override
89      public FullHttpRequest touch() {
90          content.touch();
91          return this;
92      }
93  
94      @Override
95      public FullHttpRequest touch(Object hint) {
96          content.touch(hint);
97          return this;
98      }
99  
100     @Override
101     public boolean release() {
102         return content.release();
103     }
104 
105     @Override
106     public boolean release(int decrement) {
107         return content.release(decrement);
108     }
109 
110     @Override
111     public FullHttpRequest setProtocolVersion(HttpVersion version) {
112         super.setProtocolVersion(version);
113         return this;
114     }
115 
116     @Override
117     public FullHttpRequest setMethod(HttpMethod method) {
118         super.setMethod(method);
119         return this;
120     }
121 
122     @Override
123     public FullHttpRequest setUri(String uri) {
124         super.setUri(uri);
125         return this;
126     }
127 
128     @Override
129     public FullHttpRequest copy() {
130         return replace(content().copy());
131     }
132 
133     @Override
134     public FullHttpRequest duplicate() {
135         return replace(content().duplicate());
136     }
137 
138     @Override
139     public FullHttpRequest retainedDuplicate() {
140         return replace(content().retainedDuplicate());
141     }
142 
143     @Override
144     public FullHttpRequest replace(ByteBuf content) {
145         FullHttpRequest request = new DefaultFullHttpRequest(protocolVersion(), method(), uri(), content,
146                 headers().copy(), trailingHeaders().copy());
147         request.setDecoderResult(decoderResult());
148         return request;
149     }
150 
151     @Override
152     public int hashCode() {
153         int hash = this.hash;
154         if (hash == 0) {
155             if (content().refCnt() != 0) {
156                 try {
157                     hash = 31 + content().hashCode();
158                 } catch (IllegalReferenceCountException ignored) {
159                     // Handle race condition between checking refCnt() == 0 and using the object.
160                     hash = 31;
161                 }
162             } else {
163                 hash = 31;
164             }
165             hash = 31 * hash + trailingHeaders().hashCode();
166             hash = 31 * hash + super.hashCode();
167             this.hash = hash;
168         }
169         return hash;
170     }
171 
172     @Override
173     public boolean equals(Object o) {
174         if (!(o instanceof DefaultFullHttpRequest)) {
175             return false;
176         }
177 
178         DefaultFullHttpRequest other = (DefaultFullHttpRequest) o;
179 
180         return super.equals(other) &&
181                content().equals(other.content()) &&
182                trailingHeaders().equals(other.trailingHeaders());
183     }
184 
185     @Override
186     public String toString() {
187         return HttpMessageUtil.appendFullRequest(new StringBuilder(256), this).toString();
188     }
189 }