1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.fcgi.parser;
20
21 import java.nio.ByteBuffer;
22
23 public class EndRequestContentParser extends ContentParser
24 {
25 private final Parser.Listener listener;
26 private State state = State.APPLICATION;
27 private int cursor;
28 private int application;
29 private int protocol;
30
31 public EndRequestContentParser(HeaderParser headerParser, Parser.Listener listener)
32 {
33 super(headerParser);
34 this.listener = listener;
35 }
36
37 @Override
38 public Result parse(ByteBuffer buffer)
39 {
40 while (buffer.hasRemaining())
41 {
42 switch (state)
43 {
44 case APPLICATION:
45 {
46 if (buffer.remaining() >= 4)
47 {
48 application = buffer.getInt();
49 state = State.PROTOCOL;
50 }
51 else
52 {
53 state = State.APPLICATION_BYTES;
54 cursor = 0;
55 }
56 break;
57 }
58 case APPLICATION_BYTES:
59 {
60 int quarterInt = buffer.get() & 0xFF;
61 application = (application << 8) + quarterInt;
62 if (++cursor == 4)
63 state = State.PROTOCOL;
64 break;
65 }
66 case PROTOCOL:
67 {
68 protocol = buffer.get() & 0xFF;
69 state = State.RESERVED;
70 break;
71 }
72 case RESERVED:
73 {
74 if (buffer.remaining() >= 3)
75 {
76 buffer.position(buffer.position() + 3);
77 onEnd();
78 reset();
79 return Result.COMPLETE;
80 }
81 else
82 {
83 state = State.APPLICATION_BYTES;
84 cursor = 0;
85 break;
86 }
87 }
88 case RESERVED_BYTES:
89 {
90 buffer.get();
91 if (++cursor == 0)
92 {
93 onEnd();
94 reset();
95 return Result.COMPLETE;
96 }
97 break;
98 }
99 default:
100 {
101 throw new IllegalStateException();
102 }
103 }
104 }
105 return Result.PENDING;
106 }
107
108 private void onEnd()
109 {
110 if (application != 0)
111 listener.onFailure(getRequest(), new Exception("FastCGI application returned code " + application));
112 else if (protocol != 0)
113 listener.onFailure(getRequest(), new Exception("FastCGI server returned code " + protocol));
114 else
115 listener.onEnd(getRequest());
116 }
117
118 private void reset()
119 {
120 state = State.APPLICATION;
121 cursor = 0;
122 application = 0;
123 protocol = 0;
124 }
125
126 private enum State
127 {
128 APPLICATION, APPLICATION_BYTES, PROTOCOL, RESERVED, RESERVED_BYTES
129 }
130 }