Search in sources :

Example 46 with DefaultHttpResponse

use of org.jboss.netty.handler.codec.http.DefaultHttpResponse in project voldemort by voldemort.

the class GetAllResponseSender method sendResponse.

/**
     * Sends nested multipart response. Outer multipart wraps all the keys
     * requested. Each key has a separate multipart for the versioned values.
     */
@Override
public void sendResponse(StoreStats performanceStats, boolean isFromLocalZone, long startTimeInMs) throws Exception {
    /*
         * Pay attention to the code below. Note that in this method we wrap a multiPart object with a mimeMessage.
         * However when writing to the outputStream we only send the multiPart object and not the entire
         * mimeMessage. This is intentional.
         *
         * In the earlier version of this code we used to create a multiPart object and just send that multiPart
         * across the wire.
         *
         * However, we later discovered that upon setting the content of a MimeBodyPart, JavaMail internally creates
         * a DataHandler object wrapping the object you passed in. The part's Content-Type header is not updated
         * immediately. In order to get the headers updated, one needs to to call MimeMessage.saveChanges() on the
         * enclosing message, which cascades down the MIME structure into a call to MimeBodyPart.updateHeaders()
         * on the body part. It's this updateHeaders call that transfers the content type from the
         * DataHandler to the part's MIME Content-Type header.
         *
         * To make sure that the Content-Type headers are being updated (without changing too much code), we decided
         * to wrap the multiPart in a mimeMessage, call mimeMessage.saveChanges() and then just send the multiPart.
         * This is to make sure multiPart's headers are updated accurately.
         */
    MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
    // multiPartKeys is the outer multipart
    MimeMultipart multiPartKeys = new MimeMultipart();
    ByteArrayOutputStream keysOutputStream = new ByteArrayOutputStream();
    for (Entry<ByteArray, List<Versioned<byte[]>>> entry : versionedResponses.entrySet()) {
        ByteArray key = entry.getKey();
        String base64Key = RestUtils.encodeVoldemortKey(key.get());
        String contentLocationKey = "/" + this.storeName + "/" + base64Key;
        // Create the individual body part - for each key requested
        MimeBodyPart keyBody = new MimeBodyPart();
        try {
            // Add the right headers
            keyBody.addHeader(CONTENT_TYPE, "application/octet-stream");
            keyBody.addHeader(CONTENT_TRANSFER_ENCODING, "binary");
            keyBody.addHeader(CONTENT_LOCATION, contentLocationKey);
        } catch (MessagingException me) {
            logger.error("Exception while constructing key body headers", me);
            keysOutputStream.close();
            throw me;
        }
        // multiPartValues is the inner multipart
        MimeMultipart multiPartValues = new MimeMultipart();
        for (Versioned<byte[]> versionedValue : entry.getValue()) {
            byte[] responseValue = versionedValue.getValue();
            VectorClock vectorClock = (VectorClock) versionedValue.getVersion();
            String eTag = RestUtils.getSerializedVectorClock(vectorClock);
            numVectorClockEntries += vectorClock.getVersionMap().size();
            // Create the individual body part - for each versioned value of
            // a key
            MimeBodyPart valueBody = new MimeBodyPart();
            try {
                // Add the right headers
                valueBody.addHeader(CONTENT_TYPE, "application/octet-stream");
                valueBody.addHeader(CONTENT_TRANSFER_ENCODING, "binary");
                valueBody.addHeader(RestMessageHeaders.X_VOLD_VECTOR_CLOCK, eTag);
                valueBody.setContent(responseValue, "application/octet-stream");
                valueBody.addHeader(RestMessageHeaders.CONTENT_LENGTH, Integer.toString(responseValue.length));
                multiPartValues.addBodyPart(valueBody);
            } catch (MessagingException me) {
                logger.error("Exception while constructing value body part", me);
                keysOutputStream.close();
                throw me;
            }
        }
        try {
            // Add the inner multipart as the content of the outer body part
            keyBody.setContent(multiPartValues);
            multiPartKeys.addBodyPart(keyBody);
        } catch (MessagingException me) {
            logger.error("Exception while constructing key body part", me);
            keysOutputStream.close();
            throw me;
        }
    }
    message.setContent(multiPartKeys);
    message.saveChanges();
    try {
        multiPartKeys.writeTo(keysOutputStream);
    } catch (Exception e) {
        logger.error("Exception while writing mutipart to output stream", e);
        throw e;
    }
    ChannelBuffer responseContent = ChannelBuffers.dynamicBuffer();
    responseContent.writeBytes(keysOutputStream.toByteArray());
    // Create the Response object
    HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
    // Set the right headers
    response.setHeader(CONTENT_TYPE, "multipart/binary");
    response.setHeader(CONTENT_TRANSFER_ENCODING, "binary");
    // Copy the data into the payload
    response.setContent(responseContent);
    response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
    // Write the response to the Netty Channel
    if (logger.isDebugEnabled()) {
        String keyStr = getKeysHexString(this.versionedResponses.keySet());
        debugLog("GET_ALL", this.storeName, keyStr, startTimeInMs, System.currentTimeMillis(), numVectorClockEntries);
    }
    this.messageEvent.getChannel().write(response);
    if (performanceStats != null && isFromLocalZone) {
        recordStats(performanceStats, startTimeInMs, Tracked.GET_ALL);
    }
    keysOutputStream.close();
}
Also used : MessagingException(javax.mail.MessagingException) VectorClock(voldemort.versioning.VectorClock) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse) ByteArrayOutputStream(org.apache.commons.io.output.ByteArrayOutputStream) Properties(java.util.Properties) MessagingException(javax.mail.MessagingException) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) MimeMessage(javax.mail.internet.MimeMessage) MimeMultipart(javax.mail.internet.MimeMultipart) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) ByteArray(voldemort.utils.ByteArray) List(java.util.List) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 47 with DefaultHttpResponse

use of org.jboss.netty.handler.codec.http.DefaultHttpResponse in project voldemort by voldemort.

the class GetMetadataResponseSender method sendResponse.

/**
     * Sends a normal HTTP response containing the serialization information in
     * a XML format
     */
@Override
public void sendResponse(StoreStats performanceStats, boolean isFromLocalZone, long startTimeInMs) throws Exception {
    ChannelBuffer responseContent = ChannelBuffers.dynamicBuffer(this.responseValue.length);
    responseContent.writeBytes(responseValue);
    // 1. Create the Response object
    HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
    // 2. Set the right headers
    response.setHeader(CONTENT_TYPE, "binary");
    response.setHeader(CONTENT_TRANSFER_ENCODING, "binary");
    // 3. Copy the data into the payload
    response.setContent(responseContent);
    response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
    if (logger.isDebugEnabled()) {
        logger.debug("Response = " + response);
    }
    // Write the response to the Netty Channel
    this.messageEvent.getChannel().write(response);
    if (performanceStats != null && isFromLocalZone) {
        recordStats(performanceStats, startTimeInMs, Tracked.GET);
    }
}
Also used : DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer)

Example 48 with DefaultHttpResponse

use of org.jboss.netty.handler.codec.http.DefaultHttpResponse in project voldemort by voldemort.

the class RestErrorHandler method writeErrorResponse.

/**
     * Writes all error responses to the client.
     * 
     * TODO REST-Server 1. collect error stats
     * 
     * @param messageEvent - for retrieving the channel details
     * @param status - error code
     * @param message - error message
     */
public static void writeErrorResponse(MessageEvent messageEvent, HttpResponseStatus status, String message) {
    // Create the Response object
    HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status);
    response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
    response.setContent(ChannelBuffers.copiedBuffer("Failure: " + status.toString() + ". " + message + "\r\n", CharsetUtil.UTF_8));
    response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
    // Write the response to the Netty Channel
    messageEvent.getChannel().write(response);
}
Also used : DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse)

Example 49 with DefaultHttpResponse

use of org.jboss.netty.handler.codec.http.DefaultHttpResponse in project voldemort by voldemort.

the class CoordinatorAdminRequestHandler method sendResponse.

public HttpResponse sendResponse(HttpResponseStatus responseCode, String responseBody) {
    String actualResponseBody = responseBody + "\n";
    HttpResponse response = new DefaultHttpResponse(HTTP_1_1, responseCode);
    response.setHeader(CONTENT_LENGTH, actualResponseBody.length());
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try {
        outputStream.write(actualResponseBody.getBytes());
    } catch (IOException e) {
        logger.error("IOException while trying to write the outputStream for an admin response", e);
        throw new RuntimeException(e);
    }
    ChannelBuffer responseContent = ChannelBuffers.dynamicBuffer();
    responseContent.writeBytes(outputStream.toByteArray());
    response.setContent(responseContent);
    if (logger.isDebugEnabled()) {
        logger.debug("Sent " + response);
    }
    return response;
}
Also used : DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse) ByteArrayOutputStream(org.apache.commons.io.output.ByteArrayOutputStream) IOException(java.io.IOException) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer)

Example 50 with DefaultHttpResponse

use of org.jboss.netty.handler.codec.http.DefaultHttpResponse in project cdap by caskdata.

the class SecurityAuthenticationHttpHandler method validateSecuredInterception.

/**
   * Intercepts the HttpMessage for getting the access token in authorization header
   *
   * @param ctx channel handler context delegated from MessageReceived callback
   * @param msg intercepted HTTP message
   * @param inboundChannel
   * @return {@code true} if the HTTP message has valid Access token
   * @throws Exception
   */
private boolean validateSecuredInterception(ChannelHandlerContext ctx, HttpRequest msg, Channel inboundChannel, AuditLogEntry logEntry) throws Exception {
    String auth = msg.getHeader(HttpHeaders.Names.AUTHORIZATION);
    String accessToken = null;
    /*
     * Parse the access token from authorization header.  The header will be in the form:
     *     Authorization: Bearer ACCESSTOKEN
     *
     * where ACCESSTOKEN is the base64 encoded serialized AccessToken instance.
     */
    if (auth != null) {
        int spIndex = auth.trim().indexOf(' ');
        if (spIndex != -1) {
            accessToken = auth.substring(spIndex + 1).trim();
        }
    }
    HttpMethod httpMethod = msg.getMethod();
    String uri = msg.getUri();
    logEntry.setClientIP(((InetSocketAddress) ctx.getChannel().getRemoteAddress()).getAddress());
    logEntry.setRequestLine(httpMethod, uri, msg.getProtocolVersion());
    TokenState tokenState = tokenValidator.validate(accessToken);
    if (!tokenState.isValid()) {
        HttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.UNAUTHORIZED);
        logEntry.setResponseCode(HttpResponseStatus.UNAUTHORIZED.getCode());
        JsonObject jsonObject = new JsonObject();
        if (tokenState == TokenState.MISSING) {
            httpResponse.addHeader(HttpHeaders.Names.WWW_AUTHENTICATE, String.format("Bearer realm=\"%s\"", realm));
            LOG.debug("Authentication failed due to missing token");
        } else {
            httpResponse.addHeader(HttpHeaders.Names.WWW_AUTHENTICATE, String.format("Bearer realm=\"%s\" error=\"invalid_token\"" + " error_description=\"%s\"", realm, tokenState.getMsg()));
            jsonObject.addProperty("error", "invalid_token");
            jsonObject.addProperty("error_description", tokenState.getMsg());
            LOG.debug("Authentication failed due to invalid token, reason={};", tokenState);
        }
        JsonArray externalAuthenticationURIs = new JsonArray();
        // Waiting for service to get discovered
        stopWatchWait(externalAuthenticationURIs);
        jsonObject.add("auth_uri", externalAuthenticationURIs);
        ChannelBuffer content = ChannelBuffers.wrappedBuffer(jsonObject.toString().getBytes(Charsets.UTF_8));
        httpResponse.setContent(content);
        int contentLength = content.readableBytes();
        httpResponse.setHeader(HttpHeaders.Names.CONTENT_LENGTH, contentLength);
        httpResponse.setHeader(HttpHeaders.Names.CONTENT_TYPE, "application/json;charset=UTF-8");
        logEntry.setResponseContentLength(new Long(contentLength));
        ChannelFuture writeFuture = Channels.future(inboundChannel);
        Channels.write(ctx, writeFuture, httpResponse);
        writeFuture.addListener(ChannelFutureListener.CLOSE);
        return false;
    } else {
        AccessTokenTransformer.AccessTokenIdentifierPair accessTokenIdentifierPair = accessTokenTransformer.transform(accessToken);
        AuditLogContent auditLogContent = AUDIT_LOG_LOOKUP_METHOD.contains(httpMethod) ? AUDIT_LOOK_UP.getAuditLogContent(msg.getUri(), httpMethod) : null;
        if (auditLogContent != null) {
            List<String> headerNames = auditLogContent.getHeaderNames();
            if (!headerNames.isEmpty()) {
                Map<String, String> headers = new HashMap<>();
                for (String headerName : headerNames) {
                    headers.put(headerName, msg.getHeader(headerName));
                }
                logEntry.setHeaders(headers);
            }
            if (auditLogContent.isLogRequestBody()) {
                ChannelBuffer body = msg.getContent();
                if (body.readable()) {
                    logEntry.setRequestBody(body.toString(Charsets.UTF_8));
                }
            }
            logEntry.setLogResponseBody(auditLogContent.isLogResponsebody());
        }
        logEntry.setUserName(accessTokenIdentifierPair.getAccessTokenIdentifierObj().getUsername());
        msg.setHeader(HttpHeaders.Names.AUTHORIZATION, "CDAP-verified " + accessTokenIdentifierPair.getAccessTokenIdentifierStr());
        msg.setHeader(Constants.Security.Headers.USER_ID, accessTokenIdentifierPair.getAccessTokenIdentifierObj().getUsername());
        msg.setHeader(Constants.Security.Headers.USER_IP, ((InetSocketAddress) ctx.getChannel().getRemoteAddress()).getAddress().getHostAddress());
        return true;
    }
}
Also used : ChannelFuture(org.jboss.netty.channel.ChannelFuture) HashMap(java.util.HashMap) InetSocketAddress(java.net.InetSocketAddress) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse) JsonObject(com.google.gson.JsonObject) TokenState(co.cask.cdap.security.auth.TokenState) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) JsonArray(com.google.gson.JsonArray) AccessTokenTransformer(co.cask.cdap.security.auth.AccessTokenTransformer) AuditLogContent(co.cask.cdap.common.logging.AuditLogContent) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpMethod(org.jboss.netty.handler.codec.http.HttpMethod)

Aggregations

DefaultHttpResponse (org.jboss.netty.handler.codec.http.DefaultHttpResponse)117 HttpResponse (org.jboss.netty.handler.codec.http.HttpResponse)92 ChannelBuffer (org.jboss.netty.buffer.ChannelBuffer)66 Test (org.testng.annotations.Test)54 DefaultHttpChunk (org.jboss.netty.handler.codec.http.DefaultHttpChunk)52 HttpChunk (org.jboss.netty.handler.codec.http.HttpChunk)51 DefaultHttpChunkTrailer (org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer)38 HttpChunkTrailer (org.jboss.netty.handler.codec.http.HttpChunkTrailer)34 ChannelFuture (org.jboss.netty.channel.ChannelFuture)31 Checkpoint (com.linkedin.databus.core.Checkpoint)25 BootstrapDatabaseTooOldException (com.linkedin.databus2.core.container.request.BootstrapDatabaseTooOldException)25 Channel (org.jboss.netty.channel.Channel)19 DefaultHttpRequest (org.jboss.netty.handler.codec.http.DefaultHttpRequest)19 ConditionCheck (com.linkedin.databus2.test.ConditionCheck)18 HttpRequest (org.jboss.netty.handler.codec.http.HttpRequest)18 InetSocketAddress (java.net.InetSocketAddress)17 SocketAddress (java.net.SocketAddress)16 Logger (org.apache.log4j.Logger)15 Test (org.junit.Test)11 SucceededChannelFuture (org.jboss.netty.channel.SucceededChannelFuture)10