1 module hunt.http.codec.websocket.model.StatusCode;
2 
3 /**
4  * The <a href="https://tools.ietf.org/html/rfc6455#section-7.4">RFC 6455 specified status codes</a> and <a
5  * href="https://www.iana.org/assignments/websocket/websocket.xml#close-code-number-rules">IANA: WebSocket Close Code Number Registry</a>
6  */
7 struct StatusCode {
8     /**
9      * 1000 indicates a normal closure, meaning that the purpose for which the connection was established has been fulfilled.
10      * <p>
11      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
12      */
13     enum int NORMAL = 1000;
14 
15     /**
16      * 1001 indicates that an endpoint is "going away", such as a server going down or a browser having navigated away from a page.
17      * <p>
18      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
19      */
20     enum int SHUTDOWN = 1001;
21 
22     /**
23      * 1002 indicates that an endpoint is terminating the connection due to a protocol error.
24      * <p>
25      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
26      */
27     enum int PROTOCOL = 1002;
28 
29     /**
30      * 1003 indicates that an endpoint is terminating the connection because it has received a type of data it cannot accept (e.g., an endpoint that understands
31      * only text data MAY send this if it receives a binary message).
32      * <p>
33      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
34      */
35     enum int BAD_DATA = 1003;
36 
37     /**
38      * Reserved. The specific meaning might be defined in the future.
39      * <p>
40      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
41      */
42     enum int UNDEFINED = 1004;
43 
44     /**
45      * 1005 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting
46      * a status code to indicate that no status code was actually present.
47      * <p>
48      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
49      */
50     enum int NO_CODE = 1005;
51 
52     /**
53      * 1006 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting
54      * a status code to indicate that the connection was closed abnormally, e.g., without sending or receiving a Close control frame.
55      * <p>
56      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
57      */
58     enum int NO_CLOSE = 1006;
59 
60     /**
61      * Abnormal Close is a synonym for {@link #NO_CLOSE}, used to indicate a close
62      * condition where no close frame was processed from the remote side.
63      */
64     enum int ABNORMAL = NO_CLOSE;
65 
66     /**
67      * 1007 indicates that an endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the
68      * message (e.g., non-UTF-8 [<a href="https://tools.ietf.org/html/rfc3629">RFC3629</a>] data within a text message).
69      * <p>
70      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
71      */
72     enum int BAD_PAYLOAD = 1007;
73 
74     /**
75      * 1008 indicates that an endpoint is terminating the connection because it has received a message that violates its policy. This is a generic status code
76      * that can be returned when there is no other more suitable status code (e.g., 1003 or 1009) or if there is a need to hide specific details about the
77      * policy.
78      * <p>
79      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
80      */
81     enum int POLICY_VIOLATION = 1008;
82 
83     /**
84      * 1009 indicates that an endpoint is terminating the connection because it has received a message that is too big for it to process.
85      * <p>
86      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
87      */
88     enum int MESSAGE_TOO_LARGE = 1009;
89 
90     /**
91      * 1010 indicates that an endpoint (client) is terminating the connection because it has expected the server to negotiate one or more extension, but the
92      * server didn't return them in the response message of the WebSocket handshake. The list of extensions that are needed SHOULD appear in the /reason/ part
93      * of the Close frame. Note that this status code is not used by the server, because it can fail the WebSocket handshake instead.
94      * <p>
95      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
96      */
97     enum int REQUIRED_EXTENSION = 1010;
98 
99     /**
100      * 1011 indicates that a server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.
101      * <p>
102      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
103      */
104     enum int SERVER_ERROR = 1011;
105 
106     /**
107      * 1012 indicates that the service is restarted. a client may reconnect, and if it chooses to do, should reconnect using a randomized delay of 5 - 30s.
108      * <p>
109      * See <a href="https://www.ietf.org/mail-archive/web/hybi/current/msg09649.html">[hybi] Additional WebSocket Close Error Codes</a>
110      */
111     enum int SERVICE_RESTART = 1012;
112 
113     /**
114      * 1013 indicates that the service is experiencing overload. a client should only connect to a different IP (when there are multiple for the target) or
115      * reconnect to the same IP upon user action.
116      * <p>
117      * See <a href="https://www.ietf.org/mail-archive/web/hybi/current/msg09649.html">[hybi] Additional WebSocket Close Error Codes</a>
118      */
119     enum int TRY_AGAIN_LATER = 1013;
120 
121     /**
122      * 1014 indicates that a gateway or proxy received and invalid upstream response.
123      * <p>
124      * See <a href="https://www.ietf.org/mail-archive/web/hybi/current/msg10748.html">[hybi] WebSocket Subprotocol Close Code: Bad Gateway</a>
125      */
126     enum int INVALID_UPSTREAM_RESPONSE = 1014;
127 
128     /**
129      * 1015 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting
130      * a status code to indicate that the connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified).
131      * <p>
132      * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
133      */
134     enum int FAILED_TLS_HANDSHAKE = 1015;
135 
136     /**
137      * Test if provided status code can be sent/received on a WebSocket close.
138      * <p>
139      * This honors the RFC6455 rules and IANA rules.
140      * </p>
141      *
142      * @param statusCode the statusCode to test
143      * @return true if transmittable
144      */
145     static bool isTransmittable(int statusCode) {
146         return (statusCode == NORMAL) ||
147                 (statusCode == SHUTDOWN) ||
148                 (statusCode == PROTOCOL) ||
149                 (statusCode == BAD_DATA) ||
150                 (statusCode == BAD_PAYLOAD) ||
151                 (statusCode == POLICY_VIOLATION) ||
152                 (statusCode == MESSAGE_TOO_LARGE) ||
153                 (statusCode == REQUIRED_EXTENSION) ||
154                 (statusCode == SERVER_ERROR) ||
155                 (statusCode == SERVICE_RESTART) ||
156                 (statusCode == TRY_AGAIN_LATER) ||
157                 (statusCode == INVALID_UPSTREAM_RESPONSE);
158     }
159 }