All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fireflysource.net.http.common.model.HttpMethod Maven / Gradle / Ivy

There is a newer version: 5.0.2
Show newest version
package com.fireflysource.net.http.common.model;

import com.fireflysource.common.collection.trie.ArrayTernaryTrie;
import com.fireflysource.common.collection.trie.ArrayTrie;
import com.fireflysource.common.collection.trie.Trie;
import com.fireflysource.common.string.StringUtils;

import java.nio.ByteBuffer;

/**
 * @author Pengtao Qiu
 */
public enum HttpMethod {
    GET,
    POST,
    HEAD,
    PUT,
    PATCH,
    OPTIONS,
    DELETE,
    TRACE,
    CONNECT,
    MOVE,
    PROXY,
    PRI;

    public final static Trie CACHE = new ArrayTernaryTrie<>(false);
    public final static Trie INSENSITIVE_CACHE = new ArrayTrie<>();

    static {
        for (HttpMethod method : HttpMethod.values())
            CACHE.put(method.toString(), method);
    }

    static {
        for (HttpMethod method : HttpMethod.values())
            INSENSITIVE_CACHE.put(method.toString(), method);
    }

    private final String value;
    private final byte[] bytes;

    HttpMethod() {
        value = this.name();
        bytes = StringUtils.getUtf8Bytes(value);
    }

    public static HttpMethod from(String value) {
        return CACHE.get(value);
    }

    /**
     * Optimized lookup to find a method name and trailing space in a byte array.
     *
     * @param bytes    Array containing ISO-8859-1 characters
     * @param position The first valid index
     * @param limit    The first non valid index
     * @return A HttpMethod if a match or null if no easy match.
     */
    public static HttpMethod lookAheadGet(byte[] bytes, final int position, int limit) {
        int length = limit - position;
        if (length < 4)
            return null;
        switch (bytes[position]) {
            case 'G':
                if (bytes[position + 1] == 'E' && bytes[position + 2] == 'T' && bytes[position + 3] == ' ')
                    return GET;
                break;
            case 'P':
                if (bytes[position + 1] == 'O' && bytes[position + 2] == 'S' && bytes[position + 3] == 'T' && length >= 5 && bytes[position + 4] == ' ')
                    return POST;
                if (bytes[position + 1] == 'R' && bytes[position + 2] == 'O' && bytes[position + 3] == 'X' && length >= 6 && bytes[position + 4] == 'Y' && bytes[position + 5] == ' ')
                    return PROXY;
                if (bytes[position + 1] == 'U' && bytes[position + 2] == 'T' && bytes[position + 3] == ' ')
                    return PUT;
                if (bytes[position + 1] == 'R' && bytes[position + 2] == 'I' && bytes[position + 3] == ' ')
                    return PRI;
                break;
            case 'H':
                if (bytes[position + 1] == 'E' && bytes[position + 2] == 'A' && bytes[position + 3] == 'D' && length >= 5 && bytes[position + 4] == ' ')
                    return HEAD;
                break;
            case 'O':
                if (bytes[position + 1] == 'P' && bytes[position + 2] == 'T' && bytes[position + 3] == 'I' && length >= 8 &&
                        bytes[position + 4] == 'O' && bytes[position + 5] == 'N' && bytes[position + 6] == 'S' && bytes[position + 7] == ' ')
                    return OPTIONS;
                break;
            case 'D':
                if (bytes[position + 1] == 'E' && bytes[position + 2] == 'L' && bytes[position + 3] == 'E' && length >= 7 &&
                        bytes[position + 4] == 'T' && bytes[position + 5] == 'E' && bytes[position + 6] == ' ')
                    return DELETE;
                break;
            case 'T':
                if (bytes[position + 1] == 'R' && bytes[position + 2] == 'A' && bytes[position + 3] == 'C' && length >= 6 &&
                        bytes[position + 4] == 'E' && bytes[position + 5] == ' ')
                    return TRACE;
                break;
            case 'C':
                if (bytes[position + 1] == 'O' && bytes[position + 2] == 'N' && bytes[position + 3] == 'N' && length >= 8 &&
                        bytes[position + 4] == 'E' && bytes[position + 5] == 'C' && bytes[position + 6] == 'T' && bytes[position + 7] == ' ')
                    return CONNECT;
                break;
            case 'M':
                if (bytes[position + 1] == 'O' && bytes[position + 2] == 'V' && bytes[position + 3] == 'E' && length >= 5 && bytes[position + 4] == ' ')
                    return MOVE;
                break;

            default:
                break;
        }
        return null;
    }

    /**
     * Optimized lookup to find a method name and trailing space in a byte array.
     *
     * @param buffer buffer containing ISO-8859-1 characters, it is not modified.
     * @return A HttpMethod if a match or null if no easy match.
     */
    public static HttpMethod lookAheadGet(ByteBuffer buffer) {
        if (buffer.hasArray())
            return lookAheadGet(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.arrayOffset() + buffer.limit());

        int l = buffer.remaining();
        if (l >= 4) {
            HttpMethod m = CACHE.getBest(buffer, 0, l);
            if (m != null) {
                int ml = m.getValue().length();
                if (l > ml && buffer.get(buffer.position() + ml) == ' ')
                    return m;
            }
        }
        return null;
    }

    public boolean is(String value) {
        return this.value.equalsIgnoreCase(value);
    }

    public String getValue() {
        return value;
    }

    public byte[] getBytes() {
        return bytes;
    }

    @Override
    public String toString() {
        return value;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy