View | Details | Raw Unified | Return to bug 53169
Collapse All | Expand All

(-)test/webapp-3.0/WEB-INF/web.xml (+20 lines)
Lines 95-100 Link Here
95
    <servlet-name>Bug49922</servlet-name>
95
    <servlet-name>Bug49922</servlet-name>
96
    <url-pattern>*.od</url-pattern>
96
    <url-pattern>*.od</url-pattern>
97
  </servlet-mapping>
97
  </servlet-mapping>
98
  <servlet>
99
    <servlet-name>NoContentLengthFlushingServlet</servlet-name>
100
    <servlet-class>
101
      org.apache.catalina.core.TestStandardContext$NoContentLengthFlushingServlet
102
    </servlet-class>
103
  </servlet>
104
  <servlet-mapping>
105
    <servlet-name>NoContentLengthFlushingServlet</servlet-name>
106
    <url-pattern>/noContentLengthFlushingServlet/servlet</url-pattern>
107
  </servlet-mapping>
108
  <servlet>
109
    <servlet-name>NoContentLengthConnectionCloseFlushingServlet</servlet-name>
110
    <servlet-class>
111
      org.apache.catalina.core.TestStandardContext$NoContentLengthConnectionCloseFlushingServlet
112
    </servlet-class>
113
  </servlet>
114
  <servlet-mapping>
115
    <servlet-name>NoContentLengthConnectionCloseFlushingServlet</servlet-name>
116
    <url-pattern>/noContentLengthConnectionCloseFlushingServlet/servlet</url-pattern>
117
  </servlet-mapping>
98
118
99
  <jsp-config>
119
  <jsp-config>
100
    <jsp-property-group>
120
    <jsp-property-group>
(-)test/org/apache/coyote/http11/TestAbstractHttp11Processor.java (-4 / +58 lines)
Lines 16-35 Link Here
16
 */
16
 */
17
package org.apache.coyote.http11;
17
package org.apache.coyote.http11;
18
18
19
import java.io.File;
20
import java.io.IOException;
21
22
import static org.junit.Assert.assertEquals;
19
import static org.junit.Assert.assertEquals;
23
import static org.junit.Assert.assertFalse;
20
import static org.junit.Assert.assertFalse;
24
import static org.junit.Assert.assertTrue;
21
import static org.junit.Assert.assertTrue;
25
22
26
import org.junit.Test;
23
import java.io.File;
24
import java.io.IOException;
27
25
28
import org.apache.catalina.Context;
26
import org.apache.catalina.Context;
29
import org.apache.catalina.startup.SimpleHttpClient;
27
import org.apache.catalina.startup.SimpleHttpClient;
30
import org.apache.catalina.startup.TesterServlet;
28
import org.apache.catalina.startup.TesterServlet;
31
import org.apache.catalina.startup.Tomcat;
29
import org.apache.catalina.startup.Tomcat;
32
import org.apache.catalina.startup.TomcatBaseTest;
30
import org.apache.catalina.startup.TomcatBaseTest;
31
import org.junit.Test;
33
32
34
public class TestAbstractHttp11Processor extends TomcatBaseTest {
33
public class TestAbstractHttp11Processor extends TomcatBaseTest {
35
34
Lines 238-244 Link Here
238
        assertTrue(client.isResponse200());
237
        assertTrue(client.isResponse200());
239
        assertEquals("OK", client.getResponseBody());
238
        assertEquals("OK", client.getResponseBody());
240
    }
239
    }
240
    
241
241
242
    @Test
243
    public void testChunking11NoContentLength() throws Exception {
244
        Tomcat tomcat = getTomcatInstance();
245
246
        // Use the normal Tomcat ROOT context
247
        File root = new File("test/webapp-3.0");
248
        tomcat.addWebapp("", root.getAbsolutePath());
249
250
        tomcat.start();
251
252
        String request =
253
            "GET /noContentLengthFlushingServlet/servlet HTTP/1.1" + SimpleHttpClient.CRLF +
254
            "Host: any" + SimpleHttpClient.CRLF +
255
            "Accept: text/event-stream" +
256
                    SimpleHttpClient.CRLF +
257
            SimpleHttpClient.CRLF;
258
259
        Client client = new Client(tomcat.getConnector().getLocalPort());
260
        client.setRequest(new String[] {request});
261
262
        client.connect();
263
        client.processRequest();
264
        assertTrue(client.isResponse200());
265
        assertTrue(client.getResponseHeaders().contains("Transfer-Encoding: chunked"));
266
    }
267
    
268
    @Test
269
    public void testNoChunking11NoContentLengthConnectionClose() throws Exception {
270
        Tomcat tomcat = getTomcatInstance();
271
        
272
        // Use the normal Tomcat ROOT context
273
        File root = new File("test/webapp-3.0");
274
        tomcat.addWebapp("", root.getAbsolutePath());
275
        
276
        tomcat.start();
277
        
278
        String request =
279
                "GET /noContentLengthConnectionCloseFlushingServlet/servlet HTTP/1.1" + SimpleHttpClient.CRLF +
280
                "Host: any" + SimpleHttpClient.CRLF +
281
                "Accept: text/event-stream" +
282
                SimpleHttpClient.CRLF +
283
                SimpleHttpClient.CRLF;
284
        
285
        Client client = new Client(tomcat.getConnector().getLocalPort());
286
        client.setRequest(new String[] {request});
287
        
288
        client.connect();
289
        client.processRequest();
290
        assertTrue(client.isResponse200());
291
        assertTrue(client.getResponseHeaders().contains("Connection: close"));
292
        assertFalse(client.getResponseHeaders().contains("Transfer-Encoding: chunked"));
293
        assertEquals("OK", client.getResponseBody());
294
    }
295
242
    private static final class Client extends SimpleHttpClient {
296
    private static final class Client extends SimpleHttpClient {
243
297
244
        public Client(int port) {
298
        public Client(int port) {
(-)test/org/apache/catalina/core/TestStandardContext.java (+36 lines)
Lines 440-446 Link Here
440
            }
440
            }
441
        }
441
        }
442
    }
442
    }
443
    
444
    // flushes with no content-length set
445
    // should result in chunking on HTTP 1.1
446
    public static final class NoContentLengthFlushingServlet extends HttpServlet {
443
447
448
        private static final long serialVersionUID = 1L;
449
        
450
        @Override
451
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
452
                throws ServletException, IOException {
453
            resp.setStatus(HttpServletResponse.SC_OK);
454
            resp.setContentType("text/plain");
455
            resp.getWriter().write("OK");
456
            resp.flushBuffer();
457
        }
458
        
459
    }
460
    
461
    // flushes with no content-length set but sets Connection: close header
462
    // should no result in chunking on HTTP 1.1
463
    public static final class NoContentLengthConnectionCloseFlushingServlet extends HttpServlet {
464
465
        private static final long serialVersionUID = 1L;
466
        
467
        @Override
468
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
469
                throws ServletException, IOException {
470
            resp.setStatus(HttpServletResponse.SC_OK);
471
            resp.setContentType("text/event-stream");
472
            resp.addHeader("Connection", "close");
473
            resp.flushBuffer();
474
            resp.getWriter().write("OK");
475
            resp.flushBuffer();
476
        }
477
        
478
    }
479
444
    /**
480
    /**
445
     * Test case for bug 49711: HttpServletRequest.getParts does not work
481
     * Test case for bug 49711: HttpServletRequest.getParts does not work
446
     * in a filter.
482
     * in a filter.
(-)java/org/apache/coyote/http11/AbstractHttp11Processor.java (-2 / +13 lines)
Lines 1131-1137 Link Here
1131
        MimeHeaders headers = request.getMimeHeaders();
1131
        MimeHeaders headers = request.getMimeHeaders();
1132
1132
1133
        // Check connection header
1133
        // Check connection header
1134
        MessageBytes connectionValueMB = headers.getValue("connection");
1134
        MessageBytes connectionValueMB = headers.getValue(Constants.CONNECTION);
1135
        if (connectionValueMB != null) {
1135
        if (connectionValueMB != null) {
1136
            ByteChunk connectionValueBC = connectionValueMB.getByteChunk();
1136
            ByteChunk connectionValueBC = connectionValueMB.getByteChunk();
1137
            if (findBytes(connectionValueBC, Constants.CLOSE_BYTES) != -1) {
1137
            if (findBytes(connectionValueBC, Constants.CLOSE_BYTES) != -1) {
Lines 1376-1382 Link Here
1376
                (outputFilters[Constants.IDENTITY_FILTER]);
1376
                (outputFilters[Constants.IDENTITY_FILTER]);
1377
            contentDelimitation = true;
1377
            contentDelimitation = true;
1378
        } else {
1378
        } else {
1379
            if (entityBody && http11) {
1379
            // if the response code supports an entity body
1380
            // and we're on HTTP 1.1 then we chunk
1381
            //  unless we have a Connection: close header
1382
            if (entityBody && http11 && !isConnectionClose(headers)) {
1380
                getOutputBuffer().addActiveFilter
1383
                getOutputBuffer().addActiveFilter
1381
                    (outputFilters[Constants.CHUNKED_FILTER]);
1384
                    (outputFilters[Constants.CHUNKED_FILTER]);
1382
                contentDelimitation = true;
1385
                contentDelimitation = true;
Lines 1446-1451 Link Here
1446
        getOutputBuffer().endHeaders();
1449
        getOutputBuffer().endHeaders();
1447
1450
1448
    }
1451
    }
1452
    
1453
    private boolean isConnectionClose(MimeHeaders headers) {
1454
        MessageBytes connection = headers.getValue(Constants.CONNECTION);
1455
        if (connection == null) {
1456
            return false;
1457
        }
1458
        return connection.equals(Constants.CLOSE);  
1459
    }
1449
1460
1450
    abstract boolean prepareSendfile(OutputFilter[] outputFilters);
1461
    abstract boolean prepareSendfile(OutputFilter[] outputFilters);
1451
1462

Return to bug 53169