Http Parser : URLConnection « Network Protocol « Java






Http Parser

    
/**
Copyright (C) 2004  Juho Vh-Herttua

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/


import java.io.*;
import java.util.*;
import java.text.*;
import java.net.URLDecoder;

public class HttpParser {
  private static final String[][] HttpReplies = {{"100", "Continue"},
                                                 {"101", "Switching Protocols"},
                                                 {"200", "OK"},
                                                 {"201", "Created"},
                                                 {"202", "Accepted"},
                                                 {"203", "Non-Authoritative Information"},
                                                 {"204", "No Content"},
                                                 {"205", "Reset Content"},
                                                 {"206", "Partial Content"},
                                                 {"300", "Multiple Choices"},
                                                 {"301", "Moved Permanently"},
                                                 {"302", "Found"},
                                                 {"303", "See Other"},
                                                 {"304", "Not Modified"},
                                                 {"305", "Use Proxy"},
                                                 {"306", "(Unused)"},
                                                 {"307", "Temporary Redirect"},
                                                 {"400", "Bad Request"},
                                                 {"401", "Unauthorized"},
                                                 {"402", "Payment Required"},
                                                 {"403", "Forbidden"},
                                                 {"404", "Not Found"},
                                                 {"405", "Method Not Allowed"},
                                                 {"406", "Not Acceptable"},
                                                 {"407", "Proxy Authentication Required"},
                                                 {"408", "Request Timeout"},
                                                 {"409", "Conflict"},
                                                 {"410", "Gone"},
                                                 {"411", "Length Required"},
                                                 {"412", "Precondition Failed"},
                                                 {"413", "Request Entity Too Large"},
                                                 {"414", "Request-URI Too Long"},
                                                 {"415", "Unsupported Media Type"},
                                                 {"416", "Requested Range Not Satisfiable"},
                                                 {"417", "Expectation Failed"},
                                                 {"500", "Internal Server Error"},
                                                 {"501", "Not Implemented"},
                                                 {"502", "Bad Gateway"},
                                                 {"503", "Service Unavailable"},
                                                 {"504", "Gateway Timeout"},
                                                 {"505", "HTTP Version Not Supported"}};

  private BufferedReader reader;
  private String method, url;
  private Hashtable headers, params;
  private int[] ver;

  public HttpParser(InputStream is) {
    reader = new BufferedReader(new InputStreamReader(is));
    method = "";
    url = "";
    headers = new Hashtable();
    params = new Hashtable();
    ver = new int[2];
  }

  public int parseRequest() throws IOException {
    String initial, prms[], cmd[], temp[];
    int ret, idx, i;

    ret = 200; // default is OK now
    initial = reader.readLine();
    if (initial == null || initial.length() == 0) return 0;
    if (Character.isWhitespace(initial.charAt(0))) {
      // starting whitespace, return bad request
      return 400;
    }

    cmd = initial.split("\\s");
    if (cmd.length != 3) {
      return 400;
    }

    if (cmd[2].indexOf("HTTP/") == 0 && cmd[2].indexOf('.') > 5) {
      temp = cmd[2].substring(5).split("\\.");
      try {
        ver[0] = Integer.parseInt(temp[0]);
        ver[1] = Integer.parseInt(temp[1]);
      } catch (NumberFormatException nfe) {
        ret = 400;
      }
    }
    else ret = 400;

    if (cmd[0].equals("GET") || cmd[0].equals("HEAD")) {
      method = cmd[0];

      idx = cmd[1].indexOf('?');
      if (idx < 0) url = cmd[1];
      else {
        url = URLDecoder.decode(cmd[1].substring(0, idx), "ISO-8859-1");
        prms = cmd[1].substring(idx+1).split("&");

        params = new Hashtable();
        for (i=0; i<prms.length; i++) {
          temp = prms[i].split("=");
          if (temp.length == 2) {
            // we use ISO-8859-1 as temporary charset and then
            // String.getBytes("ISO-8859-1") to get the data
            params.put(URLDecoder.decode(temp[0], "ISO-8859-1"),
                       URLDecoder.decode(temp[1], "ISO-8859-1"));
          }
          else if(temp.length == 1 && prms[i].indexOf('=') == prms[i].length()-1) {
            // handle empty string separatedly
            params.put(URLDecoder.decode(temp[0], "ISO-8859-1"), "");
          }
        }
      }
      parseHeaders();
      if (headers == null) ret = 400;
    }
    else if (cmd[0].equals("POST")) {
      ret = 501; // not implemented
    }
    else if (ver[0] == 1 && ver[1] >= 1) {
      if (cmd[0].equals("OPTIONS") ||
          cmd[0].equals("PUT") ||
          cmd[0].equals("DELETE") ||
          cmd[0].equals("TRACE") ||
          cmd[0].equals("CONNECT")) {
        ret = 501; // not implemented
      }
    }
    else {
      // meh not understand, bad request
      ret = 400;
    }

    if (ver[0] == 1 && ver[1] >= 1 && getHeader("Host") == null) {
      ret = 400;
    }

    return ret;
  }

  private void parseHeaders() throws IOException {
    String line;
    int idx;

    // that fscking rfc822 allows multiple lines, we don't care now
    line = reader.readLine();
    while (!line.equals("")) {
      idx = line.indexOf(':');
      if (idx < 0) {
        headers = null;
        break;
      }
      else {
        headers.put(line.substring(0, idx).toLowerCase(), line.substring(idx+1).trim());
      }
      line = reader.readLine();
    }
  }

  public String getMethod() {
    return method;
  }

  public String getHeader(String key) {
    if (headers != null)
      return (String) headers.get(key.toLowerCase());
    else return null;
  }

  public Hashtable getHeaders() {
    return headers;
  }

  public String getRequestURL() {
    return url;
  }

  public String getParam(String key) {
    return (String) params.get(key);
  }

  public Hashtable getParams() {
    return params;
  }

  public String getVersion() {
    return ver[0] + "." + ver[1];
  }

  public int compareVersion(int major, int minor) {
    if (major < ver[0]) return -1;
    else if (major > ver[0]) return 1;
    else if (minor < ver[1]) return -1;
    else if (minor > ver[1]) return 1;
    else return 0;
  }

  public static String getHttpReply(int codevalue) {
    String key, ret;
    int i;

    ret = null;
    key = "" + codevalue;
    for (i=0; i<HttpReplies.length; i++) {
      if (HttpReplies[i][0].equals(key)) {
        ret = codevalue + " " + HttpReplies[i][1];
        break;
      }
    }

    return ret;
  }

  public static String getDateHeader() {
    SimpleDateFormat format;
    String ret;

    format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.US);
    format.setTimeZone(TimeZone.getTimeZone("GMT"));
    ret = "Date: " + format.format(new Date()) + " GMT";

    return ret;
  }
}

   
    
    
    
  








Related examples in the same category

1.Demonstrate URLConnection.
2.Call a servlet from a Java command line application
3.A CGI POST Example
4.Http authentication header
5.URLConnection.setRequestProperty
6.File size from URL
7.Sending a POST Request Using a URL
8.Check if a file was modified on the server
9.Getting Text from a URL
10.Getting an Image from a URL
11.Sending a POST Request with Parameters From a Java Class
12.Downloading a web page using URL and URLConnection classes
13.Get response header from HTTP request
14.Read / download webpage content
15.Read a GIF or CLASS from an URL save it locally
16.Zip URLConnection
17.Zip URLStream Handler
18.Http Constants
19.Get URLConnection Expiration
20.Locating files by path or URL
21.Download from URL
22.This program demonstrates how to use the URLConnection class for a POST request.
23.Connects to an URL and displays the response header data and the first 10 lines of the requested data.Connects to an URL and displays the response header data and the first 10 lines of the requested data.
24.Load content from URL to string