View Javadoc

1   /*******************************************************************************
2    * Copyright (c) 2011 Michael Mimo Moratti.
3    *
4    * Michael Mimo Moratti licenses this file to you under the Apache License, version 2.0
5    * (the "License"); you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at:
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
11   * License for the specific language governing permissions and limitations
12   * under the License.
13   *******************************************************************************/
14  package ch.mimo.netty.handler.codec.icap;
15  
16  import java.util.List;
17  
18  import org.jboss.netty.buffer.ChannelBuffer;
19  import org.jboss.netty.handler.codec.http.HttpChunkTrailer;
20  import org.jboss.netty.handler.codec.http.HttpHeaders;
21  
22  /**
23   * Decoder State that reads http trailing headers.
24   * 
25   * @author Michael Mimo Moratti (mimo@mimo.ch)
26   *
27   * @see IcapMessageDecoder
28   * @see StateEnum
29   */
30  public class ReadTrailingHeadersState extends State<Object> {
31  
32  	public ReadTrailingHeadersState(String name) {
33  		super(name);
34  	}
35  	
36  	@Override
37  	public void onEntry(ChannelBuffer buffer, IcapMessageDecoder icapMessageDecoder) throws DecodingException {
38  	}
39  
40  	@Override
41  	public StateReturnValue execute(ChannelBuffer buffer, IcapMessageDecoder icapMessageDecoder) throws DecodingException {
42  		SizeDelimiter sizeDelimiter = new SizeDelimiter(icapMessageDecoder.maxHttpHeaderSize);
43  		boolean preview = icapMessageDecoder.message.isPreviewMessage();
44          String line = IcapDecoderUtil.readSingleHeaderLine(buffer,sizeDelimiter);
45          String lastHeader = null;
46          if (line.length() != 0) {
47              HttpChunkTrailer trailer = new DefaultIcapChunkTrailer(preview,false);
48              do {
49                  char firstChar = line.charAt(0);
50                  if (lastHeader != null && (firstChar == ' ' || firstChar == '\t')) {
51                      List<String> current = trailer.getHeaders(lastHeader);
52                      if (current.size() != 0) {
53                          int lastPos = current.size() - 1;
54                          String newString = current.get(lastPos) + line.trim();
55                          current.set(lastPos, newString);
56                      } else {
57                          // Content-Length, Transfer-Encoding, or Trailer
58                      }
59                  } else {
60                      String[] header = IcapDecoderUtil.splitHeader(line);
61                      String name = header[0];
62                      if (!name.equalsIgnoreCase(HttpHeaders.Names.CONTENT_LENGTH) &&
63                          !name.equalsIgnoreCase(HttpHeaders.Names.TRANSFER_ENCODING) &&
64                          !name.equalsIgnoreCase(HttpHeaders.Names.TRAILER)) {
65                          trailer.addHeader(name, header[1]);
66                      }
67                      lastHeader = name;
68                  }
69  
70                  line = IcapDecoderUtil.readSingleHeaderLine(buffer,sizeDelimiter);
71              } while (line.length() != 0);
72  
73              return StateReturnValue.createRelevantResult(trailer);
74          }
75          return StateReturnValue.createRelevantResult(new DefaultIcapChunkTrailer(preview,false));
76  	}
77  
78  	@Override
79  	public StateEnum onExit(ChannelBuffer buffer, IcapMessageDecoder icapMessageDecoder, Object decisionInformation) throws DecodingException {
80  		return null;
81  	}
82  }