Package freenet.clients.http

Source Code of freenet.clients.http.HTTPRequestImpl

/* This code is part of Freenet. It is distributed under the GNU General
* Public License, version 2 (or at your option any later version). See
* http://www.gnu.org/ for further details of the GPL. */
package freenet.clients.http;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.Map.Entry;

import javax.naming.SizeLimitExceededException;

import freenet.support.Fields;
import freenet.support.LogThresholdCallback;
import freenet.support.Logger;
import freenet.support.MultiValueTable;
import freenet.support.SimpleReadOnlyArrayBucket;
import freenet.support.URLEncoder;
import freenet.support.Logger.LogLevel;
import freenet.support.api.Bucket;
import freenet.support.api.BucketFactory;
import freenet.support.api.HTTPRequest;
import freenet.support.api.HTTPUploadedFile;
import freenet.support.api.RandomAccessBucket;
import freenet.support.io.BucketTools;
import freenet.support.io.Closer;
import freenet.support.io.LineReadingInputStream;

/**
* Used for passing all HTTP request information to the FredPlugin that handles
* the request. It parses the query string and has several methods for accessing
* the request parameter values.
*
* @author nacktschneck
*/
public class HTTPRequestImpl implements HTTPRequest {

  /**
   * This map is used to store all parameter values.
   * 
   * Don't access this map directly, use {@link #getParameterValueList(String)} and
   * {@link #isParameterSet(String)} instead
   */
  private final Map<String, List<String>> parameterNameValuesMap = new HashMap<String, List<String>>();

  /**
   * the original URI as given to the constructor
   */
  private URI uri;
 
  /**
   * The headers sent by the client
   */
  private MultiValueTable<String, String> headers;
 
  /**
   * The data sent in the connection
   */
  private Bucket data;
 
  /**
   * A hashmap of buckets that we use to store all the parts for a multipart/form-data request
   */
  private HashMap<String, RandomAccessBucket> parts;
 
  private boolean freedParts;
 
  /** A map for uploaded files. */
  private Map<String, HTTPUploadedFileImpl> uploadedFiles = new HashMap<String, HTTPUploadedFileImpl>();
 
  private final BucketFactory bucketfactory;
 
  private final String method;

        private static volatile boolean logMINOR;
  static {
    Logger.registerLogThresholdCallback(new LogThresholdCallback(){
      @Override
      public void shouldUpdate(){
        logMINOR = Logger.shouldLog(LogLevel.MINOR, this);
      }
    });
  }

  /**
   * Create a new HTTPRequest for the given URI and parse its request
   * parameters.
   *
   * @param uri
   *            the URI being requested
   */
  public HTTPRequestImpl(URI uri, String method) {
    this.uri = uri;
    this.parseRequestParameters(uri.getRawQuery(), true, false);
    this.data = null;
    this.parts = null;
    this.bucketfactory = null;
    this.method = method;
  }

  /**
   * Creates a new HTTPRequest for the given path and url-encoded query string
   *
   * @param path i.e. /test/test.html
   * @param encodedQueryString a=some+text&b=abc%40def.de
   * @throws URISyntaxException if the URI is invalid
   */
  public HTTPRequestImpl(String path, String encodedQueryString, String method) throws URISyntaxException {
    this.data = null;
    this.parts = null;
    this.bucketfactory = null;
    if ((encodedQueryString!=null) && (encodedQueryString.length()>0)) {
      this.uri = new URI(path+ '?' +encodedQueryString);
    } else {
      this.uri = new URI(path);
    }
    this.method = method;
    this.parseRequestParameters(uri.getRawQuery(), true, false);
  }
 
  /**
   * Creates a new HTTPRequest for the given URI and data.
   *
   * @param uri The URI being requested
   * @param h Client headers
   * @param d The data
   * @param ctx The toadlet context (for headers and bucket factory)
   * @throws URISyntaxException if the URI is invalid
   */
  public HTTPRequestImpl(URI uri, Bucket d, ToadletContext ctx, String method) {
    this.uri = uri;
    this.headers = ctx.getHeaders();
    this.parseRequestParameters(uri.getRawQuery(), true, false);
    this.data = d;
    this.parts = new HashMap<String, RandomAccessBucket>();
    this.bucketfactory = ctx.getBucketFactory();
    this.method = method;
    if(data != null) {
      try {
        this.parseMultiPartData();
      } catch (IOException ioe) {
        Logger.error(this, "Temporary files error ? Could not parse: "+ioe, ioe);
      }
    }
  }
 

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getPath()
   */
  @Override
  public String getPath() {
    return this.uri.getPath();
  }


  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#hasParameters()
   */
  @Override
  public boolean hasParameters() {
    return ! this.parameterNameValuesMap.isEmpty();
  }

  /**
   * Returns the names of all parameters.
   *
   * @return The names of all parameters
   */
  @Override
  public Collection<String> getParameterNames() {
    return parameterNameValuesMap.keySet();
  }

  /**
   * Parse the query string and populate {@link #parameterNameValuesMap} with
   * the lists of values for each parameter. If this method is not called at
   * all, all other methods would be useless. Because they rely on the
   * parameter map to be filled.
   *
   * @param queryString
   *            the query string in its raw form (not yet url-decoded)
   * @param doUrlDecoding TODO
   */
  private void parseRequestParameters(String queryString, boolean doUrlDecoding, boolean asParts) {

    if(logMINOR) Logger.minor(this, "queryString is "+queryString+", doUrlDecoding="+doUrlDecoding);

    Map<String, List<String>> parameters = parseUriParameters(queryString, doUrlDecoding);

    if (asParts) {
      for (Entry<String, List<String>> parameterValues : parameters.entrySet()) {
        List<String> values = parameterValues.getValue();
        String value = values.get(values.size() - 1);
        byte[] buf;
        try {
          buf = value.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
          throw new Error("Impossible: JVM doesn't support UTF-8: " + e, e);
        } // FIXME some other encoding?
        RandomAccessBucket b = new SimpleReadOnlyArrayBucket(buf);
        parts.put(parameterValues.getKey(), b);
        if(logMINOR)
          Logger.minor(this, "Added as part: name="+parameterValues.getKey()+" value="+value);
      }
    } else {
      parameterNameValuesMap.clear();
      parameterNameValuesMap.putAll(parameters);
    }
  }

  /**
   * Get the first value of the parameter with the given name.
   *
   * @param name
   *            the name of the parameter to get
   * @return the first value or <code>null</code> if the parameter was not
   *         set
   */
  private String getParameterValue(String name) {
    if (!this.isParameterSet(name)) {
      return null;
    }
    List<String> allValues = this.getParameterValueList(name);
    return allValues.get(0);
  }

  /**
   * Get the list of all values for the parameter with the given name. When
   * this method is called for a given parameter for the first time, a new
   * empty list of values is created and stored in
   * {@link #parameterNameValuesMap}. This list is returned and should be
   * used to add parameter values. If you only want to check if a parameter is
   * set at all, you must use {@link #isParameterSet(String)}.
   *
   * @param name
   *            the name of the parameter to get
   * @return the list of all values for this parameter that were parsed so
   *         far.
   */
  private List<String> getParameterValueList(String name) {
    List<String> values = this.parameterNameValuesMap.get(name);
    if (values == null) {
      values = new LinkedList<String>();
      this.parameterNameValuesMap.put(name, values);
    }
    return values;
  }

  /**
   * Parses the parameters from the given query string, optionally decoding
   * the parameters using UTF-8.
   *
   * @param queryString
   *            The query string to decode
   * @param doUrlDecoding
   *            {@code true} to decode the parameter names and values
   * @return The decoded parameters
   */
  public static Map<String, List<String>> parseUriParameters(String queryString, boolean doUrlDecoding) {
    if(logMINOR) Logger.minor(HTTPRequestImpl.class, "queryString is "+queryString+", doUrlDecoding="+doUrlDecoding);

    /* create result map. */
    Map<String, List<String>> parameters = new HashMap<String, List<String>>();

    // nothing to do if there was no query string in the URI
    if ((queryString == null) || (queryString.length() == 0)) {
      return parameters;
    }

    // iterate over all tokens in the query string (separated by &)
    StringTokenizer tokenizer = new StringTokenizer(queryString, "&");
    while (tokenizer.hasMoreTokens()) {
      String nameValueToken = tokenizer.nextToken();

      if(logMINOR) Logger.minor(HTTPRequestImpl.class, "Token: "+nameValueToken);

      // a token can be either a name, or a name value pair...
      String name = null;
      String value = "";
      int indexOfEqualsChar = nameValueToken.indexOf('=');
      if (indexOfEqualsChar < 0) {
        // ...it's only a name, so the value stays emptys
        name = nameValueToken;
        if(logMINOR) Logger.minor(HTTPRequestImpl.class, "Name: "+name);
      } else if (indexOfEqualsChar == nameValueToken.length() - 1) {
        // ...it's a name with an empty value, so remove the '='
        // character
        name = nameValueToken.substring(0, indexOfEqualsChar);
        if(logMINOR) Logger.minor(HTTPRequestImpl.class, "Name: "+name);
      } else {
        // ...it's a name value pair, split into name and value
        name = nameValueToken.substring(0, indexOfEqualsChar);
        value = nameValueToken.substring(indexOfEqualsChar + 1);
        if(logMINOR) Logger.minor(HTTPRequestImpl.class, "Name: "+name+" Value: "+value);
      }

      // url-decode the name and value
      if (doUrlDecoding) {
          try {
            name = URLDecoder.decode(name, "UTF-8");
            value = URLDecoder.decode(value, "UTF-8");
          } catch (UnsupportedEncodingException e) {
            throw new Error("Impossible: JVM doesn't support UTF-8: " + e, e);
          }
        if(logMINOR) {
          Logger.minor(HTTPRequestImpl.class, "Decoded name: "+name);
          Logger.minor(HTTPRequestImpl.class, "Decoded value: "+value);
        }
      }

      List<String> values = parameters.get(name);
      if (values == null) {
        values = new ArrayList<String>();
        parameters.put(name, values);
      }
      values.add(value);
    }

    return parameters;
  }

  /**
   * Creates a query string from the given parameters.
   *
   * @param parameterValues
   *            The parameters to create a query string from
   * @param doUrlEncoding
   *            {@code true} if encoding for HTTP headers, {@code false} to
   *            only encode unsafe characters
   * @return The query string
   */
  public static String createQueryString(Map<String, List<String>> parameterValues, boolean doUrlEncoding) {
    StringBuilder queryString = new StringBuilder();
    for (Entry<String, List<String>> parameter : parameterValues.entrySet()) {
      for (String value : parameter.getValue()) {
        if (queryString.length() > 0) {
          queryString.append('&');
        }
        queryString.append(URLEncoder.encode(parameter.getKey(), doUrlEncoding));
        queryString.append('=');
        queryString.append(URLEncoder.encode(value, doUrlEncoding));
      }
    }
    return queryString.toString();
  }

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#isParameterSet(java.lang.String)
   */
  @Override
  public boolean isParameterSet(String name) {
    return this.parameterNameValuesMap.containsKey(name);
  }

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getParam(java.lang.String)
   */
  @Override
  public String getParam(String name) {
    return this.getParam(name, "");
  }

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getParam(java.lang.String, java.lang.String)
   */
  @Override
  public String getParam(String name, String defaultValue) {
    String value = this.getParameterValue(name);
    if (value == null || value.isEmpty()) {
      return defaultValue;
    }
    return value;
  }

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getIntParam(java.lang.String)
   */
  @Override
  public int getIntParam(String name) {
    return this.getIntParam(name, 0);
  }

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getIntParam(java.lang.String, int)
   */
  @Override
  public int getIntParam(String name, int defaultValue) {
    if (!this.isParameterSet(name)) {
      return defaultValue;
    }
    String value = this.getParameterValue(name);
    try {
      return Integer.parseInt(value);
    } catch (NumberFormatException e) {
      return defaultValue;
    }
  }

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getIntPart(java.lang.String, int)
   */
  @Override
  public int getIntPart(String name, int defaultValue) {
    if (!this.isPartSet(name)) {
      return defaultValue;
    }
    String value = this.getPartAsString(name, 32);
    try {
      return Integer.parseInt(value);
    } catch (NumberFormatException e) {
      return defaultValue;
    }
  }

  // TODO: add similar methods for long, boolean etc.

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getMultipleParam(java.lang.String)
   */
  @Override
  public String[] getMultipleParam(String name) {
    List<String> valueList = this.getParameterValueList(name);
    String[] values = new String[valueList.size()];
    valueList.toArray(values);
    return values;
  }

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getMultipleIntParam(java.lang.String)
   */
  @Override
  public int[] getMultipleIntParam(String name) {
    List<String> valueList = this.getParameterValueList(name);

    // try parsing all values and put the valid Integers in a new list
    List<Integer> intValueList = new ArrayList<Integer>();
    for (int i = 0; i < valueList.size(); i++) {
      try {
        intValueList.add(Integer.valueOf(valueList.get(i)));
      } catch (Exception e) {
        // ignore invalid parameter values
      }
    }

    // convert the valid Integers to an array of ints
    int[] values = new int[intValueList.size()];
    for (int i = 0; i < intValueList.size(); i++) {
      values[i] = intValueList.get(i);
    }
    return values;
  }


  // TODO: add similar methods for multiple long, boolean etc.
 
 
  /**
   * Parse submitted data from a bucket.
   * Note that if this is application/x-www-form-urlencoded, it will come out as
   * params, whereas if it is multipart/form-data it will be separated into buckets.
   */
  private void parseMultiPartData() throws IOException {
    InputStream is = null;
    LineReadingInputStream lis = null;
    OutputStream bucketos = null;

    try {
      if(data == null)
        return;
      String ctype = this.headers.get("content-type");
      if(ctype == null)
        return;
      if(logMINOR)
        Logger.minor(this, "Uploaded content-type: " + ctype);
      String[] ctypeparts = ctype.split(";");
      if(ctypeparts[0].equalsIgnoreCase("application/x-www-form-urlencoded")) {
        // Completely different encoding, but easy to handle
        if(data.size() > 1024 * 1024)
          throw new IOException("Too big");
        byte[] buf = BucketTools.toByteArray(data);
        String s = new String(buf, "us-ascii");
        parseRequestParameters(s, true, true);
      }
      if(!ctypeparts[0].trim().equalsIgnoreCase("multipart/form-data") || (ctypeparts.length < 2))
        return;

      String boundary = null;
      for(String ctypepart: ctypeparts) {
        String[] subparts = ctypepart.split("=");
        if((subparts.length == 2) && subparts[0].trim().equalsIgnoreCase("boundary"))
          boundary = subparts[1];
      }

      if((boundary == null) || (boundary.length() == 0))
        return;
      if(boundary.charAt(0) == '"')
        boundary = boundary.substring(1);
      if(boundary.charAt(boundary.length() - 1) == '"')
        boundary = boundary.substring(0, boundary.length() - 1);

      boundary = "--" + boundary;

      if(logMINOR)
        Logger.minor(this, "Boundary is: " + boundary);

      is = this.data.getInputStream();
      lis = new LineReadingInputStream(is);

      String line;
      line = lis.readLine(100, 100, false); // really it's US-ASCII, but ISO-8859-1 is close enough.
      while((is.available() > 0) && !line.equals(boundary)) {
        line = lis.readLine(100, 100, false);
      }

      boundary = "\r\n" + boundary;

      RandomAccessBucket filedata = null;
      String name = null;
      String filename = null;
      String contentType = null;

      while(is.available() > 0) {
        name = null;
        filename = null;
        contentType = null;
        // chomp headers
        while((line = lis.readLine(200, 200, true)) /* should be UTF-8 as we told the browser to send UTF-8 */ != null) {
          if(line.length() == 0)
            break;

          String[] lineparts = line.split(":");
          if(lineparts == null || lineparts.length == 0)
            continue;
          String hdrname = lineparts[0].trim();

          if(hdrname.equalsIgnoreCase("Content-Disposition")) {
            if(lineparts.length < 2)
              continue;
            String[] valueparts = lineparts[1].split(";");

            for(int i = 0; i < valueparts.length; i++) {
              String[] subparts = valueparts[i].split("=");
              if(subparts.length != 2)
                continue;
              String fieldname = subparts[0].trim();
              String value = subparts[1].trim();
              if(value.startsWith("\"") && value.endsWith("\""))
                value = value.substring(1, value.length() - 1);
              if(fieldname.equalsIgnoreCase("name"))
                name = value;
              else if(fieldname.equalsIgnoreCase("filename"))
                filename = value;
            }
          }
          else if(hdrname.equalsIgnoreCase("Content-Type")) {
            contentType = lineparts[1].trim();
            if(logMINOR)
              Logger.minor(this, "Parsed type: " + contentType);
          }
          else {
          // Do nothing, irrelevant header
          }
        }

        if(name == null)
          continue;

        // we should be at the data now. Start reading it in, checking for the
      // boundary string

        // we can only give an upper bound for the size of the bucket
        filedata = this.bucketfactory.makeBucket(is.available());
        bucketos = filedata.getOutputStream();
        // buffer characters that match the boundary so far
      // FIXME use whatever charset was used
        byte[] bbound = boundary.getBytes("UTF-8"); // ISO-8859-1? boundary should be in US-ASCII
        int offset = 0;
        while((is.available() > 0) && (offset < bbound.length)) {
          byte b = (byte) is.read();

          if(b == bbound[offset])
            offset++;
          else if((b != bbound[offset]) && (offset > 0)) {
            // offset bytes matched, but no more
          // write the bytes that matched, then the non-matching byte
            bucketos.write(bbound, 0, offset);
            offset = 0;
            if(b == bbound[0])
              offset = 1;
            else
              bucketos.write(b);
          }
          else
            bucketos.write(b);
        }

        bucketos.close();
        bucketos = null;
     
        parts.put(name, filedata);
        if(logMINOR)
          Logger.minor(this, "Name = " + name + " length = " + filedata.size() + " filename = " + filename);
        if(filename != null)
          uploadedFiles.put(name, new HTTPUploadedFileImpl(filename, contentType, filedata));
      }
    }
    finally {
      Closer.close(bucketos);
      Closer.close(lis);
      Closer.close(is);
      Closer.close(is);
    }
  }
 
  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getUploadedFile(java.lang.String)
   */
  @Override
  public HTTPUploadedFile getUploadedFile(String name) {
    return uploadedFiles.get(name);
  }
 
  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getPart(java.lang.String)
   */
  @Override
  public RandomAccessBucket getPart(String name) {
    if(freedParts) throw new IllegalStateException("Already freed");
    return this.parts.get(name);
  }
 
  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#isPartSet(java.lang.String)
   */
  @Override
  public boolean isPartSet(String name) {
    if(freedParts) throw new IllegalStateException("Already freed");
    if(parts == null)
      return false;

    return this.parts.containsKey(name);
  }

  @Override
  @Deprecated
  public String getPartAsString(String name, int maxlength) {
    try {
      return new String(getPartAsBytes(name, maxlength), "UTF-8");
    } catch (UnsupportedEncodingException e) {
      throw new Error("Impossible: JVM doesn't support UTF-8: " + e, e);
    }
  }
 
  @Override
  public String getPartAsStringThrowing(String name, int maxLength) throws NoSuchElementException, SizeLimitExceededException {
    if(freedParts) throw new IllegalStateException("Already freed");
    Bucket part = this.parts.get(name);
   
    if(part == null)
      throw new NoSuchElementException(name);
   
    if(part.size() > maxLength)
      throw new SizeLimitExceededException();
   
    return getPartAsLimitedString(part, maxLength);
  }
 
  @Override
  public String getPartAsStringFailsafe(String name, int maxLength) {
    if(freedParts) throw new IllegalStateException("Already freed");
    Bucket part = this.parts.get(name);
    return part == null ? "" : getPartAsLimitedString(part, maxLength);
  }
 
  private String getPartAsLimitedString(Bucket part, int maxLength) {
    try {
      return new String(getPartAsLimitedBytes(part, maxLength), "UTF-8");
    } catch (UnsupportedEncodingException e) {
      throw new Error("Impossible: JVM doesn't support UTF-8: " + e, e);
    }
  }

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getPartAsString(java.lang.String, int)
   */
  @Override
  @Deprecated
  public byte[] getPartAsBytes(String name, int maxlength) {
    if(freedParts) throw new IllegalStateException("Already freed");
    Bucket part = this.parts.get(name);
    if(part == null) return new byte[0];
   
    if (part.size() > maxlength) return new byte[0];
   
    InputStream is = null;
    DataInputStream dis = null;
    try {
      is = part.getInputStream();
      dis = new DataInputStream(is);
      byte[] buf = new byte[(int)Math.min(part.size(), maxlength)];
      dis.readFully(buf);
      return buf;
    } catch (IOException ioe) {
           Logger.error(this, "Caught IOE:" + ioe.getMessage());
    } finally {
      Closer.close(dis);
      if(dis == null) Closer.close(is); // DataInputStream.close() does this for us normally
    }
   
    return new byte[0];
  }
 
  @Override
  public byte[] getPartAsBytesThrowing(String name, int maxLength) throws NoSuchElementException, SizeLimitExceededException {
    if(freedParts) throw new IllegalStateException("Already freed");
    Bucket part = this.parts.get(name);
   
    if(part == null)
      throw new NoSuchElementException(name);
   
    if(part.size() > maxLength)
      throw new SizeLimitExceededException();
   
    return getPartAsLimitedBytes(part, maxLength);
  }
 
  @Override
  public byte[] getPartAsBytesFailsafe(String name, int maxLength) {
    if(freedParts) throw new IllegalStateException("Already freed");
    Bucket part = this.parts.get(name);
    return part == null ? new byte[0] : getPartAsLimitedBytes(part, maxLength);
  }
 
  private byte[] getPartAsLimitedBytes(Bucket part, int maxLength) {
    InputStream is = null;
    DataInputStream dis = null;
    try {
      is = part.getInputStream();
      dis = new DataInputStream(is);
      byte[] buf = new byte[(int)Math.min(part.size(), maxLength)];
      dis.readFully(buf, 0, buf.length);
      return buf;
    } catch (IOException ioe) {
           Logger.error(this, "Caught IOE:" + ioe.getMessage());
           return new byte[0];
    } finally {
      Closer.close(dis);
      if(dis == null) Closer.close(is); // DataInputStream.close() does this for us normally
    }
  }
 
  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#freeParts()
   */
  @Override
  public void freeParts() {
    if (this.parts == null) return;
   
    for (Bucket b : this.parts.values()) {
      b.free();
    }
    parts.clear();
    freedParts = true;
    // Do not free data. Caller is responsible for that.
  }

  /* (non-Javadoc)
   * @see freenet.clients.http.HTTPRequest#getLongParam(java.lang.String, long)
   */
  @Override
  public long getLongParam(String name, long defaultValue) {
    if (!this.isParameterSet(name)) {
      return defaultValue;
    }
    String value = this.getParameterValue(name);
    try {
      return Fields.parseLong(value);
    } catch (NumberFormatException e) {
      return defaultValue;
    }
  }

  /**
   * Container for uploaded files in HTTP POST requests.
   *
   * @author David 'Bombe' Roden &lt;bombe@freenetproject.org&gt;
   * @version $Id$
   */
  public static class HTTPUploadedFileImpl implements HTTPUploadedFile {

    /** The filename. */
    private final String filename;

    /** The content type. */
    private final String contentType;

    /** The data. */
    private final Bucket data;

    /**
     * Creates a new file with the specified filename, content type, and
     * data.
     *
     * @param filename
     *            The name of the file
     * @param contentType
     *            The content type of the file
     * @param data
     *            The data of the file
     */
    public HTTPUploadedFileImpl(String filename, String contentType, Bucket data) {
      this.filename = filename;
      this.contentType = contentType;
      this.data = data;
    }

    /* (non-Javadoc)
     * @see freenet.clients.http.HTTPUploadedFile#getContentType()
     */
    @Override
    public String getContentType() {
      return contentType;
    }

    /* (non-Javadoc)
     * @see freenet.clients.http.HTTPUploadedFile#getData()
     */
    @Override
    public Bucket getData() {
      return data;
    }

    /* (non-Javadoc)
     * @see freenet.clients.http.HTTPUploadedFile#getFilename()
     */
    @Override
    public String getFilename() {
      return filename;
    }

  }

  @Override
  public String getMethod() {
    return method;
  }

  @Override
  public Bucket getRawData() {
    return data;
  }

  @Override
  public String getHeader(String name) {
    assert(name.equals(name.toLowerCase()));
    return this.headers.get(name.toLowerCase());
  }

  @Override
  public int getContentLength() {
    String slen = headers.get("content-length");
    if (slen == null)
      return -1;
    // it is already parsed, so NumberFormatException can not happens here
    return Integer.parseInt(slen);
  }

  @Override
  public String[] getParts() {
    if(freedParts) throw new IllegalStateException("Already freed");
    return parts.keySet().toArray(new String[parts.size()]);
  }

  @Override
  public boolean isIncognito() {
    if(isParameterSet("incognito"))
      return Boolean.valueOf(getParam("incognito"));
    return false;
  }

  @Override
  public boolean isChrome() {
    String ua = getHeader("user-agent");
    if(ua != null) {
      if(ua.contains("Chrome")) return true;
    }
    return false;
  }

}
TOP

Related Classes of freenet.clients.http.HTTPRequestImpl

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.