📄 requestparametermap.java
字号:
/*
* SSL-Explorer
*
* Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Parts of the code that deal with multipart/form-data parsing are (loosely)
* based on Jettys MultipartRequest. See license below.
*
* 24/02/2005 - brett@3sp.com
*
*/
//========================================================================
//$Id$
//Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
//------------------------------------------------------------------------
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//http://www.apache.org/licenses/LICENSE-2.0
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//========================================================================
package com.sslexplorer.replacementproxy;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sslexplorer.boot.RequestHandlerRequest;
import com.sslexplorer.boot.Util;
public class RequestParameterMap extends HashMap {
private static final long serialVersionUID = -2005125971106236972L;
final static Log log = LogFactory.getLog(RequestParameterMap.class);
public final static String ISO_8859_1;
static {
String iso = System.getProperty("ISO_8859_1");
if (iso != null)
ISO_8859_1 = iso;
else {
try {
new String(new byte[] {
(byte) 20
}, "ISO-8859-1");
iso = "ISO-8859-1";
} catch (java.io.UnsupportedEncodingException e) {
iso = "ISO8859_1";
}
ISO_8859_1 = iso;
}
}
private LineInput input;
private String boundary;
private byte[] boundaryBytes;
private boolean finished;
private File multipartFile;
private long multipartLength;
private int ch;
private String proxiedURL;
private String destinationURL;
private String sslxTicket;
public RequestParameterMap() {
super();
ch = -2;
}
public RequestParameterMap(RequestHandlerRequest request) throws IOException {
this();
String contentType = request.getField("content-type");
if (contentType != null && contentType.startsWith("multipart/form-data")) {
initMultipart(contentType, request.getInputStream());
} else {
Map params = request.getParameters();
for (Iterator e = params.keySet().iterator(); e.hasNext();) {
String n = (String) e.next();
Object obj = params.get(n);
if(!checkForSSLXUrl(n, obj)) {
if (obj instanceof String[]) {
put(n, ((String[])obj)[0]);
} else if (obj instanceof String) {
put(n, obj);
} else
log.warn("Parameter value is an unexepected type " +
obj.getClass().getName());
}
}
}
}
private boolean checkForSSLXUrl(String n, Object params) {
String val;
if(params instanceof String[]) {
val = ((String[])params)[0];
} else
val = (String) params;
if(n.equals("sslex_url")) {
proxiedURL = val;
return true;
}else if(n.equals("dest_url")) {
destinationURL = val;
return true;
} else if(n.equals("sslx_ticket")) {
sslxTicket = val;
return true;
}
return false;
}
public boolean isFormData() {
return multipartFile != null;
}
public String getTicket() {
return sslxTicket;
}
public InputStream getFormData() throws IOException, FileNotFoundException {
if (multipartFile == null) {
throw new IOException("This request was not of type multipart/form-data.");
}
return new FileMultipartInputStream(multipartFile);
}
public long getFormDataLength() throws IOException {
if (multipartFile == null) {
throw new IOException("This request was not of type multipart/form-data.");
}
return multipartLength;
}
private void initMultipart(String contentType, InputStream in) throws IOException, FileNotFoundException {
multipartFile = File.createTempFile("mpr", ".tmp");
FileOutputStream mpOut = new FileOutputStream(multipartFile);
try {
input = new LineInput(in);
boundary = "--" + Util.valueOfNameValuePair(contentType.substring(contentType.indexOf("boundary=")));
boundaryBytes = (boundary + "--").getBytes(ISO_8859_1);// Get
// first
// boundary
String line = input.readLine();
if (!line.equals(boundary)) {
throw new IOException("Missing initial multi part boundary");
}
byte[] buf = (line + "\r\n").getBytes();
multipartLength += buf.length;
mpOut.write(buf);
while (!finished) {
String contentDisposition = null;
Map parms = new TreeMap();
while ((line = input.readLine()) != null) {
if (line.length() == 0)
break;
int idx = line.indexOf(':', 0);
if (idx > 0) {
String key = line.substring(0, idx).trim();
String value = line.substring(idx + 1, line.length()).trim();
List cur = (List) parms.get(key);
if (cur == null) {
cur = new ArrayList();
parms.put(key, cur);
}
cur.add(value);
if (key.equalsIgnoreCase("content-disposition"))
contentDisposition = value;
}
}
boolean form = false;
if (contentDisposition == null) {
throw new IOException("Missing content-disposition");
}
StringTokenizer tok = new StringTokenizer(contentDisposition, ";");
String name = null;
String filename = null;
while (tok.hasMoreTokens()) {
String t = tok.nextToken().trim();
String tl = t.toLowerCase();
if (t.startsWith("form-data"))
form = true;
else if (tl.startsWith("name="))
name = Util.valueOfNameValuePair(t);
else if (tl.startsWith("filename="))
filename = Util.valueOfNameValuePair(t);
}
// Check disposition
if (!form) {
log.warn("Non form-data part in multipart/form-data");
continue;
}
if (name.equals("sslex_url")) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
readBytes(input, baos, null);
proxiedURL = Util.urlDecode(new String(baos.toString()));
} else if (name.equals("dest_url")) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
readBytes(input, baos, null);
destinationURL = Util.urlDecode(new String(baos.toString()));
} else {
for (Iterator i = parms.keySet().iterator(); i.hasNext();) {
String key = (String) i.next();
List list = (List) parms.get(key);
for (Iterator j = list.iterator(); j.hasNext();) {
String val = (String) j.next();
buf = (key + ": " + val + "\r\n").getBytes();
multipartLength += buf.length;
mpOut.write(buf);
}
}
buf = "\r\n".getBytes();
multipartLength += buf.length;
mpOut.write(buf);
if (filename != null) {
readBytes(input, null, mpOut);
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
readBytes(input, baos, mpOut);
add(Util.urlDecode(name), baos.toString());
}
}
}
} finally {
Util.closeStream(mpOut);
}
}
public String getProxiedURL() {
return proxiedURL;
}
public String getDestinationURL() {
return destinationURL;
}
public void add(String key, String value) {
/* String[] v = (String[]) super.get(key);
if (v == null) {
v = new String[1];
} else {
String[] x = new String[v.length + 1];
System.arraycopy(v, 0, x, 0, v.length);
}
v[v.length - 1] = value;*/
put(key, value);
}
public String getParameter(Object name) {
return (String) get(name);
}
public Iterator getParameterNames() {
return keySet().iterator();
}
/*public String[] getParameterValues(String name) {
return (String[]) super.get(name);
}*/
private void readBytes(InputStream in, OutputStream out, OutputStream recorded) throws IOException {
int c;
boolean cr = false;
boolean lf = false;
// loop for all lines`
while (true) {
int b = 0;
while ((c = (ch != -2) ? ch : readWrite(in, recorded)) != -1) {
multipartLength++;
ch = -2;
// look for CR and/or LF
if (c == 13 || c == 10) {
if (c == 13) {
ch = readWrite(in, recorded);
multipartLength++;
}
break;
}
// look for boundary
if (b >= 0 && b < boundaryBytes.length && c == boundaryBytes[b])
b++;
else {
// this is not a boundary
if (cr && out != null)
out.write(13);
if (lf && out != null)
out.write(10);
cr = lf = false;
if (b > 0 && out != null)
out.write(boundaryBytes, 0, b);
b = -1;
if (out != null)
out.write(c);
}
}
// check partial boundary
if ((b > 0 && b < boundaryBytes.length - 2) || (b == boundaryBytes.length - 1)) {
if (cr && out != null)
out.write(13);
if (lf && out != null)
out.write(10);
cr = lf = false;
if (out != null)
out.write(boundaryBytes, 0, b);
b = -1;
}
// boundary match
if (b > 0 || c == -1) {
if (b == boundaryBytes.length)
finished = true;
if (ch == 10)
ch = -2;
break;
}
// handle CR LF
if (cr && out != null)
out.write(13);
if (lf && out != null)
out.write(10);
cr = (c == 13);
lf = (c == 10 || ch == 10);
if (ch == 10)
ch = -2;
}
}
private int readWrite(InputStream in, OutputStream out) throws IOException {
int i = in.read();
if (i != -1 && out != null) {
out.write(i);
}
return i;
}
class FileMultipartInputStream extends FileInputStream {
private File file;
public FileMultipartInputStream(File file) throws FileNotFoundException {
super(file);
this.file = file;
}
public void close() throws IOException {
super.close();
file.delete();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -