You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mi...@apache.org on 2008/07/19 04:49:59 UTC

svn commit: r678093 - in /ode/trunk: axis2/src/main/java/org/apache/ode/axis2/httpbinding/ axis2/src/test/java/org/apache/ode/axis2/httpbinding/ utils/src/main/java/org/apache/ode/utils/http/

Author: midon
Date: Fri Jul 18 19:49:58 2008
New Revision: 678093

URL: http://svn.apache.org/viewvc?rev=678093&view=rev
Log:
ODE-310: better code status handling for fault/failure

Added:
    ode/trunk/utils/src/main/java/org/apache/ode/utils/http/
    ode/trunk/utils/src/main/java/org/apache/ode/utils/http/HttpUtils.java
    ode/trunk/utils/src/main/java/org/apache/ode/utils/http/StatusCode.java
Modified:
    ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java
    ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java
    ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java
    ode/trunk/axis2/src/test/java/org/apache/ode/axis2/httpbinding/HttpHelperTest.java

Modified: ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java
URL: http://svn.apache.org/viewvc/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java?rev=678093&r1=678092&r2=678093&view=diff
==============================================================================
--- ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java (original)
+++ ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java Fri Jul 18 19:49:58 2008
@@ -38,6 +38,7 @@
 import org.apache.ode.il.epr.EndpointFactory;
 import org.apache.ode.il.epr.WSAEndpoint;
 import org.apache.ode.utils.DOMUtils;
+import static org.apache.ode.utils.http.StatusCode.*;
 import org.apache.ode.utils.wsdl.Messages;
 import org.apache.ode.utils.wsdl.WsdlUtils;
 import org.w3c.dom.Element;
@@ -251,10 +252,8 @@
                     _2xx_success();
                 } else if (statusCode >= 300 && statusCode < 400) {
                     _3xx_redirection();
-                } else if (statusCode >= 400 && statusCode < 500) {
-                    _4xx_badRequest();
-                } else if (statusCode >= 500 && statusCode < 600) {
-                    _5xx_serverError();
+                } else if (statusCode >= 400 && statusCode < 600) {
+                    _4xx_5xx_error();
                 } else {
                     unmanagedStatus();
                 }
@@ -267,30 +266,15 @@
             replyWithFailure("Unmanaged Status Code! Status-Line: " + method.getStatusLine() + " for " + method.getURI());
         }
 
-        /**
-         * For 500s if a fault is defined in the WSDL and the response body contains the corresponding xml doc, then reply with a fault ; else reply with failure.
-         *
-         * @throws IOException
-         */
-        private void _5xx_serverError() throws Exception {
-            String errmsg;
-            if (log.isWarnEnabled()) {
-                errmsg = "[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] Status-Line: " + method.getStatusLine() + " for " + method.getURI();
-                log.warn(errmsg);
+        private void _4xx_5xx_error() throws Exception {
+            int status = method.getStatusCode();
+            if(HttpHelper.isFaultOrFailure(status)>0){
+                // reply with a fault, meaning the request should not be repeated
+                replyWithFault();
+            } else {
+                // reply with a failure, meaning the request might be repeated later
+                replyWithFailure("HTTP Status-Line: " + method.getStatusLine() + " for " + method.getURI());
             }
-            Object[] fault = httpMethodConverter.parseFault(odeMex, method);
-            Message response = (Message) fault[1];
-            QName faultName = (QName) fault[0];
-
-            // finally send the fault. We did it!
-            if (log.isWarnEnabled())
-                log.warn("[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] Fault response: faultName=" + faultName + " faultType=" + response.getType() + "\n" + DOMUtils.domToString(response.getMessage()));
-
-            odeMex.replyWithFault(faultName, response);
-        }
-
-        private void _4xx_badRequest() throws Exception {
-            replyWithFailure("HTTP Status-Line: " + method.getStatusLine() + " for " + method.getURI());
         }
 
         private void _3xx_redirection() throws Exception {
@@ -317,9 +301,22 @@
                 odeMex.reply(odeResponse);
             } catch (Exception ex) {
                 replyWithFailure("Unable to process response: " + ex.getMessage(), ex);
-            }            
+            }
         }
 
+        void replyWithFault() {
+            Object[] fault = httpMethodConverter.parseFault(odeMex, method);
+            Message response = (Message) fault[1];
+            QName faultName = (QName) fault[0];
+
+            // finally send the fault. We did it!
+            if (log.isWarnEnabled())
+                log.warn("[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] Fault response: faultName=" + faultName + " faultType=" + response.getType() + "\n" + DOMUtils.domToString(response.getMessage()));
+
+            odeMex.replyWithFault(faultName, response);
+        }
+
+
         void replyWithFailure(String errmsg) {
             replyWithFailure(errmsg, null);
         }

Modified: ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java
URL: http://svn.apache.org/viewvc/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java?rev=678093&r1=678092&r2=678093&view=diff
==============================================================================
--- ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java (original)
+++ ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java Fri Jul 18 19:49:58 2008
@@ -30,21 +30,18 @@
 import org.apache.commons.httpclient.Header;
 import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
 import org.apache.commons.httpclient.methods.StringRequestEntity;
-import org.apache.commons.httpclient.methods.RequestEntity;
 import org.apache.commons.httpclient.params.HttpParams;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.lang.StringUtils;
 import org.apache.ode.axis2.Properties;
 import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.http.HttpUtils;
+import static org.apache.ode.utils.http.StatusCode.*;
 import org.w3c.dom.Element;
 import org.w3c.dom.Document;
 
 import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.StringWriter;
-import java.io.PipedOutputStream;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -128,7 +125,7 @@
     public static Element prepareDetailsElement(HttpMethod method) {
         Header h = method.getResponseHeader("Content-Type");
         String receivedType = h != null ? h.getValue() : null;
-        boolean bodyIsXml = receivedType != null && HttpHelper.isXml(receivedType);
+        boolean bodyIsXml = receivedType != null && HttpUtils.isXml(receivedType);
 
 
         Document doc = DOMUtils.newDocument();
@@ -203,20 +200,6 @@
         return sb.toString();
     }
 
-    public static final String XML_MIME_TYPE_REGEX = "(text/xml)|(application/xml)|((.*)\\+xml)";
-    private static final String TEXT_MIME_TYPE_REGEX = "text/(?!xml$).*";
-    private static final Pattern XML_MIME_TYPE_PATTERN = Pattern.compile(XML_MIME_TYPE_REGEX);
-    private static final Pattern TEXT_MIME_TYPE_PATTERN = Pattern.compile(TEXT_MIME_TYPE_REGEX);
-
-    public static boolean isXml(String contentType) {
-        return XML_MIME_TYPE_PATTERN.matcher(contentType).matches();
-    }
-
-    public static boolean isText(String contentType) {
-        return TEXT_MIME_TYPE_PATTERN.matcher(contentType).matches();
-    }
-
-
     public static String requestToString(HttpMethod m) {
         StringBuilder sb = new StringBuilder(256);
         try {
@@ -278,4 +261,44 @@
         }
         return sb.toString();
     }
+
+    /**
+     *
+     * @param s, the status code to test, must be in [400, 600[
+     * @return 1 if fault, -1 if failure, 0 if undetermined
+     */
+    public static int isFaultOrFailure(int s) {
+        if (s < 400 || s >= 600) {
+            throw new IllegalArgumentException("Status-Code must be in interval [400;600[");
+        }
+        if (s == _500_INTERNAL_SERVER_ERROR
+                || s == _501_NOT_IMPLEMENTED
+                || s == _502_BAD_GATEWAY
+                || s == _505_HTTP_VERSION_NOT_SUPPORTED
+                || s == _400_BAD_REQUEST
+                || s == _402_PAYMENT_REQUIRED
+                || s == _403_FORBIDDEN
+                || s == _404_NOT_FOUND
+                || s == _405_METHOD_NOT_ALLOWED
+                || s == _406_NOT_ACCEPTABLE
+                || s == _407_PROXY_AUTHENTICATION_REQUIRED
+                || s == _409_CONFLICT
+                || s == _410_GONE
+                || s == _412_PRECONDITION_FAILED
+                || s == _413_REQUEST_TOO_LONG
+                || s == _414_REQUEST_URI_TOO_LONG
+                || s == _415_UNSUPPORTED_MEDIA_TYPE
+                || s == _411_LENGTH_REQUIRED
+                || s == _416_REQUESTED_RANGE_NOT_SATISFIABLE
+                || s == _417_EXPECTATION_FAILED) {
+            return 1;
+        } else if (s == _503_SERVICE_UNAVAILABLE
+                || s == _504_GATEWAY_TIMEOUT
+                || s == _401_UNAUTHORIZED
+                || s == _408_REQUEST_TIMEOUT) {
+            return -1;
+        } else {
+            return 0;
+        }
+    }
 }

Modified: ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java
URL: http://svn.apache.org/viewvc/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java?rev=678093&r1=678092&r2=678093&view=diff
==============================================================================
--- ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java (original)
+++ ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java Fri Jul 18 19:49:58 2008
@@ -39,6 +39,9 @@
 import org.apache.ode.il.epr.MutableEndpoint;
 import org.apache.ode.utils.DOMUtils;
 import org.apache.ode.utils.Namespaces;
+import org.apache.ode.utils.http.HttpUtils;
+import static org.apache.ode.utils.http.HttpUtils.bodyAllowed;
+import static org.apache.ode.utils.http.StatusCode.*;
 import org.apache.ode.utils.wsdl.Messages;
 import org.apache.ode.utils.wsdl.WsdlUtils;
 import org.w3c.dom.Document;
@@ -194,7 +197,7 @@
                     String errMsg = "XML Types are not supported. Parts must use elements.";
                     if (log.isErrorEnabled()) log.error(errMsg);
                     throw new RuntimeException(errMsg);
-                } else if (HttpHelper.isXml(contentType)) {
+                } else if (HttpUtils.isXml(contentType)) {
                     if (log.isDebugEnabled()) log.debug("Content-Type [" + contentType + "] equivalent to 'text/xml'");
                     // stringify the first element
                     String xmlString = DOMUtils.domToString(DOMUtils.getFirstChildElement(partValue));
@@ -431,12 +434,12 @@
 
         // assumption is made that a response may have at most one body. HttpBindingValidator checks this.
         MIMEContent outputContent = WsdlUtils.getMimeContent(opBinding.getBindingOutput().getExtensibilityElements());
-        int statusCode = method.getStatusCode();
+        int status = method.getStatusCode();
 
-        boolean xmlExpected = outputContent != null && HttpHelper.isXml(outputContent.getType());
+        boolean xmlExpected = outputContent != null && HttpUtils.isXml(outputContent.getType());
         // '202/Accepted' and '204/No Content' status codes explicitly state that there is no body, so we should not fail even if a part is bound to the body response
         boolean isBodyExpected = outputContent != null;
-        boolean isBodyMandatory = isBodyExpected && statusCode != 204 && statusCode != 202;
+        boolean isBodyMandatory = isBodyExpected && bodyAllowed(status) && status != _202_ACCEPTED;
         final String body;
         try {
             body = method.getResponseBodyAsString();
@@ -459,7 +462,7 @@
                     Header h = method.getResponseHeader("Content-Type");
                     String receivedType = h != null ? h.getValue() : null;
                     boolean contentTypeSet = receivedType != null;
-                    boolean xmlReceived = contentTypeSet && HttpHelper.isXml(receivedType);
+                    boolean xmlReceived = contentTypeSet && HttpUtils.isXml(receivedType);
 
                     // a few checks
                     if (!contentTypeSet) {
@@ -506,7 +509,7 @@
             throw new RuntimeException("No fault binding. This " + method.getStatusCode() + " error will be considered as a failure.");
         } else if (StringUtils.isEmpty(body)) {
             throw new RuntimeException("No body in the response. This " + method.getStatusCode() + " error will be considered as a failure.");
-        } else if (receivedType != null && !HttpHelper.isXml(receivedType)) {
+        } else if (receivedType != null && !HttpUtils.isXml(receivedType)) {
             throw new RuntimeException("Response Content-Type [" + receivedType + "] does not describe XML entities. Faults must be XML. This " + method.getStatusCode() + " error will be considered as a failure.");
         } else {
 

Modified: ode/trunk/axis2/src/test/java/org/apache/ode/axis2/httpbinding/HttpHelperTest.java
URL: http://svn.apache.org/viewvc/ode/trunk/axis2/src/test/java/org/apache/ode/axis2/httpbinding/HttpHelperTest.java?rev=678093&r1=678092&r2=678093&view=diff
==============================================================================
--- ode/trunk/axis2/src/test/java/org/apache/ode/axis2/httpbinding/HttpHelperTest.java (original)
+++ ode/trunk/axis2/src/test/java/org/apache/ode/axis2/httpbinding/HttpHelperTest.java Fri Jul 18 19:49:58 2008
@@ -20,8 +20,7 @@
 package org.apache.ode.axis2.httpbinding;
 
 import junit.framework.TestCase;
-import org.apache.ode.utils.DOMUtils;
-import org.w3c.dom.Document;
+import org.apache.ode.utils.http.HttpUtils;
 
 /**
  *
@@ -51,26 +50,26 @@
     public void testIsXml() {
 
         for (String s : IS_XML) {
-            assertTrue(s+" is an xml type", HttpHelper.isXml(s));
+            assertTrue(s+" is an xml type", HttpUtils.isXml(s));
         }
         for (String s : IS_TEXT) {
-            assertFalse(s+" is not an xml type", HttpHelper.isXml(s));
+            assertFalse(s+" is not an xml type", HttpUtils.isXml(s));
         }
         for (String s : IS_IMAGE) {
-            assertFalse(s+" is not an xml type", HttpHelper.isXml(s));
+            assertFalse(s+" is not an xml type", HttpUtils.isXml(s));
         }
 
     }
 
     public void testIsText() {
         for (String s : IS_TEXT) {
-            assertTrue(s+" is a text type", HttpHelper.isText(s));
+            assertTrue(s+" is a text type", HttpUtils.isText(s));
         }
         for (String s : IS_XML) {
-            assertFalse(s+" is not a text type", HttpHelper.isText(s));
+            assertFalse(s+" is not a text type", HttpUtils.isText(s));
         }
         for (String s : IS_IMAGE) {
-            assertFalse(s+" is not a text type", HttpHelper.isXml(s));
+            assertFalse(s+" is not a text type", HttpUtils.isXml(s));
         }
     }
 }

Added: ode/trunk/utils/src/main/java/org/apache/ode/utils/http/HttpUtils.java
URL: http://svn.apache.org/viewvc/ode/trunk/utils/src/main/java/org/apache/ode/utils/http/HttpUtils.java?rev=678093&view=auto
==============================================================================
--- ode/trunk/utils/src/main/java/org/apache/ode/utils/http/HttpUtils.java (added)
+++ ode/trunk/utils/src/main/java/org/apache/ode/utils/http/HttpUtils.java Fri Jul 18 19:49:58 2008
@@ -0,0 +1,58 @@
+/*
+ * 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.ode.utils.http;
+
+import java.util.regex.Pattern;
+
+/**
+ *
+ *
+ */
+public class HttpUtils {
+    public static final String XML_MIME_TYPE_REGEX = "(text/xml)|(application/xml)|((.*)\\+xml)";
+    public static final String TEXT_MIME_TYPE_REGEX = "text/(?!xml$).*";
+    public static final Pattern XML_MIME_TYPE_PATTERN = Pattern.compile(XML_MIME_TYPE_REGEX);
+    public static final Pattern TEXT_MIME_TYPE_PATTERN = Pattern.compile(TEXT_MIME_TYPE_REGEX);
+
+    public static boolean isXml(String contentType) {
+        return XML_MIME_TYPE_PATTERN.matcher(contentType).matches();
+    }
+
+    public static boolean isText(String contentType) {
+        return TEXT_MIME_TYPE_PATTERN.matcher(contentType).matches();
+    }
+
+    /**
+     * Per <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616 section 4.3</a>, some responses can never contain a message
+     * body.
+     *
+     * @param status - the HTTP status code
+     * @return <tt>true</tt> if the message may contain a body, <tt>false</tt> if it can not
+     *         contain a message body
+     */
+    public static boolean bodyAllowed(int status) {
+        if (status >= 100 && status < 200
+                || status == StatusCode._204_NO_CONTENT
+                || status == StatusCode._304_NOT_MODIFIED) {
+            return false;
+        }
+        return true;
+    }
+}

Added: ode/trunk/utils/src/main/java/org/apache/ode/utils/http/StatusCode.java
URL: http://svn.apache.org/viewvc/ode/trunk/utils/src/main/java/org/apache/ode/utils/http/StatusCode.java?rev=678093&view=auto
==============================================================================
--- ode/trunk/utils/src/main/java/org/apache/ode/utils/http/StatusCode.java (added)
+++ ode/trunk/utils/src/main/java/org/apache/ode/utils/http/StatusCode.java Fri Jul 18 19:49:58 2008
@@ -0,0 +1,107 @@
+package org.apache.ode.utils.http;
+
+import java.util.regex.Pattern;
+
+/**
+ *
+ * <a href="http://www.ietf.org/rfc/rfc2616.txt">HTTP/1.1 Status Codes</a>
+ */
+public class StatusCode {
+
+
+    // --- 1xx Informational ---
+
+    /** <tt>100 Continue</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _100_CONTINUE = 100;
+    /** <tt>101 Switching Protocols</tt> (HTTP/1.1 - RFC 2616)*/
+    public static final int _101_SWITCHING_PROTOCOLS = 101;
+
+    // --- 2xx Success ---
+
+    /** <tt>200 OK</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _200_OK = 200;
+    /** <tt>201 Created</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _201_CREATED = 201;
+    /** <tt>202 Accepted</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _202_ACCEPTED = 202;
+    /** <tt>203 Non Authoritative Information</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _203_NON_AUTHORITATIVE_INFORMATION = 203;
+    /** <tt>204 No Content</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _204_NO_CONTENT = 204;
+    /** <tt>205 Reset Content</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _205_RESET_CONTENT = 205;
+    /** <tt>206 Partial Content</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _206_PARTIAL_CONTENT = 206;
+
+    // --- 3xx Redirection ---
+
+    /** <tt>300 Mutliple Choices</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _300_MULTIPLE_CHOICES = 300;
+    /** <tt>301 Moved Permanently</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _301_MOVED_PERMANENTLY = 301;
+    /** <tt>302 Moved Temporarily</tt> (Sometimes <tt>Found</tt>) (HTTP/1.0 - RFC 1945) */
+    public static final int _302_MOVED_TEMPORARILY = 302;
+    /** <tt>303 See Other</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _303_SEE_OTHER = 303;
+    /** <tt>304 Not Modified</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _304_NOT_MODIFIED = 304;
+    /** <tt>305 Use Proxy</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _305_USE_PROXY = 305;
+    /** <tt>307 Temporary Redirect</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _307_TEMPORARY_REDIRECT = 307;
+
+    // --- 4xx Client Error ---
+
+    /** <tt>400 Bad Request</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _400_BAD_REQUEST = 400;
+    /** <tt>401 Unauthorized</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _401_UNAUTHORIZED = 401;
+    /** <tt>402 Payment Required</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _402_PAYMENT_REQUIRED = 402;
+    /** <tt>403 Forbidden</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _403_FORBIDDEN = 403;
+    /** <tt>404 Not Found</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _404_NOT_FOUND = 404;
+    /** <tt>405 Method Not Allowed</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _405_METHOD_NOT_ALLOWED = 405;
+    /** <tt>406 Not Acceptable</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _406_NOT_ACCEPTABLE = 406;
+    /** <tt>407 Proxy Authentication Required</tt> (HTTP/1.1 - RFC 2616)*/
+    public static final int _407_PROXY_AUTHENTICATION_REQUIRED = 407;
+    /** <tt>408 Request Timeout</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _408_REQUEST_TIMEOUT = 408;
+    /** <tt>409 Conflict</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _409_CONFLICT = 409;
+    /** <tt>410 Gone</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _410_GONE = 410;
+    /** <tt>411 Length Required</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _411_LENGTH_REQUIRED = 411;
+    /** <tt>412 Precondition Failed</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _412_PRECONDITION_FAILED = 412;
+    /** <tt>413 Request Entity Too Large</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _413_REQUEST_TOO_LONG = 413;
+    /** <tt>414 Request-URI Too Long</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _414_REQUEST_URI_TOO_LONG = 414;
+    /** <tt>415 Unsupported Media Type</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _415_UNSUPPORTED_MEDIA_TYPE = 415;
+    /** <tt>416 Requested Range Not Satisfiable</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _416_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
+    /** <tt>417 Expectation Failed</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _417_EXPECTATION_FAILED = 417;
+
+    // --- 5xx Server Error ---
+
+    /** <tt>500 Server Error</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _500_INTERNAL_SERVER_ERROR = 500;
+    /** <tt>501 Not Implemented</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _501_NOT_IMPLEMENTED = 501;
+    /** <tt>502 Bad Gateway</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _502_BAD_GATEWAY = 502;
+    /** <tt>503 Service Unavailable</tt> (HTTP/1.0 - RFC 1945) */
+    public static final int _503_SERVICE_UNAVAILABLE = 503;
+    /** <tt>504 Gateway Timeout</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _504_GATEWAY_TIMEOUT = 504;
+    /** <tt>505 HTTP Version Not Supported</tt> (HTTP/1.1 - RFC 2616) */
+    public static final int _505_HTTP_VERSION_NOT_SUPPORTED = 505;
+
+}