use of org.xipki.ocsp.api.ResponderAndPath in project xipki by xipki.
the class HttpOcspServlet method servicePost.
private FullHttpResponse servicePost(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession, SslReverseProxyMode sslReverseProxyMode) throws Exception {
HttpVersion version = request.protocolVersion();
ResponderAndPath responderAndPath = server.getResponderForPath(servletUri.getPath());
if (responderAndPath == null) {
return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
}
try {
// accept only "application/ocsp-request" as content type
String reqContentType = request.headers().get("Content-Type");
if (!CT_REQUEST.equalsIgnoreCase(reqContentType)) {
return createErrorResponse(version, HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE);
}
Responder responder = responderAndPath.getResponder();
int contentLen = request.content().readableBytes();
// request too long
if (contentLen > responder.getMaxRequestSize()) {
return createErrorResponse(version, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE);
}
OcspRespWithCacheInfo ocspRespWithCacheInfo = server.answer(responder, readContent(request), false);
if (ocspRespWithCacheInfo == null || ocspRespWithCacheInfo.getResponse() == null) {
LOG.error("processRequest returned null, this should not happen");
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
byte[] encodedOcspResp = ocspRespWithCacheInfo.getResponse();
return createOKResponse(version, CT_RESPONSE, encodedOcspResp);
} catch (Throwable th) {
if (th instanceof EOFException) {
LogUtil.warn(LOG, th, "Connection reset by peer");
} else {
LOG.error("Throwable thrown, this should not happen!", th);
}
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
// end external try
}
use of org.xipki.ocsp.api.ResponderAndPath in project xipki by xipki.
the class HttpOcspServlet method serviceGet.
// method servicePost
private FullHttpResponse serviceGet(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession, SslReverseProxyMode sslReverseProxyMode) throws Exception {
HttpVersion version = request.protocolVersion();
ResponderAndPath responderAndPath = server.getResponderForPath(servletUri.getPath());
if (responderAndPath == null) {
return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
}
String path = servletUri.getPath();
String servletPath = responderAndPath.getServletPath();
Responder responder = responderAndPath.getResponder();
if (!responder.supportsHttpGet()) {
return createErrorResponse(version, HttpResponseStatus.METHOD_NOT_ALLOWED);
}
String b64OcspReq;
int offset = servletPath.length();
// GET URI contains the request and must be much longer than 10.
if (path.length() - offset > 10) {
if (path.charAt(offset) == '/') {
offset++;
}
b64OcspReq = servletUri.getPath().substring(offset);
} else {
return createErrorResponse(version, HttpResponseStatus.BAD_REQUEST);
}
try {
// POST, we support GET for longer requests anyway.
if (b64OcspReq.length() > responder.getMaxRequestSize()) {
return createErrorResponse(version, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE);
}
OcspRespWithCacheInfo ocspRespWithCacheInfo = server.answer(responder, Base64.decode(b64OcspReq), true);
if (ocspRespWithCacheInfo == null || ocspRespWithCacheInfo.getResponse() == null) {
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
byte[] encodedOcspResp = ocspRespWithCacheInfo.getResponse();
FullHttpResponse response = createOKResponse(version, CT_RESPONSE, encodedOcspResp);
OcspRespWithCacheInfo.ResponseCacheInfo cacheInfo = ocspRespWithCacheInfo.getCacheInfo();
if (cacheInfo != null) {
encodedOcspResp = ocspRespWithCacheInfo.getResponse();
HttpHeaders headers = response.headers();
// RFC 5019 6.2: Date: The date and time at which the OCSP server generated
// the HTTP response.
headers.add("Date", new Date());
// RFC 5019 6.2: Last-Modified: date and time at which the OCSP responder
// last modified the response.
headers.add("Last-Modified", new Date(cacheInfo.getThisUpdate()));
// This is overridden by max-age on HTTP/1.1 compatible components
if (cacheInfo.getNextUpdate() != null) {
headers.add("Expires", new Date(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.
headers.add("ETag", StringUtil.concat("\\", HashAlgo.SHA1.hexHash(encodedOcspResp), "\\"));
// Max age must be in seconds in the cache-control header
long maxAge;
if (responder.getCacheMaxAge() != null) {
maxAge = responder.getCacheMaxAge().longValue();
} else {
maxAge = DFLT_CACHE_MAX_AGE;
}
if (cacheInfo.getNextUpdate() != null) {
maxAge = Math.min(maxAge, (cacheInfo.getNextUpdate() - cacheInfo.getThisUpdate()) / 1000);
}
headers.add("Cache-Control", StringUtil.concat("max-age=", Long.toString(maxAge), ",public,no-transform,must-revalidate"));
}
return response;
} catch (Throwable th) {
if (th instanceof EOFException) {
LogUtil.warn(LOG, th, "Connection reset by peer");
} else {
LOG.error("Throwable thrown, this should not happen!", th);
}
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
// end external try
}
use of org.xipki.ocsp.api.ResponderAndPath in project xipki by xipki.
the class HealthCheckServlet method service0.
private FullHttpResponse service0(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession) {
HttpVersion version = request.protocolVersion();
HttpMethod method = request.method();
if (method != HttpMethod.GET) {
return createErrorResponse(version, HttpResponseStatus.METHOD_NOT_ALLOWED);
}
try {
if (server == null) {
LOG.error("server in servlet not configured");
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
ResponderAndPath responderAndPath = server.getResponderForPath(servletUri.getPath());
if (responderAndPath == null) {
return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
}
HealthCheckResult healthResult = server.healthCheck(responderAndPath.getResponder());
HttpResponseStatus status = healthResult.isHealthy() ? HttpResponseStatus.OK : HttpResponseStatus.INTERNAL_SERVER_ERROR;
byte[] respBytes = healthResult.toJsonMessage(true).getBytes();
return createResponse(version, status, HealthCheckServlet.CT_RESPONSE, respBytes);
} catch (Throwable th) {
if (th instanceof EOFException) {
LogUtil.warn(LOG, th, "connection reset by peer");
} else {
LOG.error("Throwable thrown, this should not happen", th);
}
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
}
use of org.xipki.ocsp.api.ResponderAndPath in project xipki by xipki.
the class HealthCheckServlet method doGet.
@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("Access-Control-Allow-Origin", "*");
OcspServer server = ServletHelper.getServer();
if (server == null) {
LOG.error("ServletHelper.server not configured");
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
resp.setContentLength(0);
return;
}
try {
String path = StringUtil.getRelativeRequestUri(req.getServletPath(), req.getRequestURI());
ResponderAndPath responderAndPath = server.getResponderForPath(path);
if (responderAndPath == null) {
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
resp.setContentLength(0);
return;
}
HealthCheckResult healthResult = server.healthCheck(responderAndPath.getResponder());
int status = healthResult.isHealthy() ? HttpServletResponse.SC_OK : HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
byte[] respBytes = healthResult.toJsonMessage(true).getBytes();
resp.setStatus(status);
resp.setContentType(HealthCheckServlet.CT_RESPONSE);
resp.setContentLength(respBytes.length);
resp.getOutputStream().write(respBytes);
} catch (Throwable th) {
if (th instanceof EOFException) {
LogUtil.warn(LOG, th, "connection reset by peer");
} else {
LOG.error("Throwable thrown, this should not happen", th);
}
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
resp.setContentLength(0);
} finally {
resp.flushBuffer();
}
}
use of org.xipki.ocsp.api.ResponderAndPath in project xipki by xipki.
the class HttpOcspServlet method doGet.
// method servicePost
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
OcspServer server = ServletHelper.getServer();
if (server == null) {
LOG.error("server in servlet not configured");
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
String path = StringUtil.getRelativeRequestUri(req.getServletPath(), req.getRequestURI());
ResponderAndPath responderAndPath = server.getResponderForPath(path);
if (responderAndPath == null) {
sendError(resp, HttpServletResponse.SC_NOT_FOUND);
return;
}
String servletPath = responderAndPath.getServletPath();
Responder responder = responderAndPath.getResponder();
if (!responder.supportsHttpGet()) {
sendError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
String b64OcspReq;
int offset = servletPath.length();
// GET URI contains the request and must be much longer than 10.
if (path.length() - offset > 10) {
if (path.charAt(offset) == '/') {
offset++;
}
b64OcspReq = path.substring(offset);
} else {
sendError(resp, HttpServletResponse.SC_BAD_REQUEST);
return;
}
try {
// POST, we support GET for longer requests anyway.
if (b64OcspReq.length() > responder.getMaxRequestSize()) {
sendError(resp, HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);
return;
}
OcspRespWithCacheInfo ocspRespWithCacheInfo = server.answer(responder, Base64.decode(b64OcspReq), true);
if (ocspRespWithCacheInfo == null || ocspRespWithCacheInfo.getResponse() == null) {
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
byte[] encodedOcspResp = ocspRespWithCacheInfo.getResponse();
OcspRespWithCacheInfo.ResponseCacheInfo cacheInfo = ocspRespWithCacheInfo.getCacheInfo();
if (cacheInfo != null) {
encodedOcspResp = ocspRespWithCacheInfo.getResponse();
long now = System.currentTimeMillis();
// RFC 5019 6.2: Date: The date and time at which the OCSP server generated
// the HTTP response.
resp.addDateHeader("Date", now);
// RFC 5019 6.2: Last-Modified: date and time at which the OCSP responder
// last modified the response.
resp.addDateHeader("Last-Modified", cacheInfo.getThisUpdate());
// This is overridden by max-age on HTTP/1.1 compatible components
if (cacheInfo.getNextUpdate() != null) {
resp.addDateHeader("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.
resp.addHeader("ETag", StringUtil.concat("\\", HashAlgo.SHA1.hexHash(encodedOcspResp), "\\"));
// Max age must be in seconds in the cache-control header
long maxAge;
if (responder.getCacheMaxAge() != null) {
maxAge = responder.getCacheMaxAge().longValue();
} else {
maxAge = DFLT_CACHE_MAX_AGE;
}
if (cacheInfo.getNextUpdate() != null) {
maxAge = Math.min(maxAge, (cacheInfo.getNextUpdate() - cacheInfo.getThisUpdate()) / 1000);
}
resp.addHeader("Cache-Control", StringUtil.concat("max-age=", Long.toString(maxAge), ",public,no-transform,must-revalidate"));
}
// end if (ocspRespWithCacheInfo)
resp.setContentLength(encodedOcspResp.length);
resp.setContentType(CT_RESPONSE);
resp.getOutputStream().write(encodedOcspResp);
} catch (Throwable th) {
if (th instanceof EOFException) {
LogUtil.warn(LOG, th, "Connection reset by peer");
} else {
LOG.error("Throwable thrown, this should not happen!", th);
}
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
resp.flushBuffer();
}
}
Aggregations