2013-04-30 30 views
2

我有使用Netty实现的代理服务器,在该服务器中,我解码HTTP请求,然后根据它们的路径将这些请求写入传出通道。我需要从HTTP请求的内容中提取一些信息用于将来的处理(基本上,找到一个“request-id:”形式的子字符串并记录以备后用。最好的办法是什么?显然,我可以将通道缓冲区的内容转储为一个字符串并使用标准的java字符串搜索技术,但是在netty中有没有一种简单而低成本的方式来做到这一点,而不创建一个新的字符串?例如,如果有像一个对于ChannelBuffer类型asCharSequence(CharSet)方法,我可以只使用一个java模式/匹配器。为netty搜索一个字符串的ChannelBuffer的最佳方式(不用新建一个字符串)?

回答

2

前段时间我碰到这个问题,因为我试图嗅探一个ChannelBuffer中包含的字节的内容类型。

它发生,我认为你可以使用:

channelBuffer.toByteBuffer().asCharBuffer() 

然后你可以传递给正则表达式Pattern.Matcher,因为这不会重新分配缓冲区,而只是被包装和重新代表,就像它一样。但是这不起作用,因为CharBuffer需要进行Charset.decoded,这可能与将ChannelBuffer转换为字符串一样糟糕。

ChannelBufferIndexFinder的其中一个问题是,当你搜索一个特定的字节时,当你搜索一个字符串(或者更基本上是一个长度大于1的字节数组)时,它往往工作得最好,我不能按照我想要的方式工作。

我开始在这家名为ByteSequenceIndexFinder ChannelBufferIndexFinder实现这有助于找到一个ChannelBuffer类型中的字节的实际顺序的工作,但有几个问题吧:

  1. 因为这样ChannelBuffer.bytesBefore(...)作品,它不会返回定位数组的直接偏移量,而是返回它的结尾,所以您必须从返回的索引中减去字节数组长度+1,以获取字节缓冲区内字节序列开始的偏移量。
  2. 由于查找器必须保持状态(迄今为止匹配的字节数),因此它不是线程安全的。我尝试用ThreadLocal替换简单状态(一个int),但性能大幅降低,但它仍然是一个选项。

实际上,有是非标准的那个地址问题#1的替代调用方法和它的工作原理是这样的:

ChannelBuffer bufferToSearch = ...; 
String searchStr = "...."; 
ByteSequenceIndexFinder finder = new ByteSequenceIndexFinder(searchStr.getBytes()); 
int startingOffset = finder.findIn(bufferToSearch); 

这startingOffset是内偏移匹配的字节序列的第一个字节通道缓冲区。

希望如果您需要这样的东西,它可能对您有所帮助。 This是它的测试案例的开始。

0

我使用以下实施ChannelBufferIndexFinderChannelBuffer搜索字符串:

public class StringFinder implements ChannelBufferIndexFinder { 

    private String string; 

    public StringFinder(String string) { 
     this.string = string; 
    } 

    @Override 
    public boolean find(ChannelBuffer buffer, int guessedIndex) { 

     if (buffer.writerIndex() - guessedIndex < string.length()) { 
      return false; 
     } 

     return string.equals(buffer.toString(guessedIndex, 
       string.length(), Charset.defaultCharset())); 
    } 

} 
相关问题