/*******************************************************************************
* Copyright © 2006, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.edt.javart.services.servlet.proxy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
public class RuiBrowserHttpRequest
{
private String URL;
private Map<String, String> headers;
private Map<String, String> arguments;
private String method;
private String content;
private Map<String, String> contentArguments;
public static String CONTENT_LENGTH_ID = "Content-Length";
public static String JSON_RPC_GET_METHOD_ID = "GET";
public static final int MAX_NUMBER_CHARS = Integer.MAX_VALUE;
private RuiBrowserHttpRequest(){
}
public static RuiBrowserHttpRequest createNewRequest(javax.servlet.http.HttpServletRequest httpServletReq ) throws IOException {
RuiBrowserHttpRequest newRequest = new RuiBrowserHttpRequest();
newRequest.method = httpServletReq.getMethod();
newRequest.URL = httpServletReq.getRequestURI(); //processRequestURL(request);
newRequest.headers = processHeaders(httpServletReq);
if( JSON_RPC_GET_METHOD_ID.equalsIgnoreCase( newRequest.method ) )
{
newRequest.arguments = httpServletReq.getParameterMap();//processArgs(request);
}
BufferedReader reader = httpServletReq.getReader();
newRequest.content = processContent(httpServletReq.getContentLength(), reader);
return newRequest;
}
public static RuiBrowserHttpRequest createNewRequest(Socket client) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream(), "utf-8"));
String request = reader.readLine();
if(request != null){
RuiBrowserHttpRequest newRequest = new RuiBrowserHttpRequest();
newRequest.method = request.substring(0, request.indexOf(' ')).trim();
request = request.substring(request.indexOf(' ')); // strip GET header
request = request.substring(0, request.lastIndexOf(' ')); // strip HTTP/1.0 trailer
newRequest.URL = processRequestURL(request);
newRequest.arguments = processArgs(request);
newRequest.headers = processHeaders(reader);
newRequest.content = processContent(getContentLength(newRequest), reader);
return newRequest;
}else{
return null;
}
}
private static int getContentLength(RuiBrowserHttpRequest request) {
String lengthString = (String)request.headers.get(CONTENT_LENGTH_ID);
if(lengthString == null || lengthString.length() == 0 )
{
for( Iterator<String> itr = request.headers.keySet().iterator(); itr.hasNext(); ){
String key = itr.next();
if( CONTENT_LENGTH_ID.equalsIgnoreCase((String)key) ){
lengthString = (String)request.headers.get(key);
break;
}
}
}
int contentLength = -1;
if( lengthString != null ){
try{
contentLength = Integer.parseInt(lengthString);
}
catch(NumberFormatException nfe ){}
}
return contentLength;
}
private static Map<String, String> processContentArgs(String request) {
return processArgs("?" + request);
}
/**
* @return The content parsed as arguments. The content uses '&' as a delimeter,
* so any values in the key-value pairs must have '&' escaped, else
* the parsing may throw an exception. Do not call this method if
* this is not guarenteed by the content for a particular request
* (e.g. JSON requests)!
*/
public Map<String, String> getContentArguments() {
if (this.contentArguments == null) {
this.contentArguments = processContentArgs(content);
}
return this.contentArguments;
}
public String getURL(){
return URL;
}
public String getMethod(){
return method;
}
public Map<String, String> getHeaders(){
return headers;
}
public String getContent(){
return content;
}
private static String processContent(int contentLength, BufferedReader reader) throws IOException
{
StringBuilder contentBuffer = new StringBuilder();
if( contentLength > 0 ){
//int nRead = reader.read();
for (int i = 0; i < contentLength; )
{
char nRead = (char)reader.read();
contentBuffer.append(nRead);
//need to calculate the byte count of a character
String str = Character.toString(nRead);
byte[] bytes = str.getBytes("utf-8");
i += bytes.length;
}
}
return contentBuffer.toString();
}
public static Map<String, String> processHeaders(javax.servlet.http.HttpServletRequest httpServletReq) throws IOException{
Map<String, String> result = new HashMap<String, String>();
Enumeration headerEnum = httpServletReq.getHeaderNames();
while(headerEnum.hasMoreElements()){
String headername = (String)headerEnum.nextElement();
result.put(headername, httpServletReq.getHeader(headername));
}
return result;
}
private static Map<String, String> processHeaders(BufferedReader reader) throws IOException{
Map<String, String> result = new HashMap<String, String>();
String header = reader.readLine();
while(header != null && header.length() > 0){
String label = header.substring(0, header.indexOf(':'));
String value = header.substring(header.indexOf(':') + 2);
result.put(label, value);
header = reader.readLine();
}
return result;
}
private static String processRequestURL(String request) {
int questionMarkIndex = request.indexOf('?');
if (questionMarkIndex != -1) {
return request.substring(0, questionMarkIndex);
}
return request;
}
private static Map<String, String> processArgs(String request) {
Map<String, String> arguments = new HashMap<String, String>();
int questionMarkIndex = request.indexOf('?');
if (questionMarkIndex != -1) {
request = request.substring(questionMarkIndex+1);
StringTokenizer arg = new StringTokenizer(request, "&");
while (arg.hasMoreTokens()) {
try{
String nextToken = arg.nextToken();
String key = nextToken.substring(0, nextToken.indexOf("="));
String value = URLDecoder.decode(nextToken.substring(nextToken.indexOf("=") + 1), "UTF-8");
if("contextKey".equals(key)){
value = value.replace(".js", "");
}
arguments.put(key, value);
} catch (UnsupportedEncodingException e) {
// Ignore this argument
}
}
}
return arguments;
}
public String toString(){
StringBuilder result = new StringBuilder();
result.append("METHOD: " + method + "\n");
result.append("URL: " + URL + "\n");
result.append("Arguments: \n");
for (Iterator<String> iter = arguments.keySet().iterator(); iter.hasNext();) {
String argument = iter.next();
result.append("\t" + argument + " = " + (String)arguments.get(argument) + "\n");
}
result.append("Headers: \n");
for (Iterator<String> iter = headers.keySet().iterator(); iter.hasNext();) {
String header = iter.next();
result.append("\t" + header + " = " + headers.get(header) + "\n");
}
return result.toString();
}
public Map<String, String> getArguments() {
return arguments;
}
public void setURL(String url) {
this.URL = url;
}
}