All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fitnesse.http.RequestBuilder Maven / Gradle / Ivy

There is a newer version: 20241026
Show newest version
// 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.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

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

import static util.FileUtil.CHARENCODING;

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 bodyParts = new LinkedList<>();
  private HashMap headers = new HashMap<>();
  private HashMap inputs = new HashMap<>();
  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 {
    StringBuilder text = new StringBuilder();
    text.append(method).append(" ").append(resource);
    if (isGet()) {
      String inputString = inputString();
      if (!inputString.isEmpty())
        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(CHARENCODING));
    output.write(ENDL);
    buildBody();
    sendHeaders(output);
    output.write(ENDL);
    sendBody(output);
  }

  private void sendHeaders(OutputStream output) throws IOException {
    addHostHeader();
    for (Map.Entry entry : headers.entrySet()) {
      output.write((entry.getKey() + ": " + entry.getValue()).getBytes(CHARENCODING));
      output.write(ENDL);
    }
  }

  private void buildBody() throws IOException {
    if (!isMultipart) {
      byte[] bytes = inputString().getBytes(CHARENCODING);
      bodyParts.add(new ByteArrayInputStream(bytes));
      bodyLength += bytes.length;
    } else {
      for (Map.Entry entry : inputs.entrySet()) {
        String name = entry.getKey();
        Object value = entry.getValue();
        StringBuilder partBuffer = new StringBuilder();
        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());
        }
      }
      String tail = "--" + getBoundary() + "--" + "\r\n";
      addBodyPart(tail);
    }
    addHeader("Content-Length", bodyLength + "");
  }

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

  private void sendBody(OutputStream output) throws IOException {
    for (InputStream input : bodyParts) {
      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 {
    StringBuilder buffer = new StringBuilder();
    boolean first = true;
    for (Map.Entry entry : inputs.entrySet()) {
      String value = (String) entry.getValue();
      if (!first)
        buffer.append("&");
      String key = entry.getKey();
      buffer.append(key).append("=").append(URLEncoder.encode(value, CHARENCODING));
      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;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy