/* * Copyright 2014-2016 CyberVision, Inc. * * 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 org.kaaproject.kaa.server.transports.http.transport.commands; import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION; import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH; import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE; import static io.netty.handler.codec.http.HttpResponseStatus.OK; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; import static org.apache.commons.codec.binary.Base64.encodeBase64String; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.multipart.Attribute; import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory; import io.netty.handler.codec.http.multipart.HttpDataFactory; import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder; import io.netty.handler.codec.http.multipart.InterfaceHttpData; import io.netty.handler.codec.http.multipart.InterfaceHttpData.HttpDataType; import org.apache.commons.codec.binary.Base64; import org.kaaproject.kaa.common.Constants; import org.kaaproject.kaa.common.endpoint.CommonEpConstans; import org.kaaproject.kaa.common.endpoint.security.MessageEncoderDecoder; import org.kaaproject.kaa.server.common.server.BadRequestException; import org.kaaproject.kaa.server.transport.channel.ChannelType; import org.kaaproject.kaa.server.transports.http.transport.netty.AbstractCommand; import java.io.IOException; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import java.util.Arrays; import java.util.List; public abstract class AbstractHttpSyncCommand extends AbstractCommand { private byte[] requestSignature; private byte[] requestKey; private byte[] requestData; private byte[] responseBody; private byte[] responseSignature; private int nextProtocol = Constants.KAA_PLATFORM_PROTOCOL_AVRO_ID; /** * Instantiates a new abstract operations command. */ public AbstractHttpSyncCommand() { super(); } public static String getCommandName() { return COMMAND_NAME; } /** * Gets the type of channel that issued this command. * * @return the response converter class */ public abstract ChannelType getChannelType(); /* * (non-Javadoc) * * @see * org.kaaproject.kaa.server.common.http.server.CommandProcessor#parse() */ @Override public void parse() throws Exception { LOG.trace("CommandName: " + COMMAND_NAME + ": Parse.."); HttpDataFactory factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE); HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(factory, getRequest()); if (decoder.isMultipart()) { LOG.trace("Chunked: " + HttpHeaders.isTransferEncodingChunked(getRequest())); LOG.trace(": Multipart.."); List<InterfaceHttpData> datas = decoder.getBodyHttpDatas(); if (!datas.isEmpty()) { for (InterfaceHttpData data : datas) { LOG.trace("Multipart1 name " + data.getName() + " type " + data.getHttpDataType().name()); if (data.getHttpDataType() == HttpDataType.Attribute) { Attribute attribute = (Attribute) data; if (CommonEpConstans.REQUEST_SIGNATURE_ATTR_NAME.equals(data.getName())) { requestSignature = attribute.get(); if (LOG.isTraceEnabled()) { LOG.trace("Multipart name " + data.getName() + " type " + data.getHttpDataType().name() + " Signature set. size: " + requestSignature.length); LOG.trace(MessageEncoderDecoder.bytesToHex(requestSignature)); } } else if (CommonEpConstans.REQUEST_KEY_ATTR_NAME.equals(data.getName())) { requestKey = attribute.get(); if (LOG.isTraceEnabled()) { LOG.trace("Multipart name " + data.getName() + " type " + data.getHttpDataType().name() + " requestKey set. size: " + requestKey.length); LOG.trace(MessageEncoderDecoder.bytesToHex(requestKey)); } } else if (CommonEpConstans.REQUEST_DATA_ATTR_NAME.equals(data.getName())) { requestData = attribute.get(); if (LOG.isTraceEnabled()) { LOG.trace("Multipart name " + data.getName() + " type " + data.getHttpDataType().name() + " requestData set. size: " + requestData.length); LOG.trace(MessageEncoderDecoder.bytesToHex(requestData)); } } else if (CommonEpConstans.NEXT_PROTOCOL_ATTR_NAME.equals(data.getName())) { nextProtocol = ByteBuffer.wrap(attribute.get()).getInt(); LOG.trace("[{}] next protocol is {}", getSessionUuid(), nextProtocol); } } } } else { LOG.error("Multipart.. size 0"); throw new BadRequestException("HTTP Request inccorect, multiprat size is 0"); } } } /* * (non-Javadoc) * * @see * org.kaaproject.kaa.server.common.http.server.CommandProcessor#Process () */ @Override public void process() throws BadRequestException, GeneralSecurityException, IOException { } public byte[] getRequestSignature() { return requestSignature; } public byte[] getRequestkey() { return requestKey; } public byte[] getRequestData() { return requestData; } public byte[] getResponseBody() { return responseBody; } public void setResponseBody(byte[] responseBody) { this.responseBody = responseBody; } public byte[] getResponseSignature() { return responseSignature; } public void setResponseSignature(byte[] responseSignature) { this.responseSignature = responseSignature; } /* * (non-Javadoc) * * @see org.kaaproject.kaa.server.common.http.server.CommandProcessor# * getHttpResponse() */ @Override public HttpResponse getResponse() { LOG.trace("CommandName: " + COMMAND_NAME + ": getHttpResponse.."); ByteBuf data = Unpooled.copiedBuffer(responseBody); LOG.warn("Response data: {}", Arrays.toString(data.array())); FullHttpResponse httpResponse = new DefaultFullHttpResponse(HTTP_1_1, OK, data); httpResponse.headers().set(CONTENT_TYPE, CommonEpConstans.RESPONSE_CONTENT_TYPE); httpResponse.headers().set(CONTENT_LENGTH, data.readableBytes()); LOG.warn("Response size: {}", data.readableBytes()); httpResponse .headers() .set(CommonEpConstans.RESPONSE_TYPE, CommonEpConstans.RESPONSE_TYPE_OPERATION); if (responseSignature != null) { httpResponse .headers() .set(CommonEpConstans.SIGNATURE_HEADER_NAME, encodeBase64String(responseSignature)); } if (isNeedConnectionClose()) { httpResponse.headers().set(CONNECTION, HttpHeaders.Values.CLOSE); } else { if (HttpHeaders.isKeepAlive(getRequest())) { httpResponse.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } else { httpResponse.headers().set(CONNECTION, HttpHeaders.Values.CLOSE); } } return httpResponse; } @Override public int getNextProtocol() { return nextProtocol; } }