1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 }