Package fitnesse.http

Source Code of fitnesse.http.RequestBuilder$InputStreamPart

// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.http;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import util.StreamReader;
import fitnesse.util.Base64;

public class RequestBuilder {
  private static final byte[] ENDL = "\r\n".getBytes();
  private static final Random RANDOM_GENERATOR = new SecureRandom();

  private String resource;
  private String method = "GET";
  private List<InputStream> bodyParts = new LinkedList<InputStream>();
  private HashMap<String, String> headers = new HashMap<String, String>();
  private HashMap<String, Object> inputs = new HashMap<String, Object>();
  private String host;
  private int port;
  private String boundary;
  private boolean isMultipart = false;
  private int bodyLength = 0;

  public RequestBuilder(String resource) {
    this.resource = resource;
  }

  public void setMethod(String method) {
    this.method = method;
  }

  public void addHeader(String key, String value) {
    headers.put(key, value);
  }

  public String getText() throws Exception {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    send(output);
    return output.toString();
  }

  private String buildRequestLine() throws UnsupportedEncodingException {
    StringBuffer text = new StringBuffer();
    text.append(method).append(" ").append(resource);
    if (isGet()) {
      String inputString = inputString();
      if (inputString.length() > 0)
        text.append("?").append(inputString);
    }
    text.append(" HTTP/1.1");
    return text.toString();
  }

  private boolean isGet() {
    return method.equals("GET");
  }

  public void send(OutputStream output) throws IOException {
    output.write(buildRequestLine().getBytes("UTF-8"));
    output.write(ENDL);
    buildBody();
    sendHeaders(output);
    output.write(ENDL);
    sendBody(output);
  }

  private void sendHeaders(OutputStream output) throws IOException {
    addHostHeader();
    for (Iterator<String> iterator = headers.keySet().iterator(); iterator.hasNext();) {
      String key = iterator.next();
      output.write((key + ": " + headers.get(key)).getBytes("UTF-8"));
      output.write(ENDL);
    }
  }

  private void buildBody() throws IOException {
    if (!isMultipart) {
      byte[] bytes = inputString().getBytes("UTF-8");
      bodyParts.add(new ByteArrayInputStream(bytes));
      bodyLength += bytes.length;
    } else {
      for (Iterator<String> iterator = inputs.keySet().iterator(); iterator.hasNext();) {
        String name = iterator.next();
        Object value = inputs.get(name);
        StringBuffer partBuffer = new StringBuffer();
        partBuffer.append("--").append(getBoundary()).append("\r\n");
        partBuffer.append("Content-Disposition: form-data; name=\"").append(name).append("\"").append("\r\n");
        if (value instanceof InputStreamPart) {
          InputStreamPart part = (InputStreamPart) value;
          partBuffer.append("Content-Type: ").append(part.contentType).append("\r\n");
          partBuffer.append("\r\n");
          addBodyPart(partBuffer.toString());
          bodyParts.add(part.input);
          bodyLength += part.size;
          addBodyPart("\r\n");
        } else {
          partBuffer.append("Content-Type: text/plain").append("\r\n");
          partBuffer.append("\r\n");
          partBuffer.append(value);
          partBuffer.append("\r\n");
          addBodyPart(partBuffer.toString());
        }
      }
      StringBuffer tail = new StringBuffer();
      tail.append("--").append(getBoundary()).append("--").append("\r\n");
      addBodyPart(tail.toString());
    }
    addHeader("Content-Length", bodyLength + "");
  }

  private void addBodyPart(String input) throws UnsupportedEncodingException {
    byte[] bytes = input.toString().getBytes("UTF-8");
    bodyParts.add(new ByteArrayInputStream(bytes));
    bodyLength += bytes.length;
  }

  private void sendBody(OutputStream output) throws IOException {
    for (Iterator<InputStream> iterator = bodyParts.iterator(); iterator.hasNext();) {
      InputStream input = iterator.next();

      StreamReader reader = new StreamReader(input);
      while (!reader.isEof()) {
        byte[] bytes = reader.readBytes(1000);
        output.write(bytes);
      }
    }
  }

  private void addHostHeader() {
    if (host != null)
      addHeader("Host", host + ":" + port);
    else
      addHeader("Host", "");
  }

  public void addInput(String key, Object value) {
    inputs.put(key, value);
  }

  public String inputString() throws UnsupportedEncodingException {
    StringBuffer buffer = new StringBuffer();
    boolean first = true;
    for (Iterator<String> iterator = inputs.keySet().iterator(); iterator.hasNext();) {
      String key = iterator.next();
      String value = (String) inputs.get(key);
      if (!first)
        buffer.append("&");
      buffer.append(key).append("=").append(URLEncoder.encode(value, "UTF-8"));
      first = false;
    }
    return buffer.toString();
  }

  public void addCredentials(String username, String password) {
    String rawUserpass = username + ":" + password;
    String userpass = Base64.encode(rawUserpass);
    addHeader("Authorization", "Basic " + userpass);
  }

  public void setHostAndPort(String host, int port) {
    this.host = host;
    this.port = port;
  }

  public String getBoundary() {
    if (boundary == null) {
      boundary = "----------" + RANDOM_GENERATOR.nextInt() + "BoUnDaRy";
    }
    return boundary;
  }

  public void addInputAsPart(String name, Object content) {
    multipart();
    addInput(name, content);
  }

  public void addInputAsPart(String name, InputStream input, int size, String contentType) {
    addInputAsPart(name, new InputStreamPart(input, size, contentType));
  }

  private void multipart() {
    if (!isMultipart) {
      isMultipart = true;
      setMethod("POST");
      addHeader("Content-Type", "multipart/form-data; boundary=" + getBoundary());
    }
  }

  private static class InputStreamPart {
    public InputStream input;
    public int size;
    public String contentType;

    public InputStreamPart(InputStream input, int size, String contentType) {
      this.input = input;
      this.size = size;
      this.contentType = contentType;
    }
  }
}
TOP

Related Classes of fitnesse.http.RequestBuilder$InputStreamPart

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.