001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.socket; 018 019import org.springframework.lang.Nullable; 020import org.springframework.util.Assert; 021import org.springframework.util.ObjectUtils; 022 023/** 024 * Represents a WebSocket close status code and reason. Status codes in the 1xxx range are 025 * pre-defined by the protocol. Optionally, a status code may be sent with a reason. 026 * 027 * <p>See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 028 * "Defined Status Codes"</a>. 029 * 030 * @author Rossen Stoyanchev 031 * @since 4.0 032 */ 033public final class CloseStatus { 034 035 /** 036 * "1000 indicates a normal closure, meaning that the purpose for which the connection 037 * was established has been fulfilled." 038 */ 039 public static final CloseStatus NORMAL = new CloseStatus(1000); 040 041 /** 042 * "1001 indicates that an endpoint is "going away", such as a server going down or a 043 * browser having navigated away from a page." 044 */ 045 public static final CloseStatus GOING_AWAY = new CloseStatus(1001); 046 047 /** 048 * "1002 indicates that an endpoint is terminating the connection due to a protocol 049 * error." 050 */ 051 public static final CloseStatus PROTOCOL_ERROR = new CloseStatus(1002); 052 053 /** 054 * "1003 indicates that an endpoint is terminating the connection because it has 055 * received a type of data it cannot accept (e.g., an endpoint that understands only 056 * text data MAY send this if it receives a binary message)." 057 */ 058 public static final CloseStatus NOT_ACCEPTABLE = new CloseStatus(1003); 059 060 // 10004: Reserved. 061 // The specific meaning might be defined in the future. 062 063 /** 064 * "1005 is a reserved value and MUST NOT be set as a status code in a Close control 065 * frame by an endpoint. It is designated for use in applications expecting a status 066 * code to indicate that no status code was actually present." 067 */ 068 public static final CloseStatus NO_STATUS_CODE = new CloseStatus(1005); 069 070 /** 071 * "1006 is a reserved value and MUST NOT be set as a status code in a Close control 072 * frame by an endpoint. It is designated for use in applications expecting a status 073 * code to indicate that the connection was closed abnormally, e.g., without sending 074 * or receiving a Close control frame." 075 */ 076 public static final CloseStatus NO_CLOSE_FRAME = new CloseStatus(1006); 077 078 /** 079 * "1007 indicates that an endpoint is terminating the connection because it has 080 * received data within a message that was not consistent with the type of the message 081 * (e.g., non-UTF-8 [RFC3629] data within a text message)." 082 */ 083 public static final CloseStatus BAD_DATA = new CloseStatus(1007); 084 085 /** 086 * "1008 indicates that an endpoint is terminating the connection because it has 087 * received a message that violates its policy. This is a generic status code that can 088 * be returned when there is no other more suitable status code (e.g., 1003 or 1009) 089 * or if there is a need to hide specific details about the policy." 090 */ 091 public static final CloseStatus POLICY_VIOLATION = new CloseStatus(1008); 092 093 /** 094 * "1009 indicates that an endpoint is terminating the connection because it has 095 * received a message that is too big for it to process." 096 */ 097 public static final CloseStatus TOO_BIG_TO_PROCESS = new CloseStatus(1009); 098 099 /** 100 * "1010 indicates that an endpoint (client) is terminating the connection because it 101 * has expected the server to negotiate one or more extension, but the server didn't 102 * return them in the response message of the WebSocket handshake. The list of 103 * extensions that are needed SHOULD appear in the /reason/ part of the Close frame. 104 * Note that this status code is not used by the server, because it can fail the 105 * WebSocket handshake instead." 106 */ 107 public static final CloseStatus REQUIRED_EXTENSION = new CloseStatus(1010); 108 109 /** 110 * "1011 indicates that a server is terminating the connection because it encountered 111 * an unexpected condition that prevented it from fulfilling the request." 112 */ 113 public static final CloseStatus SERVER_ERROR = new CloseStatus(1011); 114 115 /** 116 * "1012 indicates that the service is restarted. A client may reconnect, and if it 117 * chooses to do, should reconnect using a randomized delay of 5 - 30s." 118 */ 119 public static final CloseStatus SERVICE_RESTARTED = new CloseStatus(1012); 120 121 /** 122 * "1013 indicates that the service is experiencing overload. A client should only 123 * connect to a different IP (when there are multiple for the target) or reconnect to 124 * the same IP upon user action." 125 */ 126 public static final CloseStatus SERVICE_OVERLOAD = new CloseStatus(1013); 127 128 /** 129 * "1015 is a reserved value and MUST NOT be set as a status code in a Close control 130 * frame by an endpoint. It is designated for use in applications expecting a status 131 * code to indicate that the connection was closed due to a failure to perform a TLS 132 * handshake (e.g., the server certificate can't be verified)." 133 */ 134 public static final CloseStatus TLS_HANDSHAKE_FAILURE = new CloseStatus(1015); 135 136 /** 137 * A status code for use within the framework the indicate a session has 138 * become unreliable (e.g. timed out while sending a message) and extra 139 * care should be exercised, e.g. avoid sending any further data to the 140 * client that may be done during normal shutdown. 141 * @since 4.0.3 142 */ 143 public static final CloseStatus SESSION_NOT_RELIABLE = new CloseStatus(4500); 144 145 146 private final int code; 147 148 @Nullable 149 private final String reason; 150 151 152 /** 153 * Create a new {@link CloseStatus} instance. 154 * @param code the status code 155 */ 156 public CloseStatus(int code) { 157 this(code, null); 158 } 159 160 /** 161 * Create a new {@link CloseStatus} instance. 162 * @param code the status code 163 * @param reason the reason 164 */ 165 public CloseStatus(int code, @Nullable String reason) { 166 Assert.isTrue((code >= 1000 && code < 5000), "Invalid status code"); 167 this.code = code; 168 this.reason = reason; 169 } 170 171 172 /** 173 * Return the status code. 174 */ 175 public int getCode() { 176 return this.code; 177 } 178 179 /** 180 * Return the reason, or {@code null} if none. 181 */ 182 @Nullable 183 public String getReason() { 184 return this.reason; 185 } 186 187 /** 188 * Create a new {@link CloseStatus} from this one with the specified reason. 189 * @param reason the reason 190 * @return a new {@link CloseStatus} instance 191 */ 192 public CloseStatus withReason(String reason) { 193 Assert.hasText(reason, "Reason must not be empty"); 194 return new CloseStatus(this.code, reason); 195 } 196 197 198 public boolean equalsCode(CloseStatus other) { 199 return (this.code == other.code); 200 } 201 202 @Override 203 public boolean equals(@Nullable Object other) { 204 if (this == other) { 205 return true; 206 } 207 if (!(other instanceof CloseStatus)) { 208 return false; 209 } 210 CloseStatus otherStatus = (CloseStatus) other; 211 return (this.code == otherStatus.code && ObjectUtils.nullSafeEquals(this.reason, otherStatus.reason)); 212 } 213 214 @Override 215 public int hashCode() { 216 return this.code * 29 + ObjectUtils.nullSafeHashCode(this.reason); 217 } 218 219 @Override 220 public String toString() { 221 return "CloseStatus[code=" + this.code + ", reason=" + this.reason + "]"; 222 } 223 224}