// Copyright (C) 2013 The Android Open Source Project
//
// Licensed 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 com.google.gerrit.pgm.http.jetty;

import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.gwtexpui.server.CacheHeaders;

import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

class HiddenErrorHandler extends ErrorHandler {
  private static final Logger log = LoggerFactory.getLogger(HiddenErrorHandler.class);
  private static final byte[] MSG = "Internal server error\n".getBytes(Charsets.ISO_8859_1);

  public void handle(String target, Request baseRequest,
      HttpServletRequest req, HttpServletResponse res) throws IOException {
    AbstractHttpConnection.getCurrentConnection().getRequest().setHandled(true);
    try {
      log(req);
    } finally {
      replyGenericError(res);
    }
  }

  private void replyGenericError(HttpServletResponse res) throws IOException {
    if (!res.isCommitted()) {
      res.reset();
      res.setStatus(SC_INTERNAL_SERVER_ERROR);
      res.setHeader(HttpHeaders.CONTENT_TYPE, "text/plain; charset=ISO-8859-1");
      res.setContentLength(MSG.length);
      try {
        CacheHeaders.setNotCacheable(res);
      } finally {
        ServletOutputStream out = res.getOutputStream();
        try {
          out.write(MSG);
        } finally {
          out.close();
        }
      }
    }
  }

  private static void log(HttpServletRequest req) {
    Throwable err = (Throwable)req.getAttribute("javax.servlet.error.exception");
    if (err != null) {
      String uri = req.getRequestURI();
      if (!Strings.isNullOrEmpty(req.getQueryString())) {
        uri += "?" + req.getQueryString();
      }
      log.error(String.format("Error in %s %s", req.getMethod(), uri), err);
    }
  }
}

@@ -649,88 +649,8 @@
 y;%0A%0A
-import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;%0A%0A
 impo
@@ -816,16 +816,58 @@
 eaders;%0A
+import org.eclipse.jetty.http.HttpStatus;%0A
 import o
@@ -1370,101 +1370,8 @@
 ss);
-%0A  private static final byte%5B%5D MSG = %22Internal server error%5Cn%22.getBytes(Charsets.ISO_8859_1);
 %0A%0A  
@@ -1504,16 +1504,46 @@
 on %7B%0A   
+ AbstractHttpConnection conn =
  Abstrac
@@ -1580,16 +1580,26 @@
 ection()
+;%0A    conn
 .getRequ
@@ -1675,29 +1675,23 @@
    reply
-GenericError(
+(conn, 
 res);%0A  
@@ -1723,21 +1723,38 @@
 eply
-GenericError(
+(AbstractHttpConnection conn, 
 Http
@@ -1765,32 +1765,38 @@
 letResponse res)
+%0A     
  throws IOExcept
@@ -1809,102 +1809,36 @@
     
-if (!res.isCommitted()) %7B%0A      res.reset();%0A      res.setStatus(SC_INTERNAL_SERVER_ERROR
+byte%5B%5D msg = message(conn
 );%0A
-  
     
@@ -1916,18 +1916,16 @@
 %22);%0A    
-  
 res.setC
@@ -1937,19 +1937,19 @@
 tLength(
-MSG
+msg
 .length)
@@ -1950,34 +1950,30 @@
 ength);%0A    
-  
 try %7B%0A
-  
       CacheH
@@ -2001,18 +2001,16 @@
 e(res);%0A
-  
     %7D fi
@@ -2023,18 +2023,16 @@
 %7B%0A      
-  
 ServletO
@@ -2078,26 +2078,22 @@
 ;%0A      
-  
 try %7B%0A
-  
         
@@ -2106,16 +2106,14 @@
 ite(
-MSG
+msg
 );%0A
-  
     
@@ -2130,26 +2130,24 @@
 y %7B%0A        
- 
- 
 out.close();
@@ -2151,24 +2151,28 @@
 ();%0A    
+  %7D%0A
     %7D%0A  
     %7D%0A  
@@ -2163,27 +2163,264 @@
     %7D%0A  
-    %7D%0A    %7D
+%7D%0A%0A  private static byte%5B%5D message(AbstractHttpConnection conn) %7B%0A    String msg = conn.getResponse().getReason();%0A    if (msg == null)%0A      msg = HttpStatus.getMessage(conn.getResponse().getStatus());%0A    return msg.getBytes(Charsets.ISO_8859_1);
 %0A  %7D%0A%0A  

Fix HiddenErrorHandler