/******************************************************************************* * Copyright (c) 2010 Yadu. * 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: * Yadu - initial API and implementation ******************************************************************************/ package code.google.restclient.client; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; import code.google.restclient.common.RCConstants; import code.google.restclient.common.RCUtil; import code.google.restclient.mime.MimeTypeUtil; /** * @author Yaduvendra.Singh */ public class ViewRequest { private static final Logger LOG = Logger.getLogger(ViewRequest.class); private static final boolean DEBUG_ENABLED = LOG.isDebugEnabled(); private String method; private String url; private String headersStr; private String paramsStr; private String bodyStr; private String fileParamName; private String filePath; private boolean isTextBody = true; private boolean isMultipart = false; private boolean isEncodeBody = false; private String reqLine; private String host; private int port; private String scheme; private String path; private String queryStrRaw; private String protocolVersion; private Map<String, String> headers = new HashMap<String, String>(); public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getBodyStr() { return bodyStr; } public void setBodyStr(String bodyStr) { this.bodyStr = bodyStr; } public String getFileParamName() { return fileParamName; } public void setFileParamName(String fileParamName) { this.fileParamName = fileParamName; } public String getFilePath() { return filePath; } public void setFilePath(String filePath) { this.filePath = filePath; } public boolean isTextBody() { return isTextBody; } public void setTextBody(boolean isTextBody) { this.isTextBody = isTextBody; } public boolean isMultipart() { return isMultipart; } public void setMultipart(boolean isMultipart) { this.isMultipart = isMultipart; } public boolean isEncodeBody() { return isEncodeBody; } public void setEncodeBody(boolean encodeBody) { isEncodeBody = encodeBody; } public String getReqLine() { return reqLine; } public void setReqLine(String reqLine) { this.reqLine = reqLine; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getScheme() { return scheme; } public void setScheme(String scheme) { this.scheme = scheme; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getQueryStrRaw() { return queryStrRaw; } public void setQueryStrRaw(String queryStrRaw) { this.queryStrRaw = queryStrRaw; } public String getProtocolVersion() { return protocolVersion; } public void setProtocolVersion(String protocolVersion) { this.protocolVersion = protocolVersion; } public Map<String, String> getHeaders() { return headers; } public void setHeaders(Map<String, String> headers) { this.headers = headers; } public String getHeadersStr() { return headersStr; } public void setHeadersStr(String headersStr) { this.headersStr = headersStr; } public String getParamsStr() { return paramsStr; } public void setParamsStr(String paramsStr) { this.paramsStr = paramsStr; } public String getUrlToHit() throws UnsupportedEncodingException { if ( url == null || "".equals(url) ) throw new IllegalArgumentException("URL can not be null"); String urlToHit = url; String paramsString = getParamsBodyStr(false); // paramsStr; if ( !getParams().isEmpty() ) { if ( !RCUtil.isEntityEnclosingMethod(method) || (RCUtil.isEntityEnclosingMethod(method) && !isMultipart && (!isEmptyBodyStr() || !RCUtil.isEmpty(filePath))) ) { if ( !urlToHit.contains("?") ) urlToHit += "?"; else paramsString = "&" + paramsString; urlToHit += paramsString; } } return RCUtil.encodeUrl(urlToHit); } public Map<String, String> getInputHeaders() throws UnsupportedEncodingException { return RCUtil.getMapFromStr(headersStr); } public Map<String, String> getParams() { return RCUtil.getMapFromStr(paramsStr); } public String getBodyToPost() throws IOException { // if non multipart post String body = null; if ( !RCUtil.isEmpty(filePath) ) body = "@" + filePath; else if ( !isEmptyBodyStr() ) body = bodyStr; // else if( !getParams().isEmpty() ) body = getParamsBodyStr(); return body; } public String getParamsBodyStr(boolean encode) throws UnsupportedEncodingException { String paramsString = paramsStr; if ( !RCUtil.isEntityEnclosingMethod(method) || (RCUtil.isEntityEnclosingMethod(method) && !(RCUtil.isEmpty(filePath) && isEmptyBodyStr())) ) { // encode '&' if they are going to be part of url paramsString = paramsString.replaceAll("&", RCUtil.encode("&")); } if ( !encode ) return paramsString.replaceAll("\n", "&").replaceAll("\r", ""); else { StringBuilder sb = new StringBuilder(); Map<String, String> params = getParams(); for ( String name : params.keySet() ) { sb.append("&"); sb.append(RCUtil.encode(name)); sb.append("="); sb.append(RCUtil.encode(params.get(name))); // decode first to get encoded '&' back } return sb.toString().replaceFirst("&", ""); } } public String getDisplayHeaderPart() { StringBuilder sb = new StringBuilder(); try { if ( reqLine != null ) { // HTTP1.1 specifies to use absolute URL if not sending 'host' header. httpcomponents // sends 'host' header by default so not using absolute URL here sb.append(getShortReqLine()); for ( String key : headers.keySet() ) sb.append("\n" + key + ": " + headers.get(key)); } } catch ( Exception e ) { LOG.error("getDisplayHeaderPart(): error while preaparing req headers to display => ", e); } return sb.toString(); } public String getDisplayBodyPart() { StringBuilder displayBodyPart = new StringBuilder(); try { if ( RCUtil.isEntityEnclosingMethod(method) ) { Map<String, String> params = getParams(); if ( isMultipart ) displayBodyPart.append(getMultipartDisplayBodyPart()); else if ( !RCUtil.isEmpty(filePath) ) displayBodyPart.append(getFileContent()); else if ( !isEmptyBodyStr() ) displayBodyPart.append(bodyStr); else if ( !params.isEmpty() ) displayBodyPart.append(getParamsBodyStr(true)); } } catch ( Exception e ) { LOG.error("getDisplayBodyPart(): error while preparing req body to display => ", e); } return displayBodyPart.toString(); } private String getMultipartDisplayBodyPart() throws IOException { String contentType = headers.get("Content-Type"); if ( contentType != null && !contentType.startsWith(RCConstants.MULTIPART_CONTENT_TYPE) ) return ""; String boundaryStr = "-----------------------------" + contentType.substring(contentType.indexOf("boundary")); String paramTmpl = boundaryStr + " Content-Disposition: form-data; name=\"@PARAM_NAME@\";" + "\nContent-Type: text/plain; charset=\"UTF-8\"" + "\n" + "\n@PARAM_VALUE@"; String fileTmpl = boundaryStr + " Content-Disposition: form-data; name=\"@PARAM_NAME@\"; filename=\"@FILE_NAME@\"" + "\nContent-Type: text/plain" + "\n" + "\n@FILE_CONTENT@"; StringBuilder sb = new StringBuilder(); for ( String paramName : getParams().keySet() ) { sb.append("\n"); String paramBodyStr = paramTmpl.replace("@PARAM_NAME@", RCUtil.encode(paramName)); paramBodyStr = paramBodyStr.replace("@PARAM_VALUE@", RCUtil.encode(getParams().get(paramName))); sb.append(paramBodyStr); } if ( !RCUtil.isEmpty(fileParamName) && !RCUtil.isEmpty(filePath) ) { String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1); String fileStr = fileTmpl.replace("@PARAM_NAME@", fileParamName); fileStr = fileStr.replace("@FILE_NAME@", fileName); fileStr = fileStr.replace("@FILE_CONTENT@", getFileContent()); sb.append("\n"); sb.append(fileStr); } sb.append("\n" + boundaryStr + "--"); return sb.toString().replaceFirst("\n", ""); } private String getSimpleMultipartDisplayBodyPart() throws IOException { StringBuilder sb = new StringBuilder(); if ( !getParams().isEmpty() ) sb.append(getParamsBodyStr(true)); if ( !RCUtil.isEmpty(fileParamName) && !RCUtil.isEmpty(filePath) ) { if ( !getParams().isEmpty() ) sb.append("&"); sb.append(fileParamName + "=" + getFileContent()); } return sb.toString(); } private String getFileContent() throws UnsupportedEncodingException, IOException { float size = (float) getFileSize() / 1024; // Kilo Bytes if ( isTextBodyOK() && size != 0 && size <= 5 ) return RCUtil.getFileContent(filePath, false); else return "[content @ " + filePath + "]"; } private boolean isEmptyBodyStr() { if ( !RCUtil.isEmpty(bodyStr) && !RCConstants.BODY_TEXT.equals(bodyStr) ) return false; else return true; } public boolean isPostParams() throws IOException { if ( RCUtil.isEmpty(filePath) && RCUtil.isEmpty(bodyStr) && !getParams().isEmpty() ) return true; else return false; } private long getFileSize() { File file = new File(filePath); long size = 0; if ( file.exists() ) size = file.length(); return size; } private String getShortReqLine() { String reqLineShort = method + " " + (RCUtil.isEmpty(path) ? "/" : path) + (RCUtil.isEmpty(queryStrRaw) ? "" : "?" + queryStrRaw) + " " + protocolVersion; return reqLineShort; } private boolean isTextBodyOK() { LOG.debug("isTextBodyOK() - here ..."); boolean isText = isTextBody; try { if ( !RCUtil.isEmpty(filePath) ) { File file = new File(filePath); String mimeType = MimeTypeUtil.getMimeType(file); // use stream first // use extension if ( RCConstants.OCTET_MIME_TYPE.equals(mimeType) ) mimeType = MimeTypeUtil.getMimeType(filePath); if ( !RCConstants.OCTET_MIME_TYPE.equals(mimeType) ) { String mediaType = MimeTypeUtil.getMediaType(filePath); if ( "text".equalsIgnoreCase(mediaType) ) isText = true; } } } catch ( Exception e ) { LOG.warn("isTextBodyOK(): could not use mime detector to determine mime type." + " Accepting file type selected by user"); } return isText; } public void clear() { method = null; url = null; headersStr = null; paramsStr = null; bodyStr = null; fileParamName = null; filePath = null; isTextBody = false; isMultipart = false; isEncodeBody = false; reqLine = null; host = null; port = -1; scheme = null; path = null; queryStrRaw = null; protocolVersion = null; headers.clear(); } }