1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.server;
20
21 import java.io.IOException;
22 import java.nio.ByteBuffer;
23
24 import org.eclipse.jetty.util.BlockingCallback;
25 import org.eclipse.jetty.util.BufferUtil;
26 import org.eclipse.jetty.util.Callback;
27 import org.eclipse.jetty.util.log.Log;
28 import org.eclipse.jetty.util.log.Logger;
29
30 public class HttpInputOverHTTP extends HttpInput<ByteBuffer> implements Callback
31 {
32 private static final Logger LOG = Log.getLogger(HttpInputOverHTTP.class);
33 private final BlockingCallback _readBlocker = new BlockingCallback();
34 private final HttpConnection _httpConnection;
35 private ByteBuffer _content;
36
37
38
39
40 public HttpInputOverHTTP(HttpConnection httpConnection)
41 {
42 _httpConnection = httpConnection;
43 }
44
45 @Override
46 public void recycle()
47 {
48 synchronized (lock())
49 {
50 super.recycle();
51 _content=null;
52 }
53 }
54
55 @Override
56 protected void blockForContent() throws IOException
57 {
58 while(true)
59 {
60 _httpConnection.fillInterested(_readBlocker);
61 LOG.debug("{} block readable on {}",this,_readBlocker);
62 _readBlocker.block();
63
64 Object content=getNextContent();
65 if (content!=null || isFinished())
66 break;
67 }
68 }
69
70 @Override
71 public String toString()
72 {
73 return String.format("%s@%x",getClass().getSimpleName(),hashCode());
74 }
75
76 @Override
77 protected ByteBuffer nextContent() throws IOException
78 {
79
80 if (BufferUtil.hasContent(_content))
81 return _content;
82
83
84 _content=null;
85 ByteBuffer requestBuffer = _httpConnection.getRequestBuffer();
86
87 while (!_httpConnection.getParser().isComplete())
88 {
89
90 _httpConnection.getParser().parseNext(requestBuffer==null?BufferUtil.EMPTY_BUFFER:requestBuffer);
91
92
93 if (BufferUtil.hasContent(_content))
94 return _content;
95
96
97 if (BufferUtil.isEmpty(requestBuffer) && _httpConnection.getEndPoint().isInputShutdown())
98 {
99 _httpConnection.getParser().atEOF();
100 continue;
101 }
102
103
104 int filled=_httpConnection.getEndPoint().fill(requestBuffer);
105 if (LOG.isDebugEnabled())
106 LOG.debug("{} filled {}",this,filled);
107 if (filled<=0)
108 {
109 if (filled<0)
110 {
111 _httpConnection.getParser().atEOF();
112 continue;
113 }
114 return null;
115 }
116 }
117
118 return null;
119
120 }
121
122 @Override
123 protected int remaining(ByteBuffer item)
124 {
125 return item.remaining();
126 }
127
128 @Override
129 protected int get(ByteBuffer item, byte[] buffer, int offset, int length)
130 {
131 int l = Math.min(item.remaining(), length);
132 item.get(buffer, offset, l);
133 return l;
134 }
135
136 @Override
137 protected void consume(ByteBuffer item, int length)
138 {
139 item.position(item.position()+length);
140 }
141
142 @Override
143 public void content(ByteBuffer item)
144 {
145 if (BufferUtil.hasContent(_content))
146 throw new IllegalStateException();
147 _content=item;
148 }
149
150 @Override
151 protected void unready()
152 {
153 _httpConnection.fillInterested(this);
154 }
155
156 @Override
157 public void succeeded()
158 {
159 _httpConnection.getHttpChannel().getState().onReadPossible();
160 }
161
162 @Override
163 public void failed(Throwable x)
164 {
165 super.failed(x);
166 _httpConnection.getHttpChannel().getState().onReadPossible();
167 }
168 }