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 import org.eclipse.jetty.fcgi.FCGI;
24 import org.eclipse.jetty.http.HttpField;
25
26 public abstract class Parser
27 {
28 protected final HeaderParser headerParser = new HeaderParser();
29 private State state = State.HEADER;
30 private int padding;
31
32
33
34
35
36 public boolean parse(ByteBuffer buffer)
37 {
38 while (true)
39 {
40 switch (state)
41 {
42 case HEADER:
43 {
44 if (!headerParser.parse(buffer))
45 return false;
46 state = State.CONTENT;
47 break;
48 }
49 case CONTENT:
50 {
51 ContentParser contentParser = findContentParser(headerParser.getFrameType());
52 if (headerParser.getContentLength() == 0)
53 {
54 contentParser.noContent();
55 }
56 else
57 {
58 ContentParser.Result result = contentParser.parse(buffer);
59 if (result == ContentParser.Result.PENDING)
60 {
61
62 return false;
63 }
64 if (result == ContentParser.Result.ASYNC)
65 {
66
67
68 return true;
69 }
70 }
71 padding = headerParser.getPaddingLength();
72 state = State.PADDING;
73 break;
74 }
75 case PADDING:
76 {
77 if (buffer.remaining() >= padding)
78 {
79 buffer.position(buffer.position() + padding);
80 reset();
81 break;
82 }
83 else
84 {
85 padding -= buffer.remaining();
86 buffer.position(buffer.limit());
87 return false;
88 }
89 }
90 default:
91 {
92 throw new IllegalStateException();
93 }
94 }
95 }
96 }
97
98 protected abstract ContentParser findContentParser(FCGI.FrameType frameType);
99
100 private void reset()
101 {
102 headerParser.reset();
103 state = State.HEADER;
104 padding = 0;
105 }
106
107 public interface Listener
108 {
109 public void onHeader(int request, HttpField field);
110
111 public void onHeaders(int request);
112
113
114
115
116
117
118
119
120 public boolean onContent(int request, FCGI.StreamType stream, ByteBuffer buffer);
121
122 public void onEnd(int request);
123
124 public void onFailure(int request, Throwable failure);
125
126 public static class Adapter implements Listener
127 {
128 @Override
129 public void onHeader(int request, HttpField field)
130 {
131 }
132
133 @Override
134 public void onHeaders(int request)
135 {
136 }
137
138 @Override
139 public boolean onContent(int request, FCGI.StreamType stream, ByteBuffer buffer)
140 {
141 return false;
142 }
143
144 @Override
145 public void onEnd(int request)
146 {
147 }
148
149 @Override
150 public void onFailure(int request, Throwable failure)
151 {
152
153 }
154 }
155 }
156
157 private enum State
158 {
159 HEADER, CONTENT, PADDING
160 }
161 }