File: Host.java

package info (click to toggle)
tomcat9 9.0.111-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 47,852 kB
  • sloc: java: 381,732; xml: 70,399; jsp: 4,682; sh: 1,336; perl: 324; makefile: 18; ansic: 14
file content (140 lines) | stat: -rw-r--r-- 4,225 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * 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.tomcat.util.http.parser;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;

public class Host {

    private Host() {
        // Utility class. Hide default constructor.
    }


    /**
     * Parse the given input as an HTTP Host header value.
     *
     * @param mb The host header value
     *
     * @return The position of ':' that separates the host from the port or -1 if it is not present
     *
     * @throws IllegalArgumentException If the host header value is not specification compliant
     */
    public static int parse(MessageBytes mb) {
        return parse(new MessageBytesReader(mb));
    }


    /**
     * Parse the given input as an HTTP Host header value.
     *
     * @param string The host header value
     *
     * @return The position of ':' that separates the host from the port or -1 if it is not present
     *
     * @throws IllegalArgumentException If the host header value is not specification compliant
     */
    public static int parse(String string) {
        return parse(new StringReader(string));
    }


    private static int parse(Reader reader) {
        try {
            reader.mark(1);
            int first = reader.read();
            reader.reset();
            if (HttpParser.isAlpha(first)) {
                return HttpParser.readHostDomainName(reader);
            } else if (HttpParser.isNumeric(first)) {
                return HttpParser.readHostIPv4(reader, false);
            } else if ('[' == first) {
                return HttpParser.readHostIPv6(reader);
            } else {
                // Invalid
                throw new IllegalArgumentException();
            }
        } catch (IOException ioe) {
            // Should never happen
            throw new IllegalArgumentException(ioe);
        }
    }


    private static class MessageBytesReader extends Reader {

        private final byte[] bytes;
        private final int end;
        private int pos;
        private int mark;

        MessageBytesReader(MessageBytes mb) {
            ByteChunk bc = mb.getByteChunk();
            bytes = bc.getBytes();
            pos = bc.getStart();
            end = bc.getEnd();
        }

        @Override
        public int read(char[] cbuf, int off, int len) throws IOException {
            for (int i = off; i < off + len; i++) {
                // Want output in range 0 to 255, not -128 to 127
                cbuf[i] = (char) (bytes[pos++] & 0xFF);
            }
            return len;
        }

        @Override
        public void close() throws IOException {
            // NO-OP
        }

        // Over-ridden methods to improve performance

        @Override
        public int read() throws IOException {
            if (pos < end) {
                // Want output in range 0 to 255, not -128 to 127
                return bytes[pos++] & 0xFF;
            } else {
                return -1;
            }
        }

        // Methods to support mark/reset

        @Override
        public boolean markSupported() {
            return true;
        }

        @Override
        public void mark(int readAheadLimit) throws IOException {
            mark = pos;
        }

        @Override
        public void reset() throws IOException {
            pos = mark;
        }
    }
}