View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.fcgi.parser;
20  
21  import java.nio.ByteBuffer;
22  
23  import org.eclipse.jetty.fcgi.FCGI;
24  
25  public class BeginRequestContentParser extends ContentParser
26  {
27      private final ServerParser.Listener listener;
28      private State state = State.ROLE;
29      private int cursor;
30      private int role;
31      private int flags;
32  
33      public BeginRequestContentParser(HeaderParser headerParser, ServerParser.Listener listener)
34      {
35          super(headerParser);
36          this.listener = listener;
37      }
38  
39      @Override
40      public Result parse(ByteBuffer buffer)
41      {
42          while (buffer.hasRemaining())
43          {
44              switch (state)
45              {
46                  case ROLE:
47                  {
48                      if (buffer.remaining() >= 2)
49                      {
50                          role = buffer.getShort();
51                          state = State.FLAGS;
52                      }
53                      else
54                      {
55                          state = State.ROLE_BYTES;
56                          cursor = 0;
57                      }
58                      break;
59                  }
60                  case ROLE_BYTES:
61                  {
62                      int halfShort = buffer.get() & 0xFF;
63                      role = (role << 8) + halfShort;
64                      if (++cursor == 2)
65                          state = State.FLAGS;
66                      break;
67                  }
68                  case FLAGS:
69                  {
70                      flags = buffer.get() & 0xFF;
71                      state = State.RESERVED;
72                      break;
73                  }
74                  case RESERVED:
75                  {
76                      if (buffer.remaining() >= 5)
77                      {
78                          buffer.position(buffer.position() + 5);
79                          onStart();
80                          reset();
81                          return Result.COMPLETE;
82                      }
83                      else
84                      {
85                          state = State.RESERVED_BYTES;
86                          cursor = 0;
87                          break;
88                      }
89                  }
90                  case RESERVED_BYTES:
91                  {
92                      buffer.get();
93                      if (++cursor == 5)
94                      {
95                          onStart();
96                          reset();
97                          return Result.COMPLETE;
98                      }
99                      break;
100                 }
101                 default:
102                 {
103                     throw new IllegalStateException();
104                 }
105             }
106         }
107         return Result.PENDING;
108     }
109 
110     private void onStart()
111     {
112         listener.onStart(getRequest(), FCGI.Role.from(role), flags);
113     }
114 
115     private void reset()
116     {
117         state = State.ROLE;
118         cursor = 0;
119         role = 0;
120         flags = 0;
121     }
122 
123     private enum State
124     {
125         ROLE, ROLE_BYTES, FLAGS, RESERVED, RESERVED_BYTES
126     }
127 }