package org.apache.jmeter.protocol.http.proxy;
/****************************************
* File HttpRequestHdr.java
***************************************/
import java.io.*;
import java.util.StringTokenizer;
import java.util.*;
import java.net.*;
import org.apache.jmeter.samplers.Entry;
import org.apache.jmeter.protocol.http.config.*;
import org.apache.jmeter.protocol.http.sampler.*;
//
// Class: HttpRequestHdr
// Abstract: The headers of the client HTTP request.
//
/****************************************
* !ToDo (Class description)
*
*@author $Author: mstover1 $
*@created $Date: 2002/02/20 01:35:32 $
*@version $Revision: 1.7 $
***************************************/
public class HttpRequestHdr
{
/****************************************
* Http Request method. Such as get or post.
***************************************/
public String method = new String();
/****************************************
* The requested url. The universal resource locator that hopefully uniquely
* describes the object or service the client is requesting.
***************************************/
public String url = new String();
/****************************************
* Version of http being used. Such as HTTP/1.0
***************************************/
public String version = new String();
/****************************************
* !ToDo (Field description)
***************************************/
public String postData = "";
static String CR = "\r\n";
private Map headers = new HashMap();
/****************************************
* Parses a http header from a stream.
*
*@param in The stream to parse.
*@return true if parsing sucsessfull.
***************************************/
public boolean parse(InputStream in)
{
String CR = "\r\n";
/*
* Read by lines
*/
BufferedReader lines;
StringTokenizer tz;
try
{
lines = new BufferedReader(new InputStreamReader(new DataInputStream(in)));
String firstLine = lines.readLine();
tz = new StringTokenizer(firstLine);
}
catch(Exception e)
{
return false;
}
/*
* HTTP COMMAND LINE < <METHOD==get> <URL> <HTTP_VERSION> >
*/
method = getToken(tz).toUpperCase();
url = getToken(tz);
version = getToken(tz);
while(true)
{
String nextLine = null;
try
{
nextLine = lines.readLine();
tz = new StringTokenizer(nextLine);
}
catch(Exception e)
{
return false;
}
String Token = getToken(tz);
// look for termination of HTTP command
if(0 == Token.length())
{
try
{
if(method.equals("POST"))
{
postData = readPostData(lines);
}
}
catch(Exception e)
{
break;
}
break;
}
else
{
if(!Token.trim().equalsIgnoreCase("host:") && !Token.trim().equalsIgnoreCase("referer:") &&
!Token.trim().equalsIgnoreCase("proxy-connection:"))
{
headers.put(Token.trim().substring(0,Token.trim().length()-1),getRemainder(tz));
}
}
}
return true;
}
public Entry getEntry(UrlConfig config) throws MalformedURLException,IOException,ProtocolException
{
Entry entry = new Entry();
config = createUrlConfig(config);
if(config instanceof MultipartUrlConfig)
{
entry.setSamplerClass(MultipartFormSampler.class);
}
else
{
entry.setSamplerClass(HTTPSampler.class);
}
entry.addConfigElement(config,UrlConfig.class);
return entry;
}
public String getContentType()
{
return (String)headers.get("Content-Type");
}
private UrlConfig createUrlConfig(UrlConfig urlConfig)
{
urlConfig = UrlConfig.createConfig(getContentType());
urlConfig.setDomain(serverName());
urlConfig.setMethod(method);
urlConfig.setPath(serverUrl());
urlConfig.setName(urlConfig.getPath());
urlConfig.setProtocol(url.substring(0, url.indexOf(":")));
urlConfig.setPort(serverPort());
urlConfig.parseArguments(postData);
return urlConfig;
}
//
// Parsing Methods
//
/****************************************
* Find the //server.name from an url.
*
*@return Servers internet name
***************************************/
public String serverName()
{
// chop to "server.name:x/thing"
String str = url;
int i = str.indexOf("//");
if(i < 0)
{
return "";
}
str = str.substring(i + 2);
// chop to server.name:xx
i = str.indexOf("/");
if(0 < i)
{
str = str.substring(0, i);
}
// chop to server.name
i = str.indexOf(":");
if(0 < i)
{
str = str.substring(0, i);
}
return str;
}
/****************************************
* Find the :PORT form http://server.ect:PORT/some/file.xxx
*
*@return Servers internet name
***************************************/
public int serverPort()
{
String str = url;
// chop to "server.name:x/thing"
int i = str.indexOf("//");
if(i < 0)
{
return 80;
}
str = str.substring(i + 2);
// chop to server.name:xx
i = str.indexOf("/");
if(0 < i)
{
str = str.substring(0, i);
}
// chop XX
i = str.indexOf(":");
if(0 < i)
{
return Integer.parseInt(str.substring(i + 1).trim());
}
return 80;
}
/****************************************
* Find the /some/file.xxxx form http://server.ect:PORT/some/file.xxx
*
*@return the deproxied url
***************************************/
public String serverUrl()
{
String str = url;
int i = str.indexOf("//");
if(i < 0)
{
return str;
}
str = str.substring(i + 2);
i = str.indexOf("/");
if(i < 0)
{
return str;
}
return str.substring(i);
}
/****************************************
* Returns the next token in a string
*
*@param tk String that is partially tokenized.
*@return !ToDo (Return description)
*@returns The remainder
***************************************/
String getToken(StringTokenizer tk)
{
String str = "";
if(tk.hasMoreTokens())
{
str = tk.nextToken();
}
return str;
}
/****************************************
* Returns the remainder of a tokenized string
*
*@param tk String that is partially tokenized.
*@return !ToDo (Return description)
*@returns The remainder
***************************************/
String getRemainder(StringTokenizer tk)
{
String str = "";
if(tk.hasMoreTokens())
{
str = tk.nextToken();
}
while(tk.hasMoreTokens())
{
str += " " + tk.nextToken();
}
return str;
}
private String readPostData(Reader in) throws IOException
{
StringWriter string = new StringWriter();
char[] buf = new char[4096];
int x = 0;
while((x = in.read(buf)) > 0)
{
string.write(buf, 0, x);
if(!in.ready())
{
break;
}
}
string.close();
return string.toString().trim();
}
}