[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 695
  • Last Modified:

How do I get my HTTP request handler to accept file uploads?

Hello,
I have written a small HTTP server in Java, its for me to toy around with and use as a basis for other projects. I am having some issues now with receiving HTTP uploads. Initially I had left this ability out of the spec of my http server, but it appears now I need the functionality, so I have gone back and recoded my request object to support it, but whenever I use it (in an upload scenario - everything else works fine) I get a connection reset error.
            I was hoping someone could tell me how to fix my code so that it works properly. Here's what its supposed to do: first it reads all the http header information passed, and stores it in a hashtable for easy reference. After the header is collected if it is a post command, it collects the additional data and stores it in the hashtable as well, finally, if it finds the content type to be multi-part form data, it reads in the remaining bytes, and should process them into another hashtable stored value (for later processing, or writing to disk).

A working fix to this is worth 500 points. The function in question is called processRequest.

Thanks,
Rick


Here is the code:

/*
 * Request.java
 *
 * Created on January 13, 2007, 1:25 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */


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

/**
 *
 * @author Rick
 */
public class Request
{    
    /** Creates a new instance of Request */
    Socket client;
    Hashtable requestHeaders;
    config cfg;
    int errorLevel = 0;
   
    public Request(Socket client, config cfg)
    {
        this.client = client;
        this.cfg = cfg;
        requestHeaders = new Hashtable();
    }
   
    public boolean requestValueExists(String value)
    {
        return (requestHeaders.get(value) != null);
    }
   
    public void processRequest()
    {
        //grabs the whole header and sets the request hashtable up
        try
        {
            //get the request
            BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream(),"8859_1"));
            String req_in = "";
            int line = 0;
            requestHeaders.put("local_ip",client.getLocalAddress().getHostAddress());
           
            while ((req_in=in.readLine()).length() > 0)
            {
                //System.out.println(req_in);
                if (line == 0)
                {
                    //it is the page requested break it apart into query string, requested page, request type, and protocol, also set the requesting ip, and hostname
                   String reqs[] = req_in.split(" ");
                   
                   //set up the request type
                   requestHeaders.put("request_method",reqs[0].replace('/',' ').trim());
                   
                   //first split the requested file by ?
                   String tw[] = reqs[1].split("\\?");
                   
                   requestHeaders.put("page_requested",tw[0]);
                     
                   if (tw.length == 2)
                        requestHeaders.put("query_string",tw[1]);
                   
                   //set up the protocol
                   requestHeaders.put("remote_protocol",reqs[2]);
       
                   //get the hostname and ip of the requester
                   String hostnameIP = client.getInetAddress().toString();      
                   String clientInfo[] = hostnameIP.split("/");
           
                   //set up the remote hostname
                   requestHeaders.put("remote_hostname",clientInfo[0]);
                   
                   //set up the remote ip
                   requestHeaders.put("remote_ip",clientInfo[0]);  
                   
                   line=1;
                }
                else
                {
                    //split the string by :
                    String reqs[] = req_in.split(":");
                   
                    if (reqs.length == 2)
                        requestHeaders.put(reqs[0].toLowerCase().trim(),reqs[1].trim());
                    else
                        requestHeaders.put(reqs[0].toLowerCase().trim(),reqs[1].trim() + ":" + reqs[2].trim());
                }
            }   /* end of get request headers */
           
            //now check to see if there is any POST data to collect
            if ((requestHeaders.get("request_method").toString().compareTo("POST") == 0) && (requestHeaders.containsKey("content-length")) && (requestHeaders.containsKey("content-type")))
            {
                //it is a post method and there is data to collect so collect it
                //first get the total content length
                int contentLength = new Integer(requestHeaders.get("content-length").toString()).intValue();
               
                char[] postdata = new char[contentLength];
               
                //read in til the length is hit
                in.read(postdata,0,contentLength);
               
                String post_data = new String(postdata);
               
                //determine if it is a normal form submit or a multi-part form submit
                if (requestHeaders.get("content-type").toString().indexOf("multipart/form-data; boundary=") > -1)
                {
                    //get the data boundary
                    String boundary = "--" + requestHeaders.get("content-type").toString().replaceAll("multipart/form-data; boundary=","");
                   
                    //split the post_data apart by the boundary leaving data parts + 1
                    String formdata[] = post_data.split(boundary);
                   
                    System.out.println("Data Parts: " + formdata.length);
                    System.out.println("------------------");
                   
                    //process each of the data parts
                    for (int i=0; i < formdata.length; i++)
                    {
                        //System.out.println("DataPart " + i);
                       
                        //first find the Content-Disposition
                        int start = formdata[i].toLowerCase().indexOf("content-disposition: form-data; name=");
                        int end = formdata[i].toLowerCase().indexOf("\r\n",start+1);
                       
                        //System.out.println("Start:" + start);
                        //System.out.println("End:" + end);
                       
                        if ((start > -1) && (start < end))
                        {
                            String disposition = formdata[i].substring(start,end);
                       
                            //now determine if the disposution type is formdata or a file upload
                            if (disposition.toLowerCase().indexOf("filename") > -1)
                            {
                                //it is a file upload so lets start by collecting the variable name and value
                               
                                //first split the disposition by ;
                                String uploaddata[] = disposition.split(";");
                               
                                String key = uploaddata[1].toLowerCase().replaceAll("name=","").replaceAll("\"","");
                                String value = uploaddata[2].toLowerCase().replaceAll("filename=","").replaceAll("\"","");
                               
                                requestHeaders.put(key.trim(),value.trim());
                               
                                //ok lets pull the disposition line out of the data
                                String data = formdata[i].replaceAll(disposition,"");
                               
                                //ok now we have to grab the content type of the file
                                start = formdata[i].toLowerCase().indexOf("content-type");
                                end = formdata[i].toLowerCase().indexOf("\r\n",start);
                               
                                String content_type = formdata[i].substring(start,end);
                               
                                requestHeaders.put("file-content-type",content_type.split(":")[1].trim());
                               
                                //remove the content_type
                                System.out.println(data.replaceAll(content_type,"").trim().getBytes().length);
                                requestHeaders.put(value.trim(),data.replaceAll(content_type,"").trim().getBytes());                                
                            }
                            else
                            {
                                if (disposition.split("=")[1].length() > 0)
                                //it is a normal data variable so get the key / value pair and insert it into the request hash
                                requestHeaders.put(disposition.split("=")[1].replaceAll("\"",""),formdata[i].replaceAll(disposition,"").replaceAll("\r\n",""));
                            }
                        }
                        //System.out.println("--------------------");
                    }
                }
                else
                {
               
                    //convert it to a string
                    String pdata[] = post_data.split("&");
               
                    //loop over the results and split by the = sign
                    for (int i = 0; i < pdata.length; i++)
                    {
                        String data[] = pdata[i].split("=");
                        if(data.length == 2)
                            requestHeaders.put(data[0],URLDecoder.decode(data[1]));
                        else
                            requestHeaders.put(data[0],"");
                    }
                }
            }    
        }
        catch(Exception e)
        {
            cfg.writeLog("HTTP Request: Client Connection Error. (" + e.toString() + ").");
            e.printStackTrace();
            errorLevel = 1;
        }
    } // end of processRequest()
   
    public Enumeration getKeyList()
    {
        //return an enumeration of all the key values in the requestHeader hash
        return requestHeaders.keys();
    }
   
    public String getRequestValue(String value)
    {
        //return the requested value from the requestHeader hash
        return requestHeaders.get(value).toString();
    }
   
   
}
0
richardsimnett
Asked:
richardsimnett
  • 4
1 Solution
 
ksivananthCommented:
can you post the exception stack too?
0
 
richardsimnettAuthor Commented:
It doesnt throw an exception at all. Instead the browser simply stops, and displays a message connection reset. It only does this on files larger than 1k, and that are binary. Small text files (<1k) go through fine.

Thanks,
Rick
0
 
objectsCommented:
u can't use a Reader to read binary data, need to use an InputStream
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
richardsimnettAuthor Commented:
objects,
is it possible to use a combination of BufferedReader and InputStream? Basically use a buffered reader to read the HTTP header, and then an InputStream to read in the post data?

Thanks,
Rick
0
 
richardsimnettAuthor Commented:
nevermind that last question. I proved it cant be done. Im re-coding the entire thing to use inputstream. I will post my results.

Thanks,
Rick
0
 
richardsimnettAuthor Commented:
Objects,
Got it works well with InputStream.

Thanks!
Rick
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now