1 /*
2  * Copyright (C) 2004-2008 Jive Software. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.jivesoftware.openfire.http;
17 
18 import javax.servlet.http.HttpServletResponse;
19 
20 /**
21  *  An enum defining all errors which can happen during a BOSH session.
22  */
23 public enum BoshBindingError {
24     /**
25      * The format of an HTTP header or binding element received from the client is unacceptable
26      * (e.g., syntax error), or Script Syntax is not supported.
27      */
28     badRequest(Type.terminate, "bad-request", HttpServletResponse.SC_BAD_REQUEST),
29     /**
30      * The target domain specified in the 'to' attribute or the target host or port specified in the
31      * 'route' attribute is no longer serviced by the connection manager.
32      */
33     hostGone(Type.terminate, "host-gone"),
34     /**
35      * The target domain specified in the 'to' attribute or the target host or port specified in the
36      * 'route' attribute is unknown to the connection manager.
37      */
38     hostUnknown(Type.terminate, "host-unknown"),
39     /**
40      * The initialization element lacks a 'to' or 'route' attribute (or the attribute has no value)
41      * but the connection manager requires one.
42      */
43     improperAddressing(Type.terminate, "improper-addressing"),
44     /**
45      * The connection manager has experienced an internal error that prevents it from servicing the
46      * request.
47      */
48     internalServerError(Type.terminate, "internal-server-error"),
49     /**
50      * (1) 'sid' is not valid, (2) 'stream' is not valid, (3) 'rid' is larger than the upper limit
51      * of the expected window, (4) connection manager is unable to resend response, (5) 'key'
52      * sequence is invalid (6) script syntax is not enabled
53      */
54     itemNotFound(Type.terminate, "item-not-found", HttpServletResponse.SC_NOT_FOUND),
55     /**
56      * Another request being processed at the same time as this request caused the session to
57      * terminate.
58      */
59     otherRequest(Type.terminate, "other-request"),
60     /**
61      * The client has broken the session rules (polling too frequently, requesting too frequently,
62      * too many simultaneous requests).
63      */
64     policyViolation(Type.terminate, "policy-violation",
65             HttpServletResponse.SC_FORBIDDEN),
66     /**
67      * The connection manager was unable to connect to, or unable to connect securely to, or has
68      * lost its connection to, the server.
69      */
70     remoteConnectionFailed(Type.terminate, "remote-connection-failed"),
71     /**
72      * Encapsulates an error in the protocol being transported.
73      */
74     remoteStreamError(Type.terminate, "remote-stream-error"),
75     /**
76      * The connection manager does not operate at this URI (e.g., the connection manager accepts
77      * only SSL or TLS connections at some https: URI rather than the http: URI requested by the
78      * client). The client may try POSTing to the URI in the content of the <uri/> child
79      * element.
80      */
81     seeOtherUri(Type.terminate, "see-other-uri"),
82     /**
83      * The connection manager is being shut down. All active HTTP sessions are being terminated. No
84      * new sessions can be created.
85      */
86     systemShutdown(Type.terminate, "system-shutdown"),
87     /**
88      * The error is not one of those defined herein; the connection manager SHOULD include
89      * application-specific information in the content of the <body> wrapper.
90      */
91     undefinedCondition(Type.terminate, "undefined-condition");
92 
93     private Type errorType;
94     private String condition;
95     private int legacyErrorCode = HttpServletResponse.SC_BAD_REQUEST;
96 
BoshBindingError(Type errorType, String condition, int legacyErrorCode)97     BoshBindingError(Type errorType, String condition, int legacyErrorCode) {
98         this(errorType, condition);
99         this.legacyErrorCode = legacyErrorCode;
100     }
101 
BoshBindingError(Type errorType, String condition)102     BoshBindingError(Type errorType, String condition) {
103         this.errorType = errorType;
104         this.condition = condition;
105     }
106 
getErrorType()107     public Type getErrorType() {
108         return errorType;
109     }
110 
111     /**
112      * Returns the condition that caused the binding error. This should be returned to the client
113      * so that the client can take appropriate action.
114      *
115      * @return the condition that caused the binding error.
116      */
getCondition()117     public String getCondition() {
118         return condition;
119     }
120 
121     /**
122      * Returns the legacy HTTP error code which is related to the binding error. With the 1.6
123      * version of BOSH the use of HTTP errors was deprecated in favor of using errors inside of the
124      * response to the client so that they could be more easily processed on the client side.
125      *
126      * @return the legacy HTTP error code which is related to the binding error.
127      */
getLegacyErrorCode()128     public int getLegacyErrorCode() {
129         return legacyErrorCode;
130     }
131 
132     public enum Type {
133         /**
134          * The terminate error condition prevents the client from making any further requests until a
135          * new session is established.
136          */
137         terminate(null),
138         /**
139          * In the case of a recoverable binding error the client MUST repeat the HTTP request and
140          * all the preceding HTTP requests that have not received responses. The content of these
141          * requests MUST be identical to the <body> elements of the original requests. This
142          * allows the connection manager to recover a session after the previous request was lost
143          * due to a communication failure.
144          */
145         recoverable("error");
146         private String type;
147 
Type(String type)148         Type(String type) {
149             this.type = type;
150         }
151 
152         /**
153          * Returns the type that will be displayed to the client.
154          *
155          * @return the type that will be displayed to the client.
156          */
getType()157         public String getType() {
158             if (type == null) {
159                 return name();
160             }
161             else {
162                 return type;
163             }
164         }
165     }
166 }
167