Package com.bradmcevoy.http.http11

Source Code of com.bradmcevoy.http.http11.PutHelper

package com.bradmcevoy.http.http11;

import com.bradmcevoy.common.ContentTypeUtils;
import com.bradmcevoy.common.Path;
import com.bradmcevoy.http.CollectionResource;
import com.bradmcevoy.http.GetableResource;
import com.bradmcevoy.http.HttpManager;
import com.bradmcevoy.http.Range;
import com.bradmcevoy.http.Request;
import com.bradmcevoy.http.Resource;
import com.bradmcevoy.http.exceptions.BadRequestException;
import com.bradmcevoy.http.exceptions.ConflictException;
import com.bradmcevoy.http.exceptions.NotAuthorizedException;
import java.io.IOException;
import java.io.OutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* A collection of utility methods for PutHandler
*
*/
public class PutHelper {

    private static final Logger log = LoggerFactory.getLogger( PutHelper.class );

    /**
     * Largly copied from tomcat
     *
     * See the spec
     * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
     *
     * @param r
     * @param request
     * @return
     * @throws IOException
     * @throws BadRequestException - if the range header is invalid
     */
    public Range parseContentRange(Resource r, Request request) throws IOException, BadRequestException {
        // Retrieving the content-range header (if any is specified
        String rangeHeader = request.getContentRangeHeader();
        if (rangeHeader == null) {
            return null;
        }

        // bytes is the only range unit supported
        if (!rangeHeader.startsWith("bytes")) {
            log.warn("Invalid range header, does not start with 'bytes': " + rangeHeader);
            throw new BadRequestException(r);
        }

        rangeHeader = rangeHeader.substring(6).trim();

        int dashPos = rangeHeader.indexOf('-');
        int slashPos = rangeHeader.indexOf('/');

        if (dashPos == -1) {
            log.warn("Invalid range header, dash not found: " + rangeHeader);
            throw new BadRequestException(r);
        }

        if (slashPos == -1) {
            log.warn("Invalid range header, slash not found: " + rangeHeader);
            throw new BadRequestException(r);
        }


        String s;

        long start;
        s = rangeHeader.substring(0, dashPos);
        try {
            start = Long.parseLong(s);
        } catch (NumberFormatException e) {
            log.warn("Invalid range header, start is not a valid number: " + s + " Raw header:" + rangeHeader);
            throw new BadRequestException(r);
        }

        long finish;
        s = rangeHeader.substring(dashPos + 1, slashPos);
        try {
            finish = Long.parseLong(s);
        } catch (NumberFormatException e) {
            log.warn("Invalid range header, finish is not a valid number: " + s + " Raw header:" + rangeHeader);
            throw new BadRequestException(r);
        }

        Range range = new Range(start, finish);


        if (!validate(range)) {
            throw new BadRequestException(r);
        }

        return range;
    }

    private boolean validate(Range r) {
        if( r.getStart() < 0 ) {
            log.warn("invalid range, start is negative");
            return false;
        } else if( r.getFinish() < 0 ) {
            log.warn("invalid range, finish is negative");
            return false;
        } else if( r.getStart() > r.getFinish()) {
            log.warn("invalid range, start is greater then finish");
            return false;
        } else {
            return true;
        }
    }


    public Long getContentLength( Request request ) throws BadRequestException {
        Long l = request.getContentLengthHeader();
        if( l == null ) {
            String s = request.getRequestHeader( Request.Header.X_EXPECTED_ENTITY_LENGTH );
            if( s != null && s.length() > 0 ) {
                log.debug( "no content-length given, but founhd non-standard length header: " + s );
                try {
                    l = Long.parseLong( s );
                } catch( NumberFormatException e ) {
                    throw new BadRequestException( null, "invalid length for header: " + Request.Header.X_EXPECTED_ENTITY_LENGTH.code + ". value is: " + s );
                }
            }
        }
        return l;
    }

    /**
     * returns a textual representation of the list of content types for the
     * new resource. This will be the content type header if there is one,
     * otherwise it will be determined by the file name
     *
     * @param request
     * @param newName
     * @return
     */
    public String findContentTypes( Request request, String newName ) {
        String ct = request.getContentTypeHeader();
        if( ct != null ) return ct;

        return ContentTypeUtils.findContentTypes( newName );
    }


    public CollectionResource findNearestParent( HttpManager manager, String host, Path path ) throws NotAuthorizedException, ConflictException {
        if( path == null ) return null;

        Resource thisResource = manager.getResourceFactory().getResource( host, path.toString() );
        if( thisResource != null ) {
            if( thisResource instanceof CollectionResource ) {
                return (CollectionResource) thisResource;
            } else {
                log.warn( "parent is not a collection: " + path );
                return null;
            }
        }

        CollectionResource parent = findNearestParent( manager, host, path.getParent() );
        return parent;
    }

    /**
     * Copy the current content of the resource to the outputstream, except
     * writing the new partial update for the given range.
     *
     *
     * @param replacee - the resource to get the content for and to update
     * @param request
     * @param range
     * @param tempOut
     */
    public void applyPartialUpdate(GetableResource replacee, Request request, Range range, OutputStream tempOut) throws NotAuthorizedException, BadRequestException {
        try {
            replacee.sendContent(tempOut, null, null, null);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }
}
TOP

Related Classes of com.bradmcevoy.http.http11.PutHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.