我已经编写了一个代理来拦截我的tomcat的http请求。
每个请求都会通过我的代理并在到达tomcat服务器之前进行一些检查。我是通过使用java编写的TCP / IP绑定端口来实现的。
除文件上传(多部分POST表单)提交外,所有请求(GET和POST)都能成功路由到tomcat服务器。
即使我能够获取TCP / IP中的所有字节并且能够将数据刷回到tomcat服务器,但数据会被截断/丢失
是否有任何特殊的东西,比如编码等......在处理文件流内容时我需要做什么?
下面是我的示例代码......
protected void processData(InputStream input, OutputStream output) throws IOException
{
// reads a line of text from an InputStream
StringBuffer data = new StringBuffer("");
StringBuffer data2 = new StringBuffer("");
StringBuffer data3 = new StringBuffer("");
StringBuffer data4 = new StringBuffer("");
int c;
try
{
while ((c = input.read()) >= 0)
{
data.append((char) c);
// check for an end-of-line character
if ((c == 0) || (c == 10) || (c == 13))
{
output.write(data.toString().getBytes(), 0, data.length());
data4.append(data.toString());
data = new StringBuffer();
count = 0;
}
else
{
if (count > 6)
{
if (input.available() == 1)
{
data.append((char) input.read());
}
data2.append(data.toString());
data4.append(data.toString());
output.write(data.toString().getBytes(), 0, data
.toString().length());
data = new StringBuffer();
}
else
{
if (count == 6)
{
if (data.toString().toLowerCase()
.indexOf("get /") == 0
|| data.toString().toLowerCase()
.indexOf("post /") == 0)
{
count = 0;
contentLength = -1;
// continue read data(header info)
while ((line = readLine(input, data)) != null)
{
data = new StringBuffer();
// do my own stuff here dealing with headers
if (StringUtils.isBlank(line))
{
data4.append(line);
output.write(line.getBytes(), 0,
line.length());
break;
}
line += "\r\n";
output.write(line.getBytes(), 0,
line.length());
data4.append(line);
output.flush();
}
}
else
{
if (input.available() == 1)
{
data.append((char) input.read());
}
}
}
else
{
if (input.available() == 1)
{
data.append((char) input.read());
output.write(data.toString().getBytes(), 0,
data.toString().length());
data4.append(data.toString());
data3.append(data.toString());
data = new StringBuffer();
}
}
}
count++;
}
if (processbody)
total++;
if (contentLength > 0 && contentLength == total)
{
log.debug("post data2: "
+ (data2.toString() != null ? data2.toString() : " "));
log.debug("post data3: "
+ (data3.toString() != null ? data3.toString() : " "));
log.debug("post data4: "
+ (data4.toString() != null ? data4.toString() : " "));
output.flush();
}
}
}
catch (Exception e)
{
log.error("Error ", e);
}
finally
{
}
}
答案 0 :(得分:1)
你正在努力做到这一点。只需读取字节并将其写入另一侧。您不关心字符串或字符串缓冲区或行终止字符。
答案 1 :(得分:1)
您的代码中存在一些缺陷:
您从byte
读取每个InputStream
,然后将其转换为char
并将其附加到字符串构建器。如果流是编码字符,例如中文,希腊语,任何特殊字符,这将无法正确解码流成可读字符串。或者,如果流是纯二进制或ascii,则字符串不是存储流的最佳选择。当您提交文件多部分请求时,这很容易发生。
我不是并发专家(所以我可能会说这里没有意义)但如果同时有多个连接会发生什么。你应该对此感到满意。
从我看到的,你想要处理http请求的标题,所以没有理由你不应该像Alexey Sviridov建议的那样使用servlet过滤器。您可以实现自己的过滤器来拦截标头并对其执行某些操作。使用过滤器的好处是,您可以让servlet API为您解析所请求的标头,您无需担心何时读取/写入输入/输出流。
但是,如果您打算拦截请求的标头并决定是将请求传递到您的tomcat或servlet容器,还是执行不在servlet范围内的任何操作,那么您应该查看http代理库。这是一个例子:
http://proxies.xhaus.com/java/
先前有关于堆栈溢出writting HTTP Proxy in Java的问题。
遗憾的是,我不想鼓励您编写自己的http代理。你必须考虑太多的顾虑。