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