File: ConnectionSettingsLocal.java

package info (click to toggle)
tomcat11 11.0.11-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 47,028 kB
  • sloc: java: 366,244; xml: 55,681; jsp: 4,783; sh: 1,304; perl: 324; makefile: 25; ansic: 14
file content (108 lines) | stat: -rw-r--r-- 3,680 bytes parent folder | download | duplicates (2)
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
/*
 *  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.coyote.http2;

import java.util.Map;

/**
 * Represents the local connection settings i.e. the settings the client is expected to use when communicating with the
 * server. There will be a delay between calling a setter and the setting taking effect at the client. When a setter is
 * called, the new value is added to the set of pending settings. Once the ACK is received, the new value is moved to
 * the current settings. While waiting for the ACK, the getters will return the most lenient / generous / relaxed of the
 * current setting and the pending setting. This class does not validate the values passed to the setters. If an invalid
 * value is used the client will respond (almost certainly by closing the connection) as defined in the HTTP/2
 * specification.
 */
class ConnectionSettingsLocal extends ConnectionSettingsBase<IllegalArgumentException> {

    private static final String ENDPOINT_NAME = "Local(client->server)";

    private boolean sendInProgress = false;


    ConnectionSettingsLocal(String connectionId) {
        super(connectionId);
    }


    @Override
    final synchronized void set(Setting setting, Long value, boolean force) {
        checkSend();
        if (current.get(setting).longValue() == value.longValue()) {
            pending.remove(setting);
        } else {
            pending.put(setting, value);
            if (force) {
                current.put(setting, value);
            }
        }
    }


    final synchronized byte[] getSettingsFrameForPending() {
        checkSend();
        int payloadSize = pending.size() * 6;
        byte[] result = new byte[9 + payloadSize];

        ByteUtil.setThreeBytes(result, 0, payloadSize);
        result[3] = FrameType.SETTINGS.getIdByte();
        // No flags
        // Stream is zero
        // Payload
        int pos = 9;
        for (Map.Entry<Setting,Long> setting : pending.entrySet()) {
            ByteUtil.setTwoBytes(result, pos, setting.getKey().getId());
            pos += 2;
            ByteUtil.setFourBytes(result, pos, setting.getValue().longValue());
            pos += 4;
        }
        sendInProgress = true;
        return result;
    }


    final synchronized boolean ack() {
        if (sendInProgress) {
            sendInProgress = false;
            current.putAll(pending);
            pending.clear();
            return true;
        } else {
            return false;
        }
    }


    private void checkSend() {
        if (sendInProgress) {
            // Coding error. No need for i18n
            throw new IllegalStateException();
        }
    }


    @Override
    final void throwException(String msg, Http2Error error) throws IllegalArgumentException {
        throw new IllegalArgumentException(msg);
    }


    @Override
    final String getEndpointName() {
        return ENDPOINT_NAME;
    }
}