@Override
  protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
      throws ServletException, IOException {
    response.setHeader("Access-Control-Allow-Origin", "*");
    try {
      if (server == null) {
        LOG.error("server in servlet not configured");
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.setContentLength(0);
        return;
      }

      ResponderAndRelativeUri r = server.getResponderAndRelativeUri(request);
      if (r == null) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
      }

      if (StringUtil.isNotBlank(r.getRelativeUri())) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
      }

      Responder responder = r.getResponder();

      HealthCheckResult healthResult = server.healthCheck(responder);
      if (healthResult.isHealthy()) {
        response.setStatus(HttpServletResponse.SC_OK);
      } else {
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      }

      response.setContentType(HealthCheckServlet.CT_RESPONSE);
      byte[] respBytes = healthResult.toJsonMessage(true).getBytes();
      response.setContentLength(respBytes.length);
      response.getOutputStream().write(respBytes);
    } catch (EOFException e) {
      final String message = "connection reset by peer";
      if (LOG.isErrorEnabled()) {
        LOG.warn(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage());
      }
      LOG.debug(message, e);

      response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      response.setContentLength(0);
    } catch (Throwable t) {
      final String message = "Throwable thrown, this should not happen";
      if (LOG.isErrorEnabled()) {
        LOG.error(LogUtil.buildExceptionLogFormat(message), t.getClass().getName(), t.getMessage());
      }
      LOG.debug(message, t);
      response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      response.setContentLength(0);
    }

    response.flushBuffer();
  } // method doGet
Example #2
0
 @Test
 public void testReadThrowsEOFException() throws Throwable {
   FSDMsg fSDMsg = new FSDMsg("testFSDMsgBasePath");
   when(is.read(new byte[] {(byte) 00})).thenReturn(Integer.valueOf(1));
   when(is.read(new byte[] {(byte) 00})).thenReturn(Integer.valueOf(1));
   when(is.read(new byte[] {(byte) 00})).thenReturn(Integer.valueOf(-1));
   try {
     fSDMsg.read(is, 100, " ", null);
     fail("Expected EOFException to be thrown");
   } catch (EOFException ex) {
     assertEquals("ex.getClass()", EOFException.class, ex.getClass());
   }
 }
Example #3
0
  private void processRequest(
      final HttpServletRequest request,
      final HttpServletResponse response,
      final ResponderAndRelativeUri r,
      final boolean getMethod)
      throws ServletException, IOException {
    Responder responder = r.getResponder();
    AuditEvent auditEvent = null;

    AuditLevel auditLevel = AuditLevel.INFO;
    AuditStatus auditStatus = AuditStatus.SUCCESSFUL;
    String auditMessage = null;

    long start = 0;

    AuditService auditService =
        (auditServiceRegister == null) ? null : auditServiceRegister.getAuditService();

    if (auditService != null && responder.getAuditOption() != null) {
      start = System.currentTimeMillis();
      auditEvent = new AuditEvent(new Date());
      auditEvent.setApplicationName("OCSP");
      auditEvent.setName("PERF");
    }

    try {
      if (server == null) {
        String message = "responder in servlet not configured";
        LOG.error(message);
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.setContentLength(0);

        auditLevel = AuditLevel.ERROR;
        auditStatus = AuditStatus.FAILED;
        auditMessage = message;
        return;
      }

      InputStream requestStream;
      if (getMethod) {
        String relativeUri = r.getRelativeUri();

        // RFC2560 A.1.1 specifies that request longer than 255 bytes SHOULD be sent by
        // POST, we support GET for longer requests anyway.
        if (relativeUri.length() > responder.getRequestOption().getMaxRequestSize()) {
          response.setContentLength(0);
          response.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);

          auditStatus = AuditStatus.FAILED;
          auditMessage = "request too large";
          return;
        }

        requestStream = new ByteArrayInputStream(Base64.decode(relativeUri));
      } else {
        // accept only "application/ocsp-request" as content type
        if (!CT_REQUEST.equalsIgnoreCase(request.getContentType())) {
          response.setContentLength(0);
          response.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);

          auditStatus = AuditStatus.FAILED;
          auditMessage = "unsupporte media type " + request.getContentType();
          return;
        }

        // request too long
        if (request.getContentLength() > responder.getRequestOption().getMaxRequestSize()) {
          response.setContentLength(0);
          response.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);

          auditStatus = AuditStatus.FAILED;
          auditMessage = "request too large";
          return;
        } // if (CT_REQUEST)

        requestStream = request.getInputStream();
      } // end if (getMethod)

      OCSPRequest ocspRequest;
      try {
        ASN1StreamParser parser = new ASN1StreamParser(requestStream);
        ocspRequest = OCSPRequest.getInstance(parser.readObject());
      } catch (Exception e) {
        response.setContentLength(0);
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);

        auditStatus = AuditStatus.FAILED;
        auditMessage = "bad request";

        final String message = "could not parse the request (OCSPRequest)";
        if (LOG.isErrorEnabled()) {
          LOG.error(
              LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage());
        }
        LOG.debug(message, e);

        return;
      }

      OCSPReq ocspReq = new OCSPReq(ocspRequest);

      response.setContentType(HttpOcspServlet.CT_RESPONSE);

      OcspRespWithCacheInfo ocspRespWithCacheInfo =
          server.answer(responder, ocspReq, auditEvent, getMethod);
      if (ocspRespWithCacheInfo == null) {
        auditMessage = "processRequest returned null, this should not happen";
        LOG.error(auditMessage);
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.setContentLength(0);

        auditLevel = AuditLevel.ERROR;
        auditStatus = AuditStatus.FAILED;
      } else {
        OCSPResp resp = ocspRespWithCacheInfo.getResponse();
        byte[] encodedOcspResp = null;
        response.setStatus(HttpServletResponse.SC_OK);

        ResponseCacheInfo cacheInfo = ocspRespWithCacheInfo.getCacheInfo();
        if (getMethod && cacheInfo != null) {
          encodedOcspResp = resp.getEncoded();
          long now = System.currentTimeMillis();
          // RFC 5019 6.2: Date: The date and time at which the OCSP server generated
          // the HTTP response.
          response.setDateHeader("Date", now);
          // RFC 5019 6.2: Last-Modified: date and time at which the OCSP responder
          // last modified the response.
          response.setDateHeader("Last-Modified", cacheInfo.getThisUpdate());
          // RFC 5019 6.2: Expires: This date and time will be the same as the
          // nextUpdate time-stamp in the OCSP
          // response itself.
          // This is overridden by max-age on HTTP/1.1 compatible components
          if (cacheInfo.getNextUpdate() != null) {
            response.setDateHeader("Expires", cacheInfo.getNextUpdate());
          }
          // RFC 5019 6.2: This profile RECOMMENDS that the ETag value be the ASCII
          // HEX representation of the SHA1 hash of the OCSPResponse structure.
          response.setHeader(
              "ETag",
              new StringBuilder(42)
                  .append('\\')
                  .append(HashCalculator.hexSha1(encodedOcspResp))
                  .append('\\')
                  .toString());

          // Max age must be in seconds in the cache-control header
          long maxAge;
          if (responder.getResponseOption().getCacheMaxAge() != null) {
            maxAge = responder.getResponseOption().getCacheMaxAge().longValue();
          } else {
            maxAge = OcspServer.defaultCacheMaxAge;
          }

          if (cacheInfo.getNextUpdate() != null) {
            maxAge =
                Math.min(maxAge, (cacheInfo.getNextUpdate() - cacheInfo.getThisUpdate()) / 1000);
          }

          response.setHeader(
              "Cache-Control",
              new StringBuilder(55)
                  .append("max-age=")
                  .append(maxAge)
                  .append(",public,no-transform,must-revalidate")
                  .toString());
        } // end if (getMethod && cacheInfo != null)

        if (encodedOcspResp != null) {
          response.getOutputStream().write(encodedOcspResp);
        } else {
          ASN1OutputStream asn1Out = new ASN1OutputStream(response.getOutputStream());
          asn1Out.writeObject(resp.toASN1Structure());
          asn1Out.flush();
        }
      } // end if (ocspRespWithCacheInfo)
    } catch (EOFException e) {
      final String message = "Connection reset by peer";
      if (LOG.isErrorEnabled()) {
        LOG.warn(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage());
      }
      LOG.debug(message, e);

      response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      response.setContentLength(0);
    } catch (Throwable t) {
      final String message = "Throwable thrown, this should not happen!";
      LOG.error(message, t);

      response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      response.setContentLength(0);

      auditLevel = AuditLevel.ERROR;
      auditStatus = AuditStatus.FAILED;
      auditMessage = "internal error";
    } finally {
      try {
        response.flushBuffer();
      } finally {
        if (auditEvent != null) {
          if (auditLevel != null) {
            auditEvent.setLevel(auditLevel);
          }

          if (auditStatus != null) {
            auditEvent.setStatus(auditStatus);
          }

          if (auditMessage != null) {
            auditEvent.addEventData(new AuditEventData("message", auditMessage));
          }

          auditEvent.setDuration(System.currentTimeMillis() - start);

          if (!auditEvent.containsChildAuditEvents()) {
            auditService.logEvent(auditEvent);
          } else {
            List<AuditEvent> expandedAuditEvents = auditEvent.expandAuditEvents();
            for (AuditEvent event : expandedAuditEvents) {
              auditService.logEvent(event);
            }
          }
        } // end if (auditEvent != null)
      } // end inner try
    } // end external try
  } // method processRequest