在java中安全读取http请求头

在java中安全读取http请求头,java,security,http-headers,Java,Security,Http Headers,我正在用java构建自己的HTTP Web服务器,并希望在从socket inputstream读取HTTP请求头时实现一些安全措施 我试图阻止这样一种情况:某人发送非常长的单行标题或大量的标题行会导致内存溢出或其他您不想要的事情 我目前正试图通过将8kb的数据读入一个字节数组并解析我刚刚创建的缓冲区中的所有头来实现这一点。 但据我所知,这意味着您的inputstream的当前偏移量始终是从它的起点开始的8kb,即使您只有100字节的头 到目前为止,我掌握的代码是: InputStream st

我正在用java构建自己的HTTP Web服务器,并希望在从socket inputstream读取HTTP请求头时实现一些安全措施

我试图阻止这样一种情况:某人发送非常长的单行标题或大量的标题行会导致内存溢出或其他您不想要的事情

我目前正试图通过将8kb的数据读入一个字节数组并解析我刚刚创建的缓冲区中的所有头来实现这一点。 但据我所知,这意味着您的inputstream的当前偏移量始终是从它的起点开始的8kb,即使您只有100字节的头

到目前为止,我掌握的代码是:

InputStream stream = socket.getInputStream();

HashMap<String, String> headers = new HashMap<String, String>();

byte [] buffer = new byte[8*1024];

stream.read( buffer , 0 , 8*1024);
ByteArrayInputStream bytestream = new ByteArrayInputStream( buffer );
InputStreamReader streamReader = new InputStreamReader( bytestream );
BufferedReader reader = new BufferedReader( streamReader );

String requestline = reader.readLine();

for ( ;; )
{
    String line = reader.readLine();
    if ( line.equals( "" ) )
        break;

    String[] header = line.split( ":" , 2 );

    headers.put( header[0] , header[1] ); //TODO: check for bad header
}

//if contentlength > 0
//      read body
InputStream=socket.getInputStream();
HashMap headers=新的HashMap();
字节[]缓冲区=新字节[8*1024];
读取(缓冲区,0,8*1024);
ByteArrayInputStream bytestream=新的ByteArrayInputStream(缓冲区);
InputStreamReader streamReader=新的InputStreamReader(ByTestStream);
BufferedReader reader=新的BufferedReader(streamReader);
字符串requestline=reader.readLine();
对于(;;)
{
字符串行=reader.readLine();
if(第行等于(“”)
打破
String[]header=line.split(“:”,2);
headers.put(头[0],头[1]);//TODO:检查错误头
}
//如果contentlength>0
//阅读正文
所以我的问题是,如何确保我从inputstream中的正确位置开始读取主体数据(如果有)


我并不经常使用流,所以我对它们没有真正的感觉,而且谷歌到目前为止也没有什么帮助

我自己找到了答案。(比我想象的要容易)

如果我猜它没有被缓冲(我不知道什么时候缓冲了),但它是有效的

public class SafeHttpHeaderReader
{   
    public static final int MAX_READ = 8*1024;
    private InputStream stream;
    private int bytesRead;

    public SafeHttpHeaderReader(InputStream stream)
    {
        this.stream = stream;
        bytesRead = 0;
    }

    public boolean hasReachedMax()
    {
        return bytesRead >= MAX_READ;
    }

    public String readLine() throws IOException, Http400Exception
    {
        String s = "";

        while(bytesRead < MAX_READ)
        {
            String n = read();

            if(n.equals( "" ))
                break;

            if(n.equals( "\r" ))
            {
                if(read().equals( "\n" ))
                    break;

                throw new Http400Exception();
            }
            s += n;
        }

        return s;
    }

    private String read() throws IOException
    {
        byte b = readByte();

        if(b == -1)
            return "";

        return new String( new byte[]{b} , "ASCII");
    }

    private byte readByte() throws IOException
    {
        byte b = (byte) stream.read();
        bytesRead ++;
        return b;
    }
}
公共类安全HttpHeaderReader
{   
公共静态最终整数最大读取=8*1024;
私有输入流;
私有int字节读;
公共安全HttpHeaderReader(输入流)
{
this.stream=流;
字节读取=0;
}
公共布尔值hasReachedMax()
{
返回字节读取>=最大读取;
}
公共字符串readLine()引发IOException,Http400Exception
{
字符串s=“”;
while(字节读取<最大读取)
{
字符串n=read();
如果(n等于(“”)
打破
如果(n等于(“\r”))
{
如果(read().equals(“\n”))
打破
抛出新的Http400Exception();
}
s+=n;
}
返回s;
}
私有字符串read()引发IOException
{
字节b=读取字节();
如果(b==-1)
返回“”;
返回新字符串(新字节[]{b},“ASCII”);
}
私有字节readByte()引发IOException
{
字节b=(字节)stream.read();
bytesRead++;
返回b;
}
}

您可以查看ApacheTomcat源代码,了解它们是如何实现的