Package org.parosproxy.paros.network

Source Code of org.parosproxy.paros.network.HttpHeader

/*
* Created on Jun 14, 2004
*
* Paros and its related class files.
*
* Paros is an HTTP/HTTPS proxy for assessing web application security.
* Copyright (C) 2003-2004 Chinotec Technologies Company
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Clarified Artistic License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* Clarified Artistic License for more details.
*
* You should have received a copy of the Clarified Artistic License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package org.parosproxy.paros.network;

import java.util.Hashtable;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;


abstract public class HttpHeader implements java.io.Serializable{


  public static final String CRLF       = "\r\n";
  public static final String LF         = "\n";
  public static final String CONTENT_LENGTH   = "Content-length";
  public static final String TRANSFER_ENCODING = "Transfer-encoding";
  public static final String CONTENT_ENCODING = "Content-encoding";
  public static final String CONTENT_TYPE   = "Content-Type";
  public static final String PROXY_CONNECTION = "Proxy-Connection";
  public static final String PROXY_AUTHENTICATE = "Proxy-authenticate";
  public static final String CONNECTION    = "Connection";
  public static final String AUTHORIZATION  = "Authorization";
  public static final String WWW_AUTHENTICATE = "WWW-Authenticate";
  public static final String LOCATION        = "Location";
  public static final String IF_MODIFIED_SINCE  = "If-Modified-Since";
  public static final String IF_NONE_MATCH    = "If-None-Match";
  public static final String USER_AGENT    = "User-Agent";
  public static final String ACCEPT_ENCODING = "Accept-Encoding";
  public static final String CACHE_CONTROL  = "Cache-control";
  public static final String PRAGMA      = "Pragma";
  public static final String REFERER      = "Referer";
 
  public static final String HTTP09   = "HTTP/0.9";
  public static final String HTTP10   = "HTTP/1.0";
  public static final String HTTP11   = "HTTP/1.1";
  public static final String _CLOSE       = "Close";
  public static final String _KEEP_ALIVE     = "Keep-alive";
  public static final String _CHUNKED      = "Chunked";
 
  public static final String SCHEME_HTTP    = "http://";
  public static final String SCHEME_HTTPS    = "https://";
  public static final String HTTP        = "http";
  public static final String HTTPS      = "https";

  public static final Pattern patternCRLF      = Pattern.compile("\\r\\n", Pattern.MULTILINE);
  public static final Pattern patternLF        = Pattern.compile("\\n", Pattern.MULTILINE);
 
  private static final Pattern patternCharset = Pattern.compile("charset *= *([^;\\s]+)", Pattern.CASE_INSENSITIVE);

  protected static final String p_TEXT    = "[^\\x00-\\x1f\\r\\n]*";
  protected static final String p_METHOD    = "(\\w+)";
  protected static final String p_SP      = " +";
  // protected static final String p_URI      = "(\\S+)";
  // allow space in URI for encoding to %20
  protected static final String p_URI      = "([^\\r\\n]+)";
  protected static final String p_VERSION    = "(HTTP/\\d+\\.\\d+)";
  protected static final String p_STATUS_CODE  = "(\\d{3})";
  protected static final String p_REASON_PHRASE = "(" + p_TEXT + ")";
 
  protected String mStartLine = "";
  protected String mMsgHeader = "";
  protected boolean mMalformedHeader = false;
  protected Hashtable mHeaderFields = new Hashtable();
  protected int mContentLength = -1;
  protected String mLineDelimiter = CRLF;
  protected String mVersion = "";
 
  public HttpHeader() {
    init();
  }


  /**
   * Construct a HttpHeader from a given String.
   * @param data
   * @throws HttpMalformedHeaderException
   */
  public HttpHeader(String data) throws HttpMalformedHeaderException {
    this();
    setMessage(data);
  }

  /**
   * Inititialization.
   */
  private void init() {
    mHeaderFields = new Hashtable();
    mStartLine = "";
    mMsgHeader = "";
    mMalformedHeader = false;
    mContentLength = -1;
    mLineDelimiter = CRLF;
    mVersion = "";
  }

  /**
   * Set and parse this HTTP header with the string given.
   *
   * @param data
   * @throws HttpMalformedHeaderException
   */
  public void setMessage(String data) throws HttpMalformedHeaderException {
    init();

    mMsgHeader = data;
    try {
      if (!this.parse(data)) {
        mMalformedHeader = true;
      }
    } catch (Exception e) {
      mMalformedHeader = true;
    }

    if (mMalformedHeader) {
      throw new HttpMalformedHeaderException();
    }

  }
 
  public void clear() {
      init();
  }

  /**
   * Get the first header value using the name given.  If there are multiple occurence,
   * only the first one will be returned as String.
   * @param name
   * @return the header value.  null if not found.
   */
  public String getHeader(String name) {
    Vector v = getHeaders(name);
    if (v == null) {
      return null;
    }
   
    return (String) (v.firstElement());
  }
   
  /**
   * Get headers with the name.  Multiple value can be returned.
   * @param name
   * @return a vector holding the value as string.
   */
    public Vector getHeaders(String name) {
      Vector v = (Vector) mHeaderFields.get(name.toUpperCase());
      return v;
    }

    /**
     * Add a header with the name and value given.  It will be appended to the header string.
     * @param name
     * @param val
     */
  public void addHeader(String name, String val) {
    mMsgHeader = mMsgHeader + name + ": " + val + mLineDelimiter;
    addInternalHeaderFields(name, val);
  }

  /**
   * Set a header name and value.
   * If the name is not found, it will be added.
   * If the value is null, the header will be removed.
   * @param name
   * @param value
   */
    public void setHeader(String name, String value) {
//    int pos = 0;
//    int crlfpos = 0;
    Pattern pattern = null;

    if (getHeaders(name) == null && value != null) {
      // header value not found, append to end
      addHeader(name, value);
    } else {
      try {
        pattern = getHeaderRegex(name);
        Matcher matcher = pattern.matcher(mMsgHeader);
        if (value == null) {
          // delete header
          mMsgHeader = matcher.replaceAll("");
        } else {
          // replace header
          String newString = name + ": " + value + mLineDelimiter;
          mMsgHeader = matcher.replaceAll(newString);
        }

        // set into hashtable
        replaceInternalHeaderFields(name, value);
       
      }
      catch (Exception e) {
      }
     
    }
    }
   
    private Pattern getHeaderRegex(String name) throws PatternSyntaxException
  {
    return Pattern.compile("^ *"+ name + " *: *[^\\r\\n]*" + mLineDelimiter, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
  }

    /**
     * Return the HTTP version (eg HTTP/1.0, HTTP/1.1)
     * @return
     */
  public String getVersion() {
    return mVersion;
  }

  /**
   * Set the HTTP version of this header.
   * @param version
   */
  abstract public void setVersion(String version);

  /**
   * Get the content length of this header.
   * 
   * @return content length.  -1 means content length not set.
   */
  public int getContentLength() {
        return mContentLength;
    }

  /**
   * Set the content length of this header.
   * @param len
   */
  public void setContentLength(int len) {
    if (mContentLength != len) {
      setHeader(CONTENT_LENGTH, Integer.toString(len));
      mContentLength = len;
    }
  }

  /**
   * Check if this header expect connection to be closed.  HTTP/1.0 default to close.  HTTP/1.1 default to keep-alive.
   * @return
   */
     public boolean isConnectionClose() {
    boolean result = true;
    if (mMalformedHeader) {
      return true;
    }

    if (isHttp10()) {
      // HTTP 1.0 default to close unless keep alive.
      result = true;
      try {
        if (getHeader(CONNECTION).equalsIgnoreCase(_KEEP_ALIVE) || getHeader(PROXY_CONNECTION).equalsIgnoreCase(_KEEP_ALIVE)) {
          return false;
        }
      } catch (NullPointerException e) {
      }

    } else if (isHttp11()) {
      // HTTP 1.1 default to keep alive unless close.
      result = false;
      try {
        if (getHeader(CONNECTION).equalsIgnoreCase(_CLOSE)) {
          return true;
        } else if  (getHeader(PROXY_CONNECTION).equalsIgnoreCase(_CLOSE)) {
          return true;
        }
      } catch (NullPointerException e) {
      }
    }
    return result;
  }

     /**
      * Check if this header is HTTP 1.0.
      * @return true if HTTP 1.0.
      */
  public boolean isHttp10() {
    if (mVersion.equalsIgnoreCase(HTTP10)) {
      return true;
    }
    return false;
  }

  /**
   * Check if this header is HTTP 1.1.
   * @return true if HTTP 1.0.
   */
  public boolean isHttp11() {
    if (mVersion.equalsIgnoreCase(HTTP11)) {
      return true;
    }
    return false;
  }

  /**
   * Check if Transfer Encoding Chunked is set in this header.
   * @return true if transfer encoding chunked is set.
   */
    public boolean isTransferEncodingChunked() {
      String transferEncoding = getHeader(TRANSFER_ENCODING);
      if (transferEncoding != null && transferEncoding.equalsIgnoreCase(_CHUNKED)) {
        return true;
      }
      return false;
    }

    /**
     * Parse this Http header using the String given.
     * @param data String to be parsed to form this header.
     * @return
     * @throws Exception
     */
    protected boolean parse(String data) throws Exception {

        String   token = null,
        name = null,
        value = null;
        int pos = 0;
        Pattern pattern = null;

        if(data == null || data.equals("")) {
            return true;
        }

        if ((pos = data.indexOf(CRLF)) < 0) {
          if ((pos = data.indexOf(LF)) < 0) {
            return false;
          } else {
            mLineDelimiter = LF;
            pattern = patternLF;
          }
        } else {
          mLineDelimiter = CRLF;
          pattern = patternCRLF;
        }
       
    String[] split = pattern.split(data);
    mStartLine = split[0];

    StringBuffer sb = new StringBuffer(2048);
    for (int i=1; i<split.length; i++)
    {
      token = split[i];
      if (token.equals("")) {
        continue;
      }
     
            if((pos = token.indexOf(":")) < 0) {
        mMalformedHeader = true;
                return false;
            }
            name  = token.substring(0, pos).trim();
            value = token.substring(pos +1).trim();

            if(name.equalsIgnoreCase(CONTENT_LENGTH)) {
              try {
                  mContentLength = Integer.parseInt(value);
              } catch (NumberFormatException nfe){}
            }
     
            /*
            if (name.equalsIgnoreCase(PROXY_CONNECTION)) {
              sb.append(name + ": " + _CLOSE + mLineDelimiter);
            } else if (name.equalsIgnoreCase(CONNECTION)) {
              sb.append(name + ": " + _CLOSE + mLineDelimiter);
            } else {
            */
      sb.append(name + ": " + value + mLineDelimiter);
      //}
     
      addInternalHeaderFields(name, value);
    }

        mMsgHeader = sb.toString();
    return true;
  }

    /**
     * Replace the header stored in internal hashtable
     * @param name
     * @param value
     */
  private void replaceInternalHeaderFields(String name, String value) {
    String key = name.toUpperCase();
    Vector v = getHeaders(key);
    if (v == null) {
      v = new Vector();
      mHeaderFields.put(key, v);
    }

    if (value != null) {
        v.clear();
      v.add(value);
    } else {
      mHeaderFields.remove(key);
    }
  }

  /**
   * Add the header stored in internal hashtable
   * @param name
   * @param value
   */
  private void addInternalHeaderFields(String name, String value) {
    String key = name.toUpperCase();
    Vector v = getHeaders(key);
    if (v == null) {
      v = new Vector();
      mHeaderFields.put(key, v);
    }

    if (value != null) {
      v.add(value);
    } else {
      mHeaderFields.remove(key);
    }
  }

 
  /**
   * Get if this is a malformed header.
   * @return
   */
    public boolean isMalformedHeader() {
        return mMalformedHeader;
    }
   
    /**
     * Get a string representation of this header.
     */
    public String toString() {
    return getPrimeHeader() + mLineDelimiter + mMsgHeader + mLineDelimiter;
    }

    /**
     * Get the prime header.
     * @return startline for request, statusline for response.
     */
    abstract public String getPrimeHeader();

    /**
     * Get if this is a image header.
     * @return true if image.
     */
    public boolean isImage() {
      return false;
    }

    /**
     * Get if this is a text header.
     * @return true if text.
     */
    public boolean isText() {
      return true;
    }

    /**
     * Get the line delimiter of this header.
     * @return
     */
    public String getLineDelimiter() {
      return mLineDelimiter;
    }

    /**
     * Get the headers as string.  All the headers name value pair is concatenated and delimited.
     * @return Eg "Host: www.example.com\r\nUser-agent: some agent\r\n"
     */
    public String getHeadersAsString() {
      return mMsgHeader;
    }

    public boolean isEmpty() {
        if (mMsgHeader == null || mMsgHeader.equals("")) {
            return true;
        }
       
        return false;
    }
   
  public String getCharset() {
      String contentType = getHeader(CONTENT_TYPE);
      String charset = "";
      if (contentType == null) {
          return null;
      }
     
      Matcher matcher = patternCharset.matcher(contentType);
      if (matcher.find()) {
          charset = matcher.group(1);
      }
      return charset;
  }
}
TOP

Related Classes of org.parosproxy.paros.network.HttpHeader

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.