blob: 788228e19fd578a0c914a9cba4cf8e966663e0c5 [file] [log] [blame]
/*
* Copyright (c) 2017 CEA.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* CEA - initial API and implementation
*/
package org.eclipse.sensinact.gateway.nthbnd.http.callback;
import org.eclipse.sensinact.gateway.common.bundle.Mediator;
import javax.servlet.AsyncContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
/**
* Holds data structures and helper methods to process a {@link ServletRequest}
* and to build the appropriate {@link ServletResponse}
*/
public class CallbackContext {
private static final int BUFFER_SIZE = 64 * 1024;
private Mediator mediator;
private AsyncContext asyncContext;
private String method;
private byte[] content;
/**
* Constructor
*
* @param mediator the {@link Mediator} allowing the CallbackContext
* to be instantiated to interact with the OSGi host environment
* @param method the String name of the HTTP method
* @param asyncContext the {@link AsyncContext}
*/
public CallbackContext(Mediator mediator, String method, AsyncContext asyncContext) {
this.asyncContext = asyncContext;
this.method = method;
if (this.asyncContext == null) {
throw new NullPointerException("Null AsyncContext");
}
}
/**
* Returns the String name of the HTTP method of the call that
* is at the origin of this CallbackContext birth
*
* @return the HTTP method String name
*/
public String getMethod() {
return this.method;
}
/**
* Returns the {@link AsyncContext} of this CallbackContext
*
* @return this CallbackContext's {@link AsyncContext}
*/
public AsyncContext getAsyncContext() {
return this.asyncContext;
}
/**
* Returns the {@link HttpServletRequest} of the {@link AsyncContext}
* of this CallbackContext
*
* @return the {@link HttpServletRequest} of this CallbackContext's
* {@link AsyncContext}
*/
public HttpServletRequest getRequest() {
return (HttpServletRequest) getAsyncContext().getRequest();
}
/**
* Returns the {@link HttpServletResponse} of the {@link AsyncContext}
* of this CallbackContext
*
* @return the {@link HttpServletResponse} of this CallbackContext's
* {@link AsyncContext}
*/
public HttpServletResponse getResponse() {
return (HttpServletResponse) getAsyncContext().getResponse();
}
/**
* Returns the bytes array content of the {@link HttpServletRequest} attached
* to the {@link AsyncContext} of this CallbackContext
*
* @return the bytes array content of the {@link HttpServletRequest} processed
* @throws IOException if an input or output exception occurred
*/
public byte[] getRequestContent() throws IOException {
if (this.content == null) {
int read = 0;
int pos = 0;
byte[] buffer = new byte[BUFFER_SIZE];
int length = getRequest().getContentLength();
byte[] content = new byte[pos];
try {
InputStream input = getRequest().getInputStream();
while (true) {
if (length > -1 && pos >= length) {
break;
}
read = input.read(buffer);
if (read == -1) {
break;
}
byte[] newContent = new byte[pos + read];
if (pos > 0) {
System.arraycopy(content, 0, newContent, 0, pos);
}
System.arraycopy(buffer, 0, newContent, pos, read);
content = newContent;
newContent = null;
pos += read;
}
} catch (IOException e) {
mediator.error(e);
throw e;
}
this.content = content;
}
return this.content;
}
/**
* Set the bytes array content of the {@link HttpServletResponse} attached
* to the {@link AsyncContext} of this CallbackContext
*
* @param bytes the bytes array content of to the built {@link HttpServletResponse}
* @throws IOException if an input or output exception occurred
*/
public void setResponseContent(byte[] bytes) throws IOException {
int length = bytes == null ? 0 : bytes.length;
if (length > 0) {
HttpServletResponse response = getResponse();
response.setContentLength(length);
response.setBufferSize(length);
ServletOutputStream output = response.getOutputStream();
output.write(bytes);
}
}
/**
* Set the bytes array content of the {@link HttpServletResponse} of
* this CallbackContext's {@link AsyncContext}
*
* @param bytes the bytes array content to be set as content of the
* {@link HttpServletResponse}
* @throws IOException if an input or output exception occurred
*/
public void setResponseStatus(int status) {
getResponse().setStatus(status);
}
/**
* Set the error status and message of the {@link HttpServletResponse} of
* this CallbackContext's {@link AsyncContext}
*
* @param status the int error status
* @param message the String error message
* @throws IOException if an input or output exception occurred
*/
public void setResponseError(int status, String message) throws IOException {
getResponse().sendError(status, message);
}
}