@Override
  public void messageReceived(ChannelHandlerContext ctx, MessageEvent event) throws Exception {
    if (event.getMessage() instanceof MappingHttpRequest) {
      MappingHttpRequest httpRequest = (MappingHttpRequest) event.getMessage();

      if (httpRequest.getMessage() instanceof ObjectStorageDataRequestType) {
        if (httpRequest.isChunked()) {
          // Chunked request, and beginning, setup map etc.
          initializeNewPut(ctx, (ObjectStorageDataRequestType) httpRequest.getMessage());
        }
      }
    } else if (event.getMessage() instanceof HttpChunk) {
      // Add the chunk to the current streams channel buffer.
      HttpChunk chunk = (HttpChunk) event.getMessage();
      appendChunk(chunk.getContent(), ctx.getChannel());

      if (chunk.isLast()) {
        // Remove from the map
        Logs.extreme()
            .debug(
                "Removing data map due to last chunk processed event for channel: "
                    + ctx.getChannel().getId());
        dataMap.remove(ctx.getChannel());
      }
    }
    // Always pass it on
    ctx.sendUpstream(event);
  }
  @Override
  public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent e)
      throws Exception {

    if (!chunked) {
      final HttpRequest request = (HttpRequest) e.getMessage();

      final ChannelBuffer buffer = request.getContent();
      receivedData.write(buffer.array());
      // System.out.println("received "+buffer.array() );
      // System.out.println(buffer.array().length);
      if (!request.isChunked()) {
        processRequest(e);
      } else {
        chunked = true;
      }
      // final boolean keepAlive = isKeepAlive(request);
    } else {
      final HttpChunk chunk = (HttpChunk) e.getMessage();
      final ChannelBuffer buffer = chunk.getContent();
      receivedData.write(buffer.array());
      if (chunk.isLast()) {
        processRequest(e);
      }
    }
  }
 /**
  * Initialized the internals from a new chunk
  *
  * @param chunk the new received chunk
  * @throws ErrorDataDecoderException if there is a problem with the charset decoding or other
  *     errors
  */
 public void offer(HttpChunk chunk) throws ErrorDataDecoderException {
   ChannelBuffer chunked = chunk.getContent();
   if (undecodedChunk == null) {
     undecodedChunk = chunked;
   } else {
     // undecodedChunk = ChannelBuffers.wrappedBuffer(undecodedChunk, chunk.getContent());
     // less memory usage
     undecodedChunk = ChannelBuffers.wrappedBuffer(undecodedChunk, chunked);
   }
   if (chunk.isLast()) {
     isLastChunk = true;
   }
   parseBody();
 }
 void chunk(HttpChunk chunk) throws Exception {
   Preconditions.checkState(
       bodyConsumer != null, "Received chunked content without BodyConsumer.");
   if (chunk.isLast()) {
     bodyConsumer.finished(responder);
     bodyConsumer = null;
   } else {
     try {
       bodyConsumer.chunk(chunk.getContent(), responder);
     } catch (Throwable t) {
       bodyConsumer.handleError(t);
       bodyConsumer = null;
       throw new HandlerException(HttpResponseStatus.INTERNAL_SERVER_ERROR, "", t);
     }
   }
 }
  @Override
  protected void httpMessageReceived(
      ChannelHandlerContext ctx, MessageEvent e, HttpChunk httpMessage) throws Exception {
    ChannelBuffer content = httpMessage.getContent();
    if (content.readable()) {
      fireMessageReceived(httpChildChannel, content);
    }

    boolean last = httpMessage.isLast();
    if (last) {
      HttpChildChannel httpChildChannel = this.httpChildChannel;
      httpChildChannel.readState(HttpReadState.CONTENT_COMPLETE);
      this.httpChildChannel = null;
      fireInputShutdown(httpChildChannel);
      if (httpChildChannel.setReadClosed()) {
        fireChannelDisconnected(httpChildChannel);
        fireChannelUnbound(httpChildChannel);
        fireChannelClosed(httpChildChannel);
      }
    }
  }
  @Override
  public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
    if (!readingChunks) {
      request = (HttpRequest) e.getMessage();

      if (is100ContinueExpected(request)) {
        send100Continue(e);
      }

      if (request.isChunked()) {
        readingChunks = true;
      } else {
        writeObject(e, request);
      }
    } else {
      HttpChunk chunk = (HttpChunk) e.getMessage();
      if (chunk.isLast()) {
        readingChunks = false;
        writeObject(e, chunk);
      }
    }
  }
Example #7
0
    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {

      Channel ch = e.getChannel();
      ClientConnection conn = connectionMap.get(ch);
      Object msg = e.getMessage();
      if (msg instanceof HttpResponse) {
        HttpResponse response = (HttpResponse) msg;

        conn.handleResponse(response);
        ChannelBuffer content = response.getContent();
        if (content.readable()) {
          conn.handleResponseChunk(new Buffer(content));
        }
        if (!response.isChunked()) {
          conn.handleResponseEnd();
        }
      } else if (msg instanceof HttpChunk) {
        HttpChunk chunk = (HttpChunk) msg;
        if (chunk.getContent().readable()) {
          Buffer buff = new Buffer(chunk.getContent());
          conn.handleResponseChunk(buff);
        }
        if (chunk.isLast()) {
          if (chunk instanceof HttpChunkTrailer) {
            HttpChunkTrailer trailer = (HttpChunkTrailer) chunk;
            conn.handleResponseEnd(trailer);
          } else {
            conn.handleResponseEnd();
          }
        }
      } else if (msg instanceof WebSocketFrame) {
        WebSocketFrame frame = (WebSocketFrame) msg;
        conn.handleWsFrame(frame);
      } else {
        throw new IllegalStateException("Invalid object " + e.getMessage());
      }
    }
  @Override
  protected Object decode(
      ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state)
      throws Exception {
    switch (state) {
      case SKIP_CONTROL_CHARS:
        {
          try {
            skipControlCharacters(buffer);
            checkpoint(State.READ_INITIAL);
          } finally {
            checkpoint();
          }
        }
      case READ_INITIAL:
        {
          final String[] initialLine = splitInitialLine(readLine(buffer, maxInitialLineLength));
          if (initialLine.length < 3) {
            // Invalid initial line - ignore.
            checkpoint(State.SKIP_CONTROL_CHARS);
            return null;
          }
          message = createMessage(initialLine);
          checkpoint(State.READ_HEADER);
        }
      case READ_HEADER:
        {
          State nextState = readHeaders(buffer);
          checkpoint(nextState);
          if (nextState == State.SKIP_CONTROL_CHARS) {
            return message;
          } else {
            long contentLength = getContentLength(message, -1);
            if (contentLength == 0 || contentLength == -1 && isDecodingRequest()) {
              content = ChannelBuffers.EMPTY_BUFFER;
              return reset();
            }

            switch (nextState) {
              case READ_FIXED_LENGTH_CONTENT:
                if (contentLength > maxChunkSize || HttpHeaders.is100ContinueExpected(message)) {
                  // Generate HttpMessage first. HttpChunks will follow.
                  checkpoint(State.READ_FIXED_LENGTH_CONTENT_AS_CHUNKS);
                  message.setChunked(true);
                  // chunkSize will be decreased as the READ_FIXED_LENGTH_CONTENT_AS_CHUNKS
                  // state reads data chunk by chunk.
                  chunkSize = getContentLength(message, -1);
                  return message;
                }
                break;
              case READ_VARIABLE_LENGTH_CONTENT:
                if (buffer.readableBytes() > maxChunkSize
                    || HttpHeaders.is100ContinueExpected(message)) {
                  // Generate HttpMessage first. HttpChunks will follow.
                  checkpoint(State.READ_VARIABLE_LENGTH_CONTENT_AS_CHUNKS);
                  message.setChunked(true);
                  return message;
                }
                break;
              default:
                throw new IllegalStateException("Unexpected state: " + nextState);
            }
          }
          // We return null here, this forces decode to be called again where we will decode the
          // content
          return null;
        }
      case READ_VARIABLE_LENGTH_CONTENT:
        {
          if (content == null) {
            content = ChannelBuffers.dynamicBuffer(channel.getConfig().getBufferFactory());
          }
          // this will cause a replay error until the channel is closed where this will read what's
          // left in the buffer
          content.writeBytes(buffer.readBytes(buffer.readableBytes()));
          return reset();
        }
      case READ_VARIABLE_LENGTH_CONTENT_AS_CHUNKS:
        {
          // Keep reading data as a chunk until the end of connection is reached.
          int chunkSize = Math.min(maxChunkSize, buffer.readableBytes());
          HttpChunk chunk = new DefaultHttpChunk(buffer.readBytes(chunkSize));

          if (!buffer.readable()) {
            // Reached to the end of the connection.
            reset();
            if (!chunk.isLast()) {
              // Append the last chunk.
              return new Object[] {chunk, HttpChunk.LAST_CHUNK};
            }
          }
          return chunk;
        }
      case READ_FIXED_LENGTH_CONTENT:
        {
          // we have a content-length so we just read the correct number of bytes
          readFixedLengthContent(buffer);
          return reset();
        }
      case READ_FIXED_LENGTH_CONTENT_AS_CHUNKS:
        {
          long chunkSize = this.chunkSize;
          HttpChunk chunk;
          if (chunkSize > maxChunkSize) {
            chunk = new DefaultHttpChunk(buffer.readBytes(maxChunkSize));
            chunkSize -= maxChunkSize;
          } else {
            assert chunkSize <= Integer.MAX_VALUE;
            chunk = new DefaultHttpChunk(buffer.readBytes((int) chunkSize));
            chunkSize = 0;
          }
          this.chunkSize = chunkSize;

          if (chunkSize == 0) {
            // Read all content.
            reset();
            if (!chunk.isLast()) {
              // Append the last chunk.
              return new Object[] {chunk, HttpChunk.LAST_CHUNK};
            }
          }
          return chunk;
        }
        /**
         * everything else after this point takes care of reading chunked content. basically, read
         * chunk size, read chunk, read and ignore the CRLF and repeat until 0
         */
      case READ_CHUNK_SIZE:
        {
          String line = readLine(buffer, maxInitialLineLength);
          int chunkSize = getChunkSize(line);
          this.chunkSize = chunkSize;
          if (chunkSize == 0) {
            checkpoint(State.READ_CHUNK_FOOTER);
            return null;
          } else if (chunkSize > maxChunkSize) {
            // A chunk is too large. Split them into multiple chunks again.
            checkpoint(State.READ_CHUNKED_CONTENT_AS_CHUNKS);
          } else {
            checkpoint(State.READ_CHUNKED_CONTENT);
          }
        }
      case READ_CHUNKED_CONTENT:
        {
          assert chunkSize <= Integer.MAX_VALUE;
          HttpChunk chunk = new DefaultHttpChunk(buffer.readBytes((int) chunkSize));
          checkpoint(State.READ_CHUNK_DELIMITER);
          return chunk;
        }
      case READ_CHUNKED_CONTENT_AS_CHUNKS:
        {
          long chunkSize = this.chunkSize;
          HttpChunk chunk;
          if (chunkSize > maxChunkSize) {
            chunk = new DefaultHttpChunk(buffer.readBytes(maxChunkSize));
            chunkSize -= maxChunkSize;
          } else {
            assert chunkSize <= Integer.MAX_VALUE;
            chunk = new DefaultHttpChunk(buffer.readBytes((int) chunkSize));
            chunkSize = 0;
          }
          this.chunkSize = chunkSize;

          if (chunkSize == 0) {
            // Read all content.
            checkpoint(State.READ_CHUNK_DELIMITER);
          }

          if (!chunk.isLast()) {
            return chunk;
          }
        }
      case READ_CHUNK_DELIMITER:
        {
          for (; ; ) {
            byte next = buffer.readByte();
            if (next == HttpCodecUtil.CR) {
              if (buffer.readByte() == HttpCodecUtil.LF) {
                checkpoint(State.READ_CHUNK_SIZE);
                return null;
              }
            } else if (next == HttpCodecUtil.LF) {
              checkpoint(State.READ_CHUNK_SIZE);
              return null;
            }
          }
        }
      case READ_CHUNK_FOOTER:
        {
          HttpChunkTrailer trailer = readTrailingHeaders(buffer);
          if (maxChunkSize == 0) {
            // Chunked encoding disabled.
            return reset();
          } else {
            reset();
            // The last chunk, which is empty
            return trailer;
          }
        }
      default:
        {
          throw new Error("Shouldn't reach here.");
        }
    }
  }
Example #9
0
    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
      if (!readingChunks) {
        HttpResponse response = (HttpResponse) e.getMessage();

        StringBuilder sb = new StringBuilder();
        if (LOG.isDebugEnabled()) {
          sb.append("STATUS: ")
              .append(response.getStatus())
              .append(", VERSION: ")
              .append(response.getProtocolVersion())
              .append(", HEADER: ");
        }
        if (!response.getHeaderNames().isEmpty()) {
          for (String name : response.getHeaderNames()) {
            for (String value : response.getHeaders(name)) {
              if (LOG.isDebugEnabled()) {
                sb.append(name + " = " + value);
              }
              if (this.length == -1 && name.equals("Content-Length")) {
                this.length = Long.valueOf(value);
              }
            }
          }
        }
        if (LOG.isDebugEnabled()) {
          LOG.debug(sb.toString());
        }

        if (response.getStatus() == HttpResponseStatus.NO_CONTENT) {
          LOG.info("There are no data corresponding to the request");
          return;
        }

        this.raf = new RandomAccessFile(file, "rw");
        this.fc = raf.getChannel();

        if (response.isChunked()) {
          readingChunks = true;
        } else {
          ChannelBuffer content = response.getContent();
          if (content.readable()) {
            fc.write(content.toByteBuffer());
          }
        }
      } else {
        HttpChunk chunk = (HttpChunk) e.getMessage();
        if (chunk.isLast()) {
          readingChunks = false;
          long fileLength = fc.position();
          fc.close();
          raf.close();
          if (fileLength == length) {
            LOG.info("Data fetch is done (total received bytes: " + fileLength + ")");
          } else {
            LOG.info(
                "Data fetch is done, but cannot get all data "
                    + "(received/total: "
                    + fileLength
                    + "/"
                    + length
                    + ")");
          }
        } else {
          fc.write(chunk.getContent().toByteBuffer());
        }
      }
    }
 /**
  * Finalize the request by preparing the Header in the request and returns the request ready to be
  * sent.<br>
  * Once finalized, no data must be added.<br>
  * If the request does not need chunk (isChunked() == false), this request is the only object to
  * send to the remote server.
  *
  * @return the request object (chunked or not according to size of body)
  * @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already
  *     done
  */
 public HttpRequest finalizeRequest() throws ErrorDataEncoderException {
   // Finalize the multipartHttpDatas
   if (!headerFinalized) {
     if (isMultipart) {
       InternalAttribute internal = new InternalAttribute();
       if (duringMixedMode) {
         internal.addValue("\r\n--" + multipartMixedBoundary + "--");
       }
       internal.addValue("\r\n--" + multipartDataBoundary + "--\r\n");
       multipartHttpDatas.add(internal);
       multipartMixedBoundary = null;
       currentFileUpload = null;
       duringMixedMode = false;
       globalBodySize += internal.size();
     }
     headerFinalized = true;
   } else {
     throw new ErrorDataEncoderException("Header already encoded");
   }
   List<String> contentTypes = request.getHeaders(HttpHeaders.Names.CONTENT_TYPE);
   List<String> transferEncoding = request.getHeaders(HttpHeaders.Names.TRANSFER_ENCODING);
   if (contentTypes != null) {
     request.removeHeader(HttpHeaders.Names.CONTENT_TYPE);
     for (String contentType : contentTypes) {
       // "multipart/form-data; boundary=--89421926422648"
       if (contentType.toLowerCase().startsWith(HttpHeaders.Values.MULTIPART_FORM_DATA)) {
         // ignore
       } else if (contentType
           .toLowerCase()
           .startsWith(HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED)) {
         // ignore
       } else {
         request.addHeader(HttpHeaders.Names.CONTENT_TYPE, contentType);
       }
     }
   }
   if (isMultipart) {
     String value =
         HttpHeaders.Values.MULTIPART_FORM_DATA
             + "; "
             + HttpHeaders.Values.BOUNDARY
             + "="
             + multipartDataBoundary;
     request.addHeader(HttpHeaders.Names.CONTENT_TYPE, value);
   } else {
     // Not multipart
     request.addHeader(
         HttpHeaders.Names.CONTENT_TYPE, HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED);
   }
   // Now consider size for chunk or not
   long realSize = globalBodySize;
   if (isMultipart) {
     iterator = multipartHttpDatas.listIterator();
   } else {
     realSize -= 1; // last '&' removed
     iterator = multipartHttpDatas.listIterator();
   }
   request.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(realSize));
   if (realSize > HttpPostBodyUtil.chunkSize) {
     isChunked = true;
     if (transferEncoding != null) {
       request.removeHeader(HttpHeaders.Names.TRANSFER_ENCODING);
       for (String v : transferEncoding) {
         if (v.equalsIgnoreCase(HttpHeaders.Values.CHUNKED)) {
           // ignore
         } else {
           request.addHeader(HttpHeaders.Names.TRANSFER_ENCODING, v);
         }
       }
     }
     request.addHeader(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED);
     request.setContent(ChannelBuffers.EMPTY_BUFFER);
   } else {
     // get the only one body and set it to the request
     HttpChunk chunk = nextChunk();
     request.setContent(chunk.getContent());
   }
   return request;
 }