/**
   * Flush the response contents to the output channel
   *
   * @param channel Channel to be used
   */
  private void writeResponse(Channel channel) {
    // Convert the response content to a ChannelBuffer.
    ByteBuf buf = copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
    responseContent.setLength(0);

    // Decide whether to close the connection or not.
    boolean close =
        HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION))
            || request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
                && !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(
                    request.headers().get(CONNECTION));

    // Build the response object.
    FullHttpResponse response =
        new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
    response.headers().set(CONTENT_TYPE, "application/json; charset=UTF-8");

    if (!close) {
      // There's no need to add 'Content-Length' header
      // if this is the last response.
      response.headers().set(CONTENT_LENGTH, buf.readableBytes());
    }

    try {
      // Write the response.
      ChannelFuture future = channel.writeAndFlush(response);
      // Close the connection after the write operation is done if necessary.
      if (close) {
        future.addListener(ChannelFutureListener.CLOSE);
      }
    } catch (Exception e) {
      logger.error("{}", e);
    }
  }
 private static String contentDisposition(
     HttpProtocolInfo.Disposition disposition, String filename) {
   StringBuilder sb = new StringBuilder();
   sb.append(disposition.toString().toLowerCase());
   appendDispositionParm(sb, "filename", filename);
   // REVISIT consider more info: creation-date, last-modified-date, size
   return sb.toString();
 }
 /** Cleanup */
 private void reset() {
   request = null;
   requestContent.setLength(0);
   responseContent.setLength(0);
   try {
     queueSend.close();
   } catch (JMSException e) {
     logger.error("{}", e);
   }
 }
  private static void appendDispositionParm(StringBuilder sb, String name, String value) {
    sb.append(';');

    // See RFC 2183 part 2. for description of when and how to encode
    if (value.length() > 78 || !CharMatcher.ascii().matchesAllOf(value)) {
      appendUsingRfc2231Encoding(sb, name, "UTF-8", null, value);
    } else if (TSPECIAL.matchesAnyOf(value)) {
      appendAsQuotedString(sb, name, value);
    } else {
      sb.append(name).append("=").append(value);
    }
  }
 private static void appendUsingRfc2231Encoding(
     StringBuilder sb, String name, String charSet, String language, String value) {
   sb.append(name).append("*=");
   if (charSet != null) {
     sb.append(charSet);
   }
   sb.append('\'');
   if (language != null) {
     sb.append(language);
   }
   sb.append('\'');
   percentEncode(sb, value);
 }
  private void writeResponse(Channel channel) {
    // Convert the response content to a ChannelBuffer.
    ByteBuf buf = copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
    responseContent.setLength(0);

    // Decide whether to close the connection or not.
    boolean close =
        request.headers().contains(CONNECTION, HttpHeaders.Values.CLOSE, true)
            || request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
                && !request.headers().contains(CONNECTION, HttpHeaders.Values.KEEP_ALIVE, true);

    // Build the response object.
    FullHttpResponse response =
        new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
    response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");

    if (!close) {
      // There's no need to add 'Content-Length' header
      // if this is the last response.
      response.headers().set(CONTENT_LENGTH, buf.readableBytes());
    }

    Set<Cookie> cookies;
    String value = request.headers().get(COOKIE);
    if (value == null) {
      cookies = Collections.emptySet();
    } else {
      cookies = CookieDecoder.decode(value);
    }
    if (!cookies.isEmpty()) {
      // Reset the cookies if necessary.
      for (Cookie cookie : cookies) {
        response.headers().add(SET_COOKIE, ServerCookieEncoder.encode(cookie));
      }
    }
    // Write the response.
    ChannelFuture future = channel.writeAndFlush(response);
    // Close the connection after the write operation is done if necessary.
    if (close) {
      future.addListener(ChannelFutureListener.CLOSE);
    }
  }
  /** {@inheritDoc} */
  @Override
  public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
    if (msg instanceof HttpRequest) {
      HttpRequest request = this.request = (HttpRequest) msg;
      trackingType = setTrackingType(request);
    }

    if (msg instanceof HttpContent) {
      // New chunk is received
      HttpContent chunk = (HttpContent) msg;
      requestContent.append(chunk.content().toString(Charset.defaultCharset()));
      if (chunk instanceof LastHttpContent) {
        // All chunks have been received
        ResultTO resultTO = submitPayload(requestContent.toString());
        responseContent.append(gson.toJson(resultTO));
        writeResponse(ctx.channel());
        reset();
      }
    }
  }
 /** Example of reading request by chunk and getting values from chunk to chunk */
 private void readHttpDataChunkByChunk() {
   try {
     while (decoder.hasNext()) {
       InterfaceHttpData data = decoder.next();
       if (data != null) {
         try {
           // new value
           writeHttpData(data);
         } finally {
           data.release();
         }
       }
     }
   } catch (EndOfDataDecoderException e1) {
     // end
     responseContent.append("\r\n\r\nEND OF CONTENT CHUNK BY CHUNK\r\n\r\n");
   }
 }
  @Override
  public void messageReceived(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
    if (msg instanceof HttpRequest) {
      HttpRequest request = this.request = (HttpRequest) msg;
      URI uri = new URI(request.getUri());
      if (!uri.getPath().startsWith("/form")) {
        // Write Menu
        writeMenu(ctx);
        return;
      }
      responseContent.setLength(0);
      responseContent.append("WELCOME TO THE WILD WILD WEB SERVER\r\n");
      responseContent.append("===================================\r\n");

      responseContent.append("VERSION: " + request.getProtocolVersion().text() + "\r\n");

      responseContent.append("REQUEST_URI: " + request.getUri() + "\r\n\r\n");
      responseContent.append("\r\n\r\n");

      // new getMethod
      for (Entry<String, String> entry : request.headers()) {
        responseContent.append("HEADER: " + entry.getKey() + '=' + entry.getValue() + "\r\n");
      }
      responseContent.append("\r\n\r\n");

      // new getMethod
      Set<Cookie> cookies;
      String value = request.headers().get(COOKIE);
      if (value == null) {
        cookies = Collections.emptySet();
      } else {
        cookies = CookieDecoder.decode(value);
      }
      for (Cookie cookie : cookies) {
        responseContent.append("COOKIE: " + cookie + "\r\n");
      }
      responseContent.append("\r\n\r\n");

      QueryStringDecoder decoderQuery = new QueryStringDecoder(request.getUri());
      Map<String, List<String>> uriAttributes = decoderQuery.parameters();
      for (Entry<String, List<String>> attr : uriAttributes.entrySet()) {
        for (String attrVal : attr.getValue()) {
          responseContent.append("URI: " + attr.getKey() + '=' + attrVal + "\r\n");
        }
      }
      responseContent.append("\r\n\r\n");

      // if GET Method: should not try to create a HttpPostRequestDecoder
      if (request.getMethod().equals(HttpMethod.GET)) {
        // GET Method: should not try to create a HttpPostRequestDecoder
        // So stop here
        responseContent.append("\r\n\r\nEND OF GET CONTENT\r\n");
        writeResponse(ctx.channel());
        return;
      }
      try {
        decoder = new HttpPostRequestDecoder(factory, request);
      } catch (ErrorDataDecoderException e1) {
        e1.printStackTrace();
        responseContent.append(e1.getMessage());
        writeResponse(ctx.channel());
        ctx.channel().close();
        return;
      }

      readingChunks = HttpHeaders.isTransferEncodingChunked(request);
      responseContent.append("Is Chunked: " + readingChunks + "\r\n");
      responseContent.append("IsMultipart: " + decoder.isMultipart() + "\r\n");
      if (readingChunks) {
        // Chunk version
        responseContent.append("Chunks: ");
        readingChunks = true;
      }
    }

    // check if the decoder was constructed before
    // if not it handles the form get
    if (decoder != null) {
      if (msg instanceof HttpContent) {
        // New chunk is received
        HttpContent chunk = (HttpContent) msg;
        try {
          decoder.offer(chunk);
        } catch (ErrorDataDecoderException e1) {
          e1.printStackTrace();
          responseContent.append(e1.getMessage());
          writeResponse(ctx.channel());
          ctx.channel().close();
          return;
        }
        responseContent.append('o');
        // example of reading chunk by chunk (minimize memory usage due to
        // Factory)
        readHttpDataChunkByChunk();
        // example of reading only if at the end
        if (chunk instanceof LastHttpContent) {
          writeResponse(ctx.channel());
          readingChunks = false;

          reset();
        }
      }
    }
  }
 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
   logger.log(Level.WARNING, responseContent.toString(), cause);
   ctx.channel().close();
 }
  private void writeMenu(ChannelHandlerContext ctx) {
    // print several HTML forms
    // Convert the response content to a ChannelBuffer.
    responseContent.setLength(0);

    // create Pseudo Menu
    responseContent.append("<html>");
    responseContent.append("<head>");
    responseContent.append("<title>Netty Test Form</title>\r\n");
    responseContent.append("</head>\r\n");
    responseContent.append("<body bgcolor=white><style>td{font-size: 12pt;}</style>");

    responseContent.append("<table border=\"0\">");
    responseContent.append("<tr>");
    responseContent.append("<td>");
    responseContent.append("<h1>Netty Test Form</h1>");
    responseContent.append("Choose one FORM");
    responseContent.append("</td>");
    responseContent.append("</tr>");
    responseContent.append("</table>\r\n");

    // GET
    responseContent.append("<CENTER>GET FORM<HR WIDTH=\"75%\" NOSHADE color=\"blue\"></CENTER>");
    responseContent.append("<FORM ACTION=\"/formget\" METHOD=\"GET\">");
    responseContent.append("<input type=hidden name=getform value=\"GET\">");
    responseContent.append("<table border=\"0\">");
    responseContent.append(
        "<tr><td>Fill with value: <br> <input type=text name=\"info\" size=10></td></tr>");
    responseContent.append(
        "<tr><td>Fill with value: <br> <input type=text name=\"secondinfo\" size=20>");
    responseContent.append(
        "<tr><td>Fill with value: <br> <textarea name=\"thirdinfo\" cols=40 rows=10></textarea>");
    responseContent.append("</td></tr>");
    responseContent.append(
        "<tr><td><INPUT TYPE=\"submit\" NAME=\"Send\" VALUE=\"Send\"></INPUT></td>");
    responseContent.append(
        "<td><INPUT TYPE=\"reset\" NAME=\"Clear\" VALUE=\"Clear\" ></INPUT></td></tr>");
    responseContent.append("</table></FORM>\r\n");
    responseContent.append("<CENTER><HR WIDTH=\"75%\" NOSHADE color=\"blue\"></CENTER>");

    // POST
    responseContent.append("<CENTER>POST FORM<HR WIDTH=\"75%\" NOSHADE color=\"blue\"></CENTER>");
    responseContent.append("<FORM ACTION=\"/formpost\" METHOD=\"POST\">");
    responseContent.append("<input type=hidden name=getform value=\"POST\">");
    responseContent.append("<table border=\"0\">");
    responseContent.append(
        "<tr><td>Fill with value: <br> <input type=text name=\"info\" size=10></td></tr>");
    responseContent.append(
        "<tr><td>Fill with value: <br> <input type=text name=\"secondinfo\" size=20>");
    responseContent.append(
        "<tr><td>Fill with value: <br> <textarea name=\"thirdinfo\" cols=40 rows=10></textarea>");
    responseContent.append(
        "<tr><td>Fill with file (only file name will be transmitted): <br> "
            + "<input type=file name=\"myfile\">");
    responseContent.append("</td></tr>");
    responseContent.append(
        "<tr><td><INPUT TYPE=\"submit\" NAME=\"Send\" VALUE=\"Send\"></INPUT></td>");
    responseContent.append(
        "<td><INPUT TYPE=\"reset\" NAME=\"Clear\" VALUE=\"Clear\" ></INPUT></td></tr>");
    responseContent.append("</table></FORM>\r\n");
    responseContent.append("<CENTER><HR WIDTH=\"75%\" NOSHADE color=\"blue\"></CENTER>");

    // POST with enctype="multipart/form-data"
    responseContent.append(
        "<CENTER>POST MULTIPART FORM<HR WIDTH=\"75%\" NOSHADE color=\"blue\"></CENTER>");
    responseContent.append(
        "<FORM ACTION=\"/formpostmultipart\" ENCTYPE=\"multipart/form-data\" METHOD=\"POST\">");
    responseContent.append("<input type=hidden name=getform value=\"POST\">");
    responseContent.append("<table border=\"0\">");
    responseContent.append(
        "<tr><td>Fill with value: <br> <input type=text name=\"info\" size=10></td></tr>");
    responseContent.append(
        "<tr><td>Fill with value: <br> <input type=text name=\"secondinfo\" size=20>");
    responseContent.append(
        "<tr><td>Fill with value: <br> <textarea name=\"thirdinfo\" cols=40 rows=10></textarea>");
    responseContent.append("<tr><td>Fill with file: <br> <input type=file name=\"myfile\">");
    responseContent.append("</td></tr>");
    responseContent.append(
        "<tr><td><INPUT TYPE=\"submit\" NAME=\"Send\" VALUE=\"Send\"></INPUT></td>");
    responseContent.append(
        "<td><INPUT TYPE=\"reset\" NAME=\"Clear\" VALUE=\"Clear\" ></INPUT></td></tr>");
    responseContent.append("</table></FORM>\r\n");
    responseContent.append("<CENTER><HR WIDTH=\"75%\" NOSHADE color=\"blue\"></CENTER>");

    responseContent.append("</body>");
    responseContent.append("</html>");

    ByteBuf buf = copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
    // Build the response object.
    FullHttpResponse response =
        new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);

    response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");
    response.headers().set(CONTENT_LENGTH, buf.readableBytes());

    // Write the response.
    ctx.channel().writeAndFlush(response);
  }
 private void writeHttpData(InterfaceHttpData data) {
   if (data.getHttpDataType() == HttpDataType.Attribute) {
     Attribute attribute = (Attribute) data;
     String value;
     try {
       value = attribute.getValue();
     } catch (IOException e1) {
       // Error while reading data from File, only print name and error
       e1.printStackTrace();
       responseContent.append(
           "\r\nBODY Attribute: "
               + attribute.getHttpDataType().name()
               + ": "
               + attribute.getName()
               + " Error while reading value: "
               + e1.getMessage()
               + "\r\n");
       return;
     }
     if (value.length() > 100) {
       responseContent.append(
           "\r\nBODY Attribute: "
               + attribute.getHttpDataType().name()
               + ": "
               + attribute.getName()
               + " data too long\r\n");
     } else {
       responseContent.append(
           "\r\nBODY Attribute: "
               + attribute.getHttpDataType().name()
               + ": "
               + attribute
               + "\r\n");
     }
   } else {
     responseContent.append(
         "\r\nBODY FileUpload: " + data.getHttpDataType().name() + ": " + data + "\r\n");
     if (data.getHttpDataType() == HttpDataType.FileUpload) {
       FileUpload fileUpload = (FileUpload) data;
       if (fileUpload.isCompleted()) {
         if (fileUpload.length() < 10000) {
           responseContent.append("\tContent of file\r\n");
           try {
             responseContent.append(fileUpload.getString(fileUpload.getCharset()));
           } catch (IOException e1) {
             // do nothing for the example
             e1.printStackTrace();
           }
           responseContent.append("\r\n");
         } else {
           responseContent.append(
               "\tFile too long to be printed out:" + fileUpload.length() + "\r\n");
         }
         // fileUpload.isInMemory();// tells if the file is in Memory
         // or on File
         // fileUpload.renameTo(dest); // enable to move into another
         // File dest
         // decoder.removeFileUploadFromClean(fileUpload); //remove
         // the File of to delete file
       } else {
         responseContent.append("\tFile to be continued but should not!\r\n");
       }
     }
   }
 }
 // RFC 822 defines quoted-string: a simple markup using backslash
 private static void appendAsQuotedString(StringBuilder sb, String name, String value) {
   sb.append(name).append("=");
   quotedString(sb, value);
 }