org.apache.sling.launchpad.webapp.integrationtest.RangeStreamingTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.sling.launchpad.webapp.integrationtest.RangeStreamingTest.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.sling.launchpad.webapp.integrationtest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.sling.commons.testing.integration.HttpTestBase;

/**
 * The <code>RangeStreamingTest</code> tests the Range request header support
 * for the StreamRendererServlet introduced with SLING-1814
 */
public class RangeStreamingTest extends HttpTestBase {

    private String rootUrl;

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        // Create the test nodes under a path that's specific to this class to
        // allow collisions
        final String path = "/" + getClass().getSimpleName() + "/" + System.currentTimeMillis();
        testClient.mkdirs(WEBDAV_BASE_URL, path);
        rootUrl = uploadTestScript(path, "rangestreaming.txt", "rangestreaming.txt");
    }

    @Override
    protected void tearDown() throws Exception {
        testClient.delete(rootUrl);
        super.tearDown();
    }

    public void test_full_range() throws IOException {
        GetMethod get = new GetMethod(rootUrl);
        int status = httpClient.executeMethod(get);
        assertEquals(200, status);
        assertEquals(79, get.getResponseContentLength());
    }

    public void test_wrong_ranges() throws IOException {
        GetMethod get = new GetMethod(rootUrl);
        get.setRequestHeader(new Header("Range", "unit 1-10"));
        int status = httpClient.executeMethod(get);
        assertEquals("Expect 416 for unsupported unit", 416, status);

        get = new GetMethod(rootUrl);
        get.setRequestHeader(new Header("Range", "bytes 5"));
        status = httpClient.executeMethod(get);
        assertEquals("Expect 416 for missing dash", 416, status);

        get = new GetMethod(rootUrl);
        get.setRequestHeader(new Header("Range", "bytes -x"));
        status = httpClient.executeMethod(get);
        assertEquals("Expect 416 for illegal negative number", 416, status);

        get = new GetMethod(rootUrl);
        get.setRequestHeader(new Header("Range", "bytes -x"));
        status = httpClient.executeMethod(get);
        assertEquals("Expect 416 for illegal negative number", 416, status);

        get = new GetMethod(rootUrl);
        get.setRequestHeader(new Header("Range", "bytes y-10"));
        status = httpClient.executeMethod(get);
        assertEquals("Expect 416 for unparseable number", 416, status);

        get = new GetMethod(rootUrl);
        get.setRequestHeader(new Header("Range", "bytes 10-5"));
        status = httpClient.executeMethod(get);
        assertEquals("Expect 416 for end < start", 416, status);
    }

    public void test_single_range() throws IOException {
        GetMethod get = new GetMethod(rootUrl);
        get.setRequestHeader(new Header("Range", "bytes 0-9"));
        int status = httpClient.executeMethod(get);
        assertEquals("Expect 206/PARTIAL CONTENT", 206, status);
        assertEquals(10, get.getResponseContentLength());
        assertEquals("The quick ", get.getResponseBodyAsString());

        get = new GetMethod(rootUrl);
        get.setRequestHeader(new Header("Range", "bytes -10"));
        status = httpClient.executeMethod(get);
        assertEquals("Expect 206/PARTIAL CONTENT", 206, status);
        assertEquals(10, get.getResponseContentLength());
        assertEquals("corpus sic", get.getResponseBodyAsString());

        get = new GetMethod(rootUrl);
        get.setRequestHeader(new Header("Range", "bytes 16-38"));
        status = httpClient.executeMethod(get);
        assertEquals("Expect 206/PARTIAL CONTENT", 206, status);
        assertEquals(23, get.getResponseContentLength());
        assertEquals("fox jumps over the lazy", get.getResponseBodyAsString());
    }

    public void test_multiple_ranges() throws IOException {
        GetMethod get = new GetMethod(rootUrl);
        get.setRequestHeader(new Header("Range", "bytes 0-9,-10"));
        int status = httpClient.executeMethod(get);
        assertEquals("Expect 206/PARTIAL CONTENT", 206, status);

        String contentType = get.getResponseHeader("Content-Type").getValue();
        assertTrue("Content Type must be multipart/byteranges", contentType.contains("multipart/byteranges"));
        String boundary = contentType.substring(contentType.indexOf("boundary=") + "boundary=".length());

        BufferedReader reader = new BufferedReader(new InputStreamReader(get.getResponseBodyAsStream()));

        String line = reader.readLine();
        while (!("--" + boundary).equals(line)) {
            line = reader.readLine();
        }

        assertEquals("Expected content to start with boundary", "--" + boundary, line);
        assertEntityHeaders(reader, "text/plain", "bytes 0-9/79");
        assertEquals("The quick ", reader.readLine());

        assertEquals("Expected content to start with boundary", "--" + boundary, reader.readLine());
        assertEntityHeaders(reader, "text/plain", "bytes 69-78/79");
        assertEquals("corpus sic", reader.readLine());

        char[] buf = new char[boundary.length() + 4];
        reader.read(buf);
        assertEquals("Expected content to start with boundary", "--" + boundary + "--", new String(buf));
    }

    private void assertEntityHeaders(final BufferedReader reader, final String expectedContentType,
            final String expectedRange) throws IOException {
        for (String line = reader.readLine(); line != null; line = reader.readLine()) {
            line = line.toLowerCase();
            if (line.startsWith("content-type:")) {
                assertTrue("Wrong content type: " + line + "; expected=" + expectedContentType,
                        line.contains(expectedContentType));
            } else if (line.startsWith("content-range:")) {
                assertTrue("Wrong content range: " + line + "; expected=" + expectedRange,
                        line.contains(expectedRange));
            } else if (line.length() == 0) {
                return;
            }
        }

        // exhausted reader without reaching end of headers
        fail("Unexpected end of data");
    }
}