View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.client.cache;
28  
29  import static junit.framework.TestCase.assertNull;
30  import static junit.framework.TestCase.assertTrue;
31  
32  import java.io.ByteArrayInputStream;
33  import java.util.Date;
34  
35  import org.apache.http.HttpEntity;
36  import org.apache.http.HttpEntityEnclosingRequest;
37  import org.apache.http.HttpResponse;
38  import org.apache.http.HttpStatus;
39  import org.apache.http.HttpVersion;
40  import org.apache.http.client.ClientProtocolException;
41  import org.apache.http.client.methods.HttpGet;
42  import org.apache.http.client.methods.HttpHead;
43  import org.apache.http.client.methods.HttpRequestWrapper;
44  import org.apache.http.client.utils.DateUtils;
45  import org.apache.http.entity.ByteArrayEntity;
46  import org.apache.http.entity.InputStreamEntity;
47  import org.apache.http.message.BasicHttpEntityEnclosingRequest;
48  import org.apache.http.message.BasicHttpResponse;
49  import org.junit.Before;
50  import org.junit.Test;
51  
52  public class TestResponseProtocolCompliance {
53  
54      private ResponseProtocolCompliance impl;
55  
56      @Before
57      public void setUp() {
58          impl = new ResponseProtocolCompliance();
59      }
60  
61      private static class Flag {
62          public boolean set;
63      }
64  
65      private void setMinimalResponseHeaders(final HttpResponse resp) {
66          resp.setHeader("Date", DateUtils.formatDate(new Date()));
67          resp.setHeader("Server", "MyServer/1.0");
68      }
69  
70      private ByteArrayInputStream makeTrackableBody(final int nbytes, final Flag closed) {
71          final byte[] buf = HttpTestUtils.getRandomBytes(nbytes);
72          final ByteArrayInputStream bais = new ByteArrayInputStream(buf) {
73              @Override
74              public void close() {
75                  closed.set = true;
76              }
77          };
78          return bais;
79      }
80  
81      private HttpResponse makePartialResponse(final int nbytes) {
82          final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content");
83          setMinimalResponseHeaders(resp);
84          resp.setHeader("Content-Length","" + nbytes);
85          resp.setHeader("Content-Range","0-127/256");
86          return resp;
87      }
88  
89      @Test
90      public void consumesBodyIfOriginSendsOneInResponseToHEAD() throws Exception {
91          final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(new HttpHead("http://foo.example.com/"));
92          final int nbytes = 128;
93          final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
94          setMinimalResponseHeaders(resp);
95          resp.setHeader("Content-Length","" + nbytes);
96  
97          final Flag closed = new Flag();
98          final ByteArrayInputStream bais = makeTrackableBody(nbytes, closed);
99          resp.setEntity(new InputStreamEntity(bais, -1));
100 
101         impl.ensureProtocolCompliance(wrapper, resp);
102         assertNull(resp.getEntity());
103         assertTrue(closed.set || bais.read() == -1);
104     }
105 
106     @Test(expected=ClientProtocolException.class)
107     public void throwsExceptionIfOriginReturnsPartialResponseWhenNotRequested() throws Exception {
108         final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
109         final int nbytes = 128;
110         final HttpResponse resp = makePartialResponse(nbytes);
111         resp.setEntity(HttpTestUtils.makeBody(nbytes));
112 
113         impl.ensureProtocolCompliance(wrapper, resp);
114     }
115 
116     @Test
117     public void consumesPartialContentFromOriginEvenIfNotRequested() throws Exception {
118         final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
119         final int nbytes = 128;
120         final HttpResponse resp = makePartialResponse(nbytes);
121 
122         final Flag closed = new Flag();
123         final ByteArrayInputStream bais = makeTrackableBody(nbytes, closed);
124         resp.setEntity(new InputStreamEntity(bais, -1));
125 
126         try {
127             impl.ensureProtocolCompliance(wrapper, resp);
128         } catch (final ClientProtocolException expected) {
129         }
130         assertTrue(closed.set || bais.read() == -1);
131     }
132 
133     @Test
134     public void consumesBodyOf100ContinueResponseIfItArrives() throws Exception {
135         final HttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST", "/", HttpVersion.HTTP_1_1);
136         final int nbytes = 128;
137         req.setHeader("Content-Length","" + nbytes);
138         req.setHeader("Content-Type", "application/octet-stream");
139         final HttpEntity postBody = new ByteArrayEntity(HttpTestUtils.getRandomBytes(nbytes));
140         req.setEntity(postBody);
141         final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req);
142 
143         final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_CONTINUE, "Continue");
144         final Flag closed = new Flag();
145         final ByteArrayInputStream bais = makeTrackableBody(nbytes, closed);
146         resp.setEntity(new InputStreamEntity(bais, -1));
147 
148         try {
149             impl.ensureProtocolCompliance(wrapper, resp);
150         } catch (final ClientProtocolException expected) {
151         }
152         assertTrue(closed.set || bais.read() == -1);
153     }
154 
155 }