Java Code Examples for org.apache.tomcat.util.buf.ByteChunk#getStart()

The following examples show how to use org.apache.tomcat.util.buf.ByteChunk#getStart() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: CoyoteAdapter.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
/**
 * Character conversion of the a US-ASCII MessageBytes.
 *
 * @param mb The MessageBytes instance containing the bytes that should be converted to chars
 */
protected void convertMB(MessageBytes mb) {

    // This is of course only meaningful for bytes
    if (mb.getType() != MessageBytes.T_BYTES) {
        return;
    }

    ByteChunk bc = mb.getByteChunk();
    CharChunk cc = mb.getCharChunk();
    int length = bc.getLength();
    cc.allocate(length, -1);

    // Default encoding: fast conversion
    byte[] bbuf = bc.getBuffer();
    char[] cbuf = cc.getBuffer();
    int start = bc.getStart();
    for (int i = 0; i < length; i++) {
        cbuf[i] = (char) (bbuf[i + start] & 0xff);
    }
    mb.setChars(cbuf, 0, length);

}
 
Example 2
Source File: Cookies.java    From tomcatsrc with Apache License 2.0 6 votes vote down vote up
/**
 * Unescapes any double quotes in the given cookie value.
 *
 * @param bc The cookie value to modify
 */
private static void unescapeDoubleQuotes(ByteChunk bc) {

    if (bc == null || bc.getLength() == 0 || bc.indexOf('"', 0) == -1) {
        return;
    }

    int src = bc.getStart();
    int end = bc.getEnd();
    int dest = src;
    byte[] buffer = bc.getBuffer();

    while (src < end) {
        if (buffer[src] == '\\' && src < end && buffer[src+1]  == '"') {
            src++;
        }
        buffer[dest] = buffer[src];
        dest ++;
        src ++;
    }
    bc.setEnd(dest);
}
 
Example 3
Source File: Tomcat90OutputBuffer.java    From armeria with Apache License 2.0 6 votes vote down vote up
public int doWrite(ByteChunk chunk) {
    final int start = chunk.getStart();
    final int end = chunk.getEnd();
    final int length = end - start;
    if (length == 0) {
        return 0;
    }

    // NB: We make a copy because Tomcat reuses the underlying byte array of 'chunk'.
    final byte[] content = Arrays.copyOfRange(chunk.getBuffer(), start, end);

    data.add(HttpData.wrap(content));

    bytesWritten += length;
    return length;
}
 
Example 4
Source File: CoyoteAdapter.java    From Tomcat7.0.67 with Apache License 2.0 6 votes vote down vote up
/**
 * Character conversion of the a US-ASCII MessageBytes.
 */
protected void convertMB(MessageBytes mb) {

    // This is of course only meaningful for bytes
    if (mb.getType() != MessageBytes.T_BYTES) {
        return;
    }

    ByteChunk bc = mb.getByteChunk();
    CharChunk cc = mb.getCharChunk();
    int length = bc.getLength();
    cc.allocate(length, -1);

    // Default encoding: fast conversion
    byte[] bbuf = bc.getBuffer();
    char[] cbuf = cc.getBuffer();
    int start = bc.getStart();
    for (int i = 0; i < length; i++) {
        cbuf[i] = (char) (bbuf[i + start] & 0xff);
    }
    mb.setChars(cbuf, 0, length);

}
 
Example 5
Source File: CoyoteAdapter.java    From tomcatsrc with Apache License 2.0 6 votes vote down vote up
/**
 * Character conversion of the a US-ASCII MessageBytes.
 */
protected void convertMB(MessageBytes mb) {

    // This is of course only meaningful for bytes
    if (mb.getType() != MessageBytes.T_BYTES) {
        return;
    }

    ByteChunk bc = mb.getByteChunk();
    CharChunk cc = mb.getCharChunk();
    int length = bc.getLength();
    cc.allocate(length, -1);

    // Default encoding: fast conversion
    byte[] bbuf = bc.getBuffer();
    char[] cbuf = cc.getBuffer();
    int start = bc.getStart();
    for (int i = 0; i < length; i++) {
        cbuf[i] = (char) (bbuf[i + start] & 0xff);
    }
    mb.setChars(cbuf, 0, length);

}
 
Example 6
Source File: InternalAprOutputBuffer.java    From Tomcat7.0.67 with Apache License 2.0 6 votes vote down vote up
/**
 * Write chunk.
 */
@Override
public int doWrite(ByteChunk chunk, Response res) 
    throws IOException {

    int len = chunk.getLength();
    int start = chunk.getStart();
    byte[] b = chunk.getBuffer();
    while (len > 0) {
        int thisTime = len;
        if (bbuf.position() == bbuf.capacity()) {
            flushBuffer();
        }
        if (thisTime > bbuf.capacity() - bbuf.position()) {
            thisTime = bbuf.capacity() - bbuf.position();
        }
        bbuf.put(b, start, thisTime);
        len = len - thisTime;
        start = start + thisTime;
    }
    byteCount += chunk.getLength();
    return chunk.getLength();
}
 
Example 7
Source File: Stream.java    From Tomcat8-Source-Read with MIT License 5 votes vote down vote up
private void prepareRequest() {
    MessageBytes hostValueMB = coyoteRequest.getMimeHeaders().getUniqueValue("host");
    if (hostValueMB == null) {
        throw new IllegalArgumentException();
    }
    // This processing expects bytes. Server push will have used a String
    // to trigger a conversion if required.
    hostValueMB.toBytes();
    ByteChunk valueBC = hostValueMB.getByteChunk();
    byte[] valueB = valueBC.getBytes();
    int valueL = valueBC.getLength();
    int valueS = valueBC.getStart();

    int colonPos = Host.parse(hostValueMB);
    if (colonPos != -1) {
        int port = 0;
        for (int i = colonPos + 1; i < valueL; i++) {
            char c = (char) valueB[i + valueS];
            if (c < '0' || c > '9') {
                throw new IllegalArgumentException();
            }
            port = port * 10 + c - '0';
        }
        coyoteRequest.setServerPort(port);

        // Only need to copy the host name up to the :
        valueL = colonPos;
    }

    // Extract the host name
    char[] hostNameC = new char[valueL];
    for (int i = 0; i < valueL; i++) {
        hostNameC[i] = (char) valueB[i + valueS];
    }
    coyoteRequest.serverName().setChars(hostNameC, 0, valueL);
}
 
Example 8
Source File: AbstractHttp11Processor.java    From tomcatsrc with Apache License 2.0 5 votes vote down vote up
/**
 * Specialized utility method: find a sequence of lower case bytes inside
 * a ByteChunk.
 */
protected int findBytes(ByteChunk bc, byte[] b) {

    byte first = b[0];
    byte[] buff = bc.getBuffer();
    int start = bc.getStart();
    int end = bc.getEnd();

    // Look for first char
    int srcEnd = b.length;

    for (int i = start; i <= (end - srcEnd); i++) {
        if (Ascii.toLower(buff[i]) != first) {
            continue;
        }
        // found first char, now look for a match
        int myPos = i+1;
        for (int srcPos = 1; srcPos < srcEnd;) {
            if (Ascii.toLower(buff[myPos++]) != b[srcPos++]) {
                break;
            }
            if (srcPos == srcEnd) {
                return i - start; // found it
            }
        }
    }
    return -1;
}
 
Example 9
Source File: InternalAprOutputBuffer.java    From tomcatsrc with Apache License 2.0 5 votes vote down vote up
/**
 * Write chunk.
 */
@Override
public int doWrite(ByteChunk chunk, Response res) throws IOException {
    try {
        int len = chunk.getLength();
        int start = chunk.getStart();
        byte[] b = chunk.getBuffer();
        while (len > 0) {
            int thisTime = len;
            if (bbuf.position() == bbuf.capacity()) {
                flushBuffer();
            }
            if (thisTime > bbuf.capacity() - bbuf.position()) {
                thisTime = bbuf.capacity() - bbuf.position();
            }
            bbuf.put(b, start, thisTime);
            len = len - thisTime;
            start = start + thisTime;
        }
        byteCount += chunk.getLength();
        return chunk.getLength();
    } catch (IOException ioe) {
        response.action(ActionCode.CLOSE_NOW, ioe);
        // Re-throw
        throw ioe;
    }
}
 
Example 10
Source File: InternalNioOutputBuffer.java    From Tomcat7.0.67 with Apache License 2.0 5 votes vote down vote up
/**
 * Write chunk.
 */
@Override
public int doWrite(ByteChunk chunk, Response res) 
    throws IOException {

    int len = chunk.getLength();
    int start = chunk.getStart();
    byte[] b = chunk.getBuffer();
    addToBB(b, start, len);
    byteCount += chunk.getLength();
    return chunk.getLength();
}
 
Example 11
Source File: AbstractHttp11Processor.java    From Tomcat7.0.67 with Apache License 2.0 5 votes vote down vote up
/**
 * Specialized utility method: find a sequence of lower case bytes inside
 * a ByteChunk.
 */
protected int findBytes(ByteChunk bc, byte[] b) {

    byte first = b[0];
    byte[] buff = bc.getBuffer();
    int start = bc.getStart();
    int end = bc.getEnd();

    // Look for first char
    int srcEnd = b.length;

    for (int i = start; i <= (end - srcEnd); i++) {
        if (Ascii.toLower(buff[i]) != first) {
            continue;
        }
        // found first char, now look for a match
        int myPos = i+1;
        for (int srcPos = 1; srcPos < srcEnd;) {
            if (Ascii.toLower(buff[myPos++]) != b[srcPos++]) {
                break;
            }
            if (srcPos == srcEnd) {
                return i - start; // found it
            }
        }
    }
    return -1;
}
 
Example 12
Source File: AbstractHttp11Processor.java    From Tomcat7.0.67 with Apache License 2.0 4 votes vote down vote up
/**
 * Parse host.
 */
protected void parseHost(MessageBytes valueMB) {

    if (valueMB == null || valueMB.isNull()) {
        // HTTP/1.0
        // If no host header, use the port info from the endpoint
        // The host will be obtained lazily from the socket if required
        // using ActionCode#REQ_LOCAL_NAME_ATTRIBUTE
        request.setServerPort(endpoint.getPort());
        return;
    }

    ByteChunk valueBC = valueMB.getByteChunk();
    byte[] valueB = valueBC.getBytes();
    int valueL = valueBC.getLength();
    int valueS = valueBC.getStart();
    int colonPos = -1;
    if (hostNameC.length < valueL) {
        hostNameC = new char[valueL];
    }

    boolean ipv6 = (valueB[valueS] == '[');
    boolean bracketClosed = false;
    for (int i = 0; i < valueL; i++) {
        char b = (char) valueB[i + valueS];
        hostNameC[i] = b;
        if (b == ']') {
            bracketClosed = true;
        } else if (b == ':') {
            if (!ipv6 || bracketClosed) {
                colonPos = i;
                break;
            }
        }
    }

    if (colonPos < 0) {
        if (!endpoint.isSSLEnabled()) {
            // 80 - Default HTTP port
            request.setServerPort(80);
        } else {
            // 443 - Default HTTPS port
            request.setServerPort(443);
        }
        request.serverName().setChars(hostNameC, 0, valueL);
    } else {
        request.serverName().setChars(hostNameC, 0, colonPos);

        int port = 0;
        int mult = 1;
        for (int i = valueL - 1; i > colonPos; i--) {
            int charValue = HexUtils.getDec(valueB[i + valueS]);
            if (charValue == -1 || charValue > 9) {
                // Invalid character
                // 400 - Bad request
                response.setStatus(400);
                setErrorState(ErrorState.CLOSE_CLEAN, null);
                break;
            }
            port = port + (charValue * mult);
            mult = 10 * mult;
        }
        request.setServerPort(port);
    }

}
 
Example 13
Source File: AbstractHttp11Processor.java    From tomcatsrc with Apache License 2.0 4 votes vote down vote up
/**
 * Parse host.
 */
protected void parseHost(MessageBytes valueMB) {

    if (valueMB == null || valueMB.isNull()) {
        // HTTP/1.0
        // If no host header, use the port info from the endpoint
        // The host will be obtained lazily from the socket if required
        // using ActionCode#REQ_LOCAL_NAME_ATTRIBUTE
        request.setServerPort(endpoint.getPort());
        return;
    }

    ByteChunk valueBC = valueMB.getByteChunk();
    byte[] valueB = valueBC.getBytes();
    int valueL = valueBC.getLength();
    int valueS = valueBC.getStart();
    int colonPos = -1;
    if (hostNameC.length < valueL) {
        hostNameC = new char[valueL];
    }

    boolean ipv6 = (valueB[valueS] == '[');
    boolean bracketClosed = false;
    for (int i = 0; i < valueL; i++) {
        char b = (char) valueB[i + valueS];
        hostNameC[i] = b;
        if (b == ']') {
            bracketClosed = true;
        } else if (b == ':') {
            if (!ipv6 || bracketClosed) {
                colonPos = i;
                break;
            }
        }
    }

    if (colonPos < 0) {
        if (!endpoint.isSSLEnabled()) {
            // 80 - Default HTTP port
            request.setServerPort(80);
        } else {
            // 443 - Default HTTPS port
            request.setServerPort(443);
        }
        request.serverName().setChars(hostNameC, 0, valueL);
    } else {
        request.serverName().setChars(hostNameC, 0, colonPos);

        int port = 0;
        int mult = 1;
        for (int i = valueL - 1; i > colonPos; i--) {
            int charValue = HexUtils.getDec(valueB[i + valueS]);
            if (charValue == -1 || charValue > 9) {
                // Invalid character
                // 400 - Bad request
                response.setStatus(400);
                setErrorState(ErrorState.CLOSE_CLEAN, null);
                break;
            }
            port = port + (charValue * mult);
            mult = 10 * mult;
        }
        request.setServerPort(port);
    }

}
 
Example 14
Source File: Base64.java    From Tomcat7.0.67 with Apache License 2.0 4 votes vote down vote up
/**
 * Decodes Base64 data into octets
 *
 * @param base64DataBC Byte array containing Base64 data
 * @param decodedDataBC The decoded data bytes
 */
public static void decode( ByteChunk base64DataBC, ByteChunk decodedDataBC)
{
    int start = base64DataBC.getStart();
    int end = base64DataBC.getEnd();
    byte[] base64Data = base64DataBC.getBuffer();
    
    decodedDataBC.recycle();
    
    // handle the edge case, so we don't have to worry about it later
    if(end - start == 0) { return; }

    int      numberQuadruple    = (end - start)/FOURBYTE;
    byte     b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;

    // Throw away anything not in base64Data

    int encodedIndex = 0;
    int dataIndex = start;
    byte[] decodedData = null;
    
    {
        // this sizes the output array properly - rlw
        int lastData = end - start;
        // ignore the '=' padding
        while (base64Data[start+lastData-1] == PAD)
        {
            if (--lastData == 0)
            {
                return;
            }
        }
        decodedDataBC.allocate(lastData - numberQuadruple, -1);
        decodedDataBC.setEnd(lastData - numberQuadruple);
        decodedData = decodedDataBC.getBuffer();
    }

    for (int i = 0; i < numberQuadruple; i++)
    {
        dataIndex = start + i * 4;
        marker0   = base64Data[dataIndex + 2];
        marker1   = base64Data[dataIndex + 3];

        b1 = base64Alphabet[base64Data[dataIndex]];
        b2 = base64Alphabet[base64Data[dataIndex +1]];

        if (marker0 != PAD && marker1 != PAD)
        {
            //No PAD e.g 3cQl
            b3 = base64Alphabet[ marker0 ];
            b4 = base64Alphabet[ marker1 ];

            decodedData[encodedIndex]   = (byte) ((  b1 <<2 | b2>>4 ) & 0xff);
            decodedData[encodedIndex + 1] =
                (byte) ((((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ) & 0xff);
            decodedData[encodedIndex + 2] = (byte) (( b3<<6 | b4 ) & 0xff);
        }
        else if (marker0 == PAD)
        {
            //Two PAD e.g. 3c[Pad][Pad]
            decodedData[encodedIndex]   = (byte) ((  b1 <<2 | b2>>4 ) & 0xff);
        }
        else if (marker1 == PAD)
        {
            //One PAD e.g. 3cQ[Pad]
            b3 = base64Alphabet[ marker0 ];

            decodedData[encodedIndex]   = (byte) ((  b1 <<2 | b2>>4 ) & 0xff);
            decodedData[encodedIndex + 1] =
                (byte) ((((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ) & 0xff);
        }
        encodedIndex += 3;
    }
}
 
Example 15
Source File: CoyoteAdapter.java    From tomcatsrc with Apache License 2.0 4 votes vote down vote up
/**
 * Extract the path parameters from the request. This assumes parameters are
 * of the form /path;name=value;name2=value2/ etc. Currently only really
 * interested in the session ID that will be in this form. Other parameters
 * can safely be ignored.
 *
 * @param req
 * @param request
 */
protected void parsePathParameters(org.apache.coyote.Request req,
        Request request) {

    // Process in bytes (this is default format so this is normally a NO-OP
    req.decodedURI().toBytes();

    ByteChunk uriBC = req.decodedURI().getByteChunk();
    int semicolon = uriBC.indexOf(';', 0);

    // What encoding to use? Some platforms, eg z/os, use a default
    // encoding that doesn't give the expected result so be explicit
    String enc = connector.getURIEncoding();
    if (enc == null) {
        enc = "ISO-8859-1";
    }
    Charset charset = null;
    try {
        charset = B2CConverter.getCharset(enc);
    } catch (UnsupportedEncodingException e1) {
        log.warn(sm.getString("coyoteAdapter.parsePathParam",
                enc));
    }

    if (log.isDebugEnabled()) {
        log.debug(sm.getString("coyoteAdapter.debug", "uriBC",
                uriBC.toString()));
        log.debug(sm.getString("coyoteAdapter.debug", "semicolon",
                String.valueOf(semicolon)));
        log.debug(sm.getString("coyoteAdapter.debug", "enc", enc));
    }

    while (semicolon > -1) {
        // Parse path param, and extract it from the decoded request URI
        int start = uriBC.getStart();
        int end = uriBC.getEnd();

        int pathParamStart = semicolon + 1;
        int pathParamEnd = ByteChunk.findBytes(uriBC.getBuffer(),
                start + pathParamStart, end,
                new byte[] {';', '/'});

        String pv = null;

        if (pathParamEnd >= 0) {
            if (charset != null) {
                pv = new String(uriBC.getBuffer(), start + pathParamStart,
                            pathParamEnd - pathParamStart, charset);
            }
            // Extract path param from decoded request URI
            byte[] buf = uriBC.getBuffer();
            for (int i = 0; i < end - start - pathParamEnd; i++) {
                buf[start + semicolon + i]
                    = buf[start + i + pathParamEnd];
            }
            uriBC.setBytes(buf, start,
                    end - start - pathParamEnd + semicolon);
        } else {
            if (charset != null) {
                pv = new String(uriBC.getBuffer(), start + pathParamStart,
                            (end - start) - pathParamStart, charset);
            }
            uriBC.setEnd(start + semicolon);
        }

        if (log.isDebugEnabled()) {
            log.debug(sm.getString("coyoteAdapter.debug", "pathParamStart",
                    String.valueOf(pathParamStart)));
            log.debug(sm.getString("coyoteAdapter.debug", "pathParamEnd",
                    String.valueOf(pathParamEnd)));
            log.debug(sm.getString("coyoteAdapter.debug", "pv", pv));
        }

        if (pv != null) {
            int equals = pv.indexOf('=');
            if (equals > -1) {
                String name = pv.substring(0, equals);
                String value = pv.substring(equals + 1);
                request.addPathParameter(name, value);
                if (log.isDebugEnabled()) {
                    log.debug(sm.getString("coyoteAdapter.debug", "equals",
                            String.valueOf(equals)));
                    log.debug(sm.getString("coyoteAdapter.debug", "name",
                            name));
                    log.debug(sm.getString("coyoteAdapter.debug", "value",
                            value));
                }
            }
        }

        semicolon = uriBC.indexOf(';', semicolon);
    }
}
 
Example 16
Source File: Base64.java    From Tomcat7.0.67 with Apache License 2.0 4 votes vote down vote up
/**
 * Decodes Base64 data into octets
 *
 * @param base64DataBC Byte array containing Base64 data
 * @param decodedDataCC The decoded data chars
 */
public static void decode( ByteChunk base64DataBC, CharChunk decodedDataCC)
{
    int start = base64DataBC.getStart();
    int end = base64DataBC.getEnd();
    byte[] base64Data = base64DataBC.getBuffer();
    
    decodedDataCC.recycle();
    
    // handle the edge case, so we don't have to worry about it later
    if(end - start == 0) { return; }

    int      numberQuadruple    = (end - start)/FOURBYTE;
    byte     b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;

    // Throw away anything not in base64Data

    int encodedIndex = 0;
    int dataIndex = start;
    char[] decodedData = null;
    
    {
        // this sizes the output array properly - rlw
        int lastData = end - start;
        // ignore the '=' padding
        while (base64Data[start+lastData-1] == PAD)
        {
            if (--lastData == 0)
            {
                return;
            }
        }
        decodedDataCC.allocate(lastData - numberQuadruple, -1);
        decodedDataCC.setEnd(lastData - numberQuadruple);
        decodedData = decodedDataCC.getBuffer();
    }

    for (int i = 0; i < numberQuadruple; i++)
    {
        dataIndex = start + i * 4;
        marker0   = base64Data[dataIndex + 2];
        marker1   = base64Data[dataIndex + 3];

        b1 = base64Alphabet[base64Data[dataIndex]];
        b2 = base64Alphabet[base64Data[dataIndex +1]];

        if (marker0 != PAD && marker1 != PAD)
        {
            //No PAD e.g 3cQl
            b3 = base64Alphabet[ marker0 ];
            b4 = base64Alphabet[ marker1 ];

            decodedData[encodedIndex]   = (char) ((  b1 <<2 | b2>>4 ) & 0xff);
            decodedData[encodedIndex + 1] =
                (char) ((((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ) & 0xff);
            decodedData[encodedIndex + 2] = (char) (( b3<<6 | b4 ) & 0xff);
        }
        else if (marker0 == PAD)
        {
            //Two PAD e.g. 3c[Pad][Pad]
            decodedData[encodedIndex]   = (char) ((  b1 <<2 | b2>>4 ) & 0xff);
        }
        else if (marker1 == PAD)
        {
            //One PAD e.g. 3cQ[Pad]
            b3 = base64Alphabet[ marker0 ];

            decodedData[encodedIndex]   = (char) ((  b1 <<2 | b2>>4 ) & 0xff);
            decodedData[encodedIndex + 1] =
                (char) ((((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ) & 0xff);
        }
        encodedIndex += 3;
    }
}
 
Example 17
Source File: Base64.java    From tomcatsrc with Apache License 2.0 4 votes vote down vote up
/**
 * Decodes Base64 data into octets
 *
 * @param base64DataBC Byte array containing Base64 data
 * @param decodedDataCC The decoded data chars
 */
public static void decode( ByteChunk base64DataBC, CharChunk decodedDataCC)
{
    int start = base64DataBC.getStart();
    int end = base64DataBC.getEnd();
    byte[] base64Data = base64DataBC.getBuffer();
    
    decodedDataCC.recycle();
    
    // handle the edge case, so we don't have to worry about it later
    if(end - start == 0) { return; }

    int      numberQuadruple    = (end - start)/FOURBYTE;
    byte     b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;

    // Throw away anything not in base64Data

    int encodedIndex = 0;
    int dataIndex = start;
    char[] decodedData = null;
    
    {
        // this sizes the output array properly - rlw
        int lastData = end - start;
        // ignore the '=' padding
        while (base64Data[start+lastData-1] == PAD)
        {
            if (--lastData == 0)
            {
                return;
            }
        }
        decodedDataCC.allocate(lastData - numberQuadruple, -1);
        decodedDataCC.setEnd(lastData - numberQuadruple);
        decodedData = decodedDataCC.getBuffer();
    }

    for (int i = 0; i < numberQuadruple; i++)
    {
        dataIndex = start + i * 4;
        marker0   = base64Data[dataIndex + 2];
        marker1   = base64Data[dataIndex + 3];

        b1 = base64Alphabet[base64Data[dataIndex]];
        b2 = base64Alphabet[base64Data[dataIndex +1]];

        if (marker0 != PAD && marker1 != PAD)
        {
            //No PAD e.g 3cQl
            b3 = base64Alphabet[ marker0 ];
            b4 = base64Alphabet[ marker1 ];

            decodedData[encodedIndex]   = (char) ((  b1 <<2 | b2>>4 ) & 0xff);
            decodedData[encodedIndex + 1] =
                (char) ((((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ) & 0xff);
            decodedData[encodedIndex + 2] = (char) (( b3<<6 | b4 ) & 0xff);
        }
        else if (marker0 == PAD)
        {
            //Two PAD e.g. 3c[Pad][Pad]
            decodedData[encodedIndex]   = (char) ((  b1 <<2 | b2>>4 ) & 0xff);
        }
        else if (marker1 == PAD)
        {
            //One PAD e.g. 3cQ[Pad]
            b3 = base64Alphabet[ marker0 ];

            decodedData[encodedIndex]   = (char) ((  b1 <<2 | b2>>4 ) & 0xff);
            decodedData[encodedIndex + 1] =
                (char) ((((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ) & 0xff);
        }
        encodedIndex += 3;
    }
}
 
Example 18
Source File: Base64.java    From tomcatsrc with Apache License 2.0 4 votes vote down vote up
/**
 * Decodes Base64 data into octets
 *
 * @param base64DataBC Byte array containing Base64 data
 * @param decodedDataBC The decoded data bytes
 */
public static void decode( ByteChunk base64DataBC, ByteChunk decodedDataBC)
{
    int start = base64DataBC.getStart();
    int end = base64DataBC.getEnd();
    byte[] base64Data = base64DataBC.getBuffer();
    
    decodedDataBC.recycle();
    
    // handle the edge case, so we don't have to worry about it later
    if(end - start == 0) { return; }

    int      numberQuadruple    = (end - start)/FOURBYTE;
    byte     b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;

    // Throw away anything not in base64Data

    int encodedIndex = 0;
    int dataIndex = start;
    byte[] decodedData = null;
    
    {
        // this sizes the output array properly - rlw
        int lastData = end - start;
        // ignore the '=' padding
        while (base64Data[start+lastData-1] == PAD)
        {
            if (--lastData == 0)
            {
                return;
            }
        }
        decodedDataBC.allocate(lastData - numberQuadruple, -1);
        decodedDataBC.setEnd(lastData - numberQuadruple);
        decodedData = decodedDataBC.getBuffer();
    }

    for (int i = 0; i < numberQuadruple; i++)
    {
        dataIndex = start + i * 4;
        marker0   = base64Data[dataIndex + 2];
        marker1   = base64Data[dataIndex + 3];

        b1 = base64Alphabet[base64Data[dataIndex]];
        b2 = base64Alphabet[base64Data[dataIndex +1]];

        if (marker0 != PAD && marker1 != PAD)
        {
            //No PAD e.g 3cQl
            b3 = base64Alphabet[ marker0 ];
            b4 = base64Alphabet[ marker1 ];

            decodedData[encodedIndex]   = (byte) ((  b1 <<2 | b2>>4 ) & 0xff);
            decodedData[encodedIndex + 1] =
                (byte) ((((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ) & 0xff);
            decodedData[encodedIndex + 2] = (byte) (( b3<<6 | b4 ) & 0xff);
        }
        else if (marker0 == PAD)
        {
            //Two PAD e.g. 3c[Pad][Pad]
            decodedData[encodedIndex]   = (byte) ((  b1 <<2 | b2>>4 ) & 0xff);
        }
        else if (marker1 == PAD)
        {
            //One PAD e.g. 3cQ[Pad]
            b3 = base64Alphabet[ marker0 ];

            decodedData[encodedIndex]   = (byte) ((  b1 <<2 | b2>>4 ) & 0xff);
            decodedData[encodedIndex + 1] =
                (byte) ((((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ) & 0xff);
        }
        encodedIndex += 3;
    }
}
 
Example 19
Source File: AbstractAjpProcessor.java    From tomcatsrc with Apache License 2.0 4 votes vote down vote up
/**
 * Parse host.
 */
protected void parseHost(MessageBytes valueMB) {

    if (valueMB == null || valueMB.isNull()) {
        // HTTP/1.0
        request.setServerPort(request.getLocalPort());
        try {
            request.serverName().duplicate(request.localName());
        } catch (IOException e) {
            response.setStatus(400);
            setErrorState(ErrorState.CLOSE_CLEAN, e);
        }
        return;
    }

    ByteChunk valueBC = valueMB.getByteChunk();
    byte[] valueB = valueBC.getBytes();
    int valueL = valueBC.getLength();
    int valueS = valueBC.getStart();
    int colonPos = -1;
    if (hostNameC.length < valueL) {
        hostNameC = new char[valueL];
    }

    boolean ipv6 = (valueB[valueS] == '[');
    boolean bracketClosed = false;
    for (int i = 0; i < valueL; i++) {
        char b = (char) valueB[i + valueS];
        hostNameC[i] = b;
        if (b == ']') {
            bracketClosed = true;
        } else if (b == ':') {
            if (!ipv6 || bracketClosed) {
                colonPos = i;
                break;
            }
        }
    }

    if (colonPos < 0) {
        if (request.scheme().equalsIgnoreCase("https")) {
            // 443 - Default HTTPS port
            request.setServerPort(443);
        } else {
            // 80 - Default HTTTP port
            request.setServerPort(80);
        }
        request.serverName().setChars(hostNameC, 0, valueL);
    } else {

        request.serverName().setChars(hostNameC, 0, colonPos);

        int port = 0;
        int mult = 1;
        for (int i = valueL - 1; i > colonPos; i--) {
            int charValue = HexUtils.getDec(valueB[i + valueS]);
            if (charValue == -1) {
                // Invalid character
                // 400 - Bad request
                response.setStatus(400);
                setErrorState(ErrorState.CLOSE_CLEAN, null);
                break;
            }
            port = port + (charValue * mult);
            mult = 10 * mult;
        }
        request.setServerPort(port);
    }
}
 
Example 20
Source File: CoyoteAdapter.java    From Tomcat7.0.67 with Apache License 2.0 4 votes vote down vote up
/**
 * Extract the path parameters from the request. This assumes parameters are
 * of the form /path;name=value;name2=value2/ etc. Currently only really
 * interested in the session ID that will be in this form. Other parameters
 * can safely be ignored.
 *
 * @param req
 * @param request
 */
protected void parsePathParameters(org.apache.coyote.Request req,
        Request request) {

    // Process in bytes (this is default format so this is normally a NO-OP
    req.decodedURI().toBytes();

    ByteChunk uriBC = req.decodedURI().getByteChunk();
    int semicolon = uriBC.indexOf(';', 0);

    // What encoding to use? Some platforms, eg z/os, use a default
    // encoding that doesn't give the expected result so be explicit
    String enc = connector.getURIEncoding();
    if (enc == null) {
        enc = "ISO-8859-1";
    }
    Charset charset = null;
    try {
        charset = B2CConverter.getCharset(enc);
    } catch (UnsupportedEncodingException e1) {
        log.warn(sm.getString("coyoteAdapter.parsePathParam",
                enc));
    }

    if (log.isDebugEnabled()) {
        log.debug(sm.getString("coyoteAdapter.debug", "uriBC",
                uriBC.toString()));
        log.debug(sm.getString("coyoteAdapter.debug", "semicolon",
                String.valueOf(semicolon)));
        log.debug(sm.getString("coyoteAdapter.debug", "enc", enc));
    }

    while (semicolon > -1) {
        // Parse path param, and extract it from the decoded request URI
        int start = uriBC.getStart();
        int end = uriBC.getEnd();

        int pathParamStart = semicolon + 1;
        int pathParamEnd = ByteChunk.findBytes(uriBC.getBuffer(),
                start + pathParamStart, end,
                new byte[] {';', '/'});

        String pv = null;

        if (pathParamEnd >= 0) {
            if (charset != null) {
                pv = new String(uriBC.getBuffer(), start + pathParamStart,
                            pathParamEnd - pathParamStart, charset);
            }
            // Extract path param from decoded request URI
            byte[] buf = uriBC.getBuffer();
            for (int i = 0; i < end - start - pathParamEnd; i++) {
                buf[start + semicolon + i]
                    = buf[start + i + pathParamEnd];
            }
            uriBC.setBytes(buf, start,
                    end - start - pathParamEnd + semicolon);
        } else {
            if (charset != null) {
                pv = new String(uriBC.getBuffer(), start + pathParamStart,
                            (end - start) - pathParamStart, charset);
            }
            uriBC.setEnd(start + semicolon);
        }

        if (log.isDebugEnabled()) {
            log.debug(sm.getString("coyoteAdapter.debug", "pathParamStart",
                    String.valueOf(pathParamStart)));
            log.debug(sm.getString("coyoteAdapter.debug", "pathParamEnd",
                    String.valueOf(pathParamEnd)));
            log.debug(sm.getString("coyoteAdapter.debug", "pv", pv));
        }

        if (pv != null) {
            int equals = pv.indexOf('=');
            if (equals > -1) {
                String name = pv.substring(0, equals);
                String value = pv.substring(equals + 1);
                request.addPathParameter(name, value);
                if (log.isDebugEnabled()) {
                    log.debug(sm.getString("coyoteAdapter.debug", "equals",
                            String.valueOf(equals)));
                    log.debug(sm.getString("coyoteAdapter.debug", "name",
                            name));
                    log.debug(sm.getString("coyoteAdapter.debug", "value",
                            value));
                }
            }
        }

        semicolon = uriBC.indexOf(';', semicolon);
    }
}