jruby-http-kit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +72 -0
  7. data/Rakefile +1 -0
  8. data/example/config.ru +9 -0
  9. data/example/hello_world.rb +17 -0
  10. data/example/rack.rb +11 -0
  11. data/example/ring.rb +31 -0
  12. data/example/sinatra/app.rb +9 -0
  13. data/example/sinatra/config.ru +8 -0
  14. data/example/webmachine/Gemfile +4 -0
  15. data/example/webmachine/Gemfile.lock +16 -0
  16. data/example/webmachine/app.rb +37 -0
  17. data/jruby-http-kit.gemspec +25 -0
  18. data/lib/http_kit/rack_handler.rb +139 -0
  19. data/lib/http_kit/server.rb +62 -0
  20. data/lib/http_kit/version.rb +3 -0
  21. data/lib/http_kit.rb +6 -0
  22. data/lib/java/clojure-1.5.1.jar +0 -0
  23. data/lib/java/http-kit.jar +0 -0
  24. data/lib/rack/handler/http_kit.rb +3 -0
  25. data/lib/rack/http_kit.rb +3 -0
  26. data/lib/webmachine/adapters/ring.rb +135 -0
  27. data/spec/spec_helper.rb +24 -0
  28. data/spec/support/test_resource.rb +75 -0
  29. data/spec/webmachine/ring_adapter_spec.rb +127 -0
  30. data/src/.classpath +7 -0
  31. data/src/.project +17 -0
  32. data/src/org/httpkit/BytesInputStream.class +0 -0
  33. data/src/org/httpkit/BytesInputStream.java +83 -0
  34. data/src/org/httpkit/DateFormatter.class +0 -0
  35. data/src/org/httpkit/DynamicBytes.class +0 -0
  36. data/src/org/httpkit/DynamicBytes.java +76 -0
  37. data/src/org/httpkit/HTTPException.class +0 -0
  38. data/src/org/httpkit/HTTPException.java +10 -0
  39. data/src/org/httpkit/HeaderMap.class +0 -0
  40. data/src/org/httpkit/HeaderMap.java +98 -0
  41. data/src/org/httpkit/HttpMethod.class +0 -0
  42. data/src/org/httpkit/HttpMethod.java +28 -0
  43. data/src/org/httpkit/HttpStatus.class +0 -0
  44. data/src/org/httpkit/HttpStatus.java +416 -0
  45. data/src/org/httpkit/HttpUtils.class +0 -0
  46. data/src/org/httpkit/HttpUtils.java +484 -0
  47. data/src/org/httpkit/HttpVersion.class +0 -0
  48. data/src/org/httpkit/HttpVersion.java +5 -0
  49. data/src/org/httpkit/LineReader.class +0 -0
  50. data/src/org/httpkit/LineReader.java +52 -0
  51. data/src/org/httpkit/LineTooLargeException.class +0 -0
  52. data/src/org/httpkit/LineTooLargeException.java +13 -0
  53. data/src/org/httpkit/PrefixThreadFactory.class +0 -0
  54. data/src/org/httpkit/PrefixThreadFactory.java +20 -0
  55. data/src/org/httpkit/PriorityQueue.class +0 -0
  56. data/src/org/httpkit/PriorityQueue.java +235 -0
  57. data/src/org/httpkit/ProtocolException.class +0 -0
  58. data/src/org/httpkit/ProtocolException.java +10 -0
  59. data/src/org/httpkit/RequestTooLargeException.class +0 -0
  60. data/src/org/httpkit/RequestTooLargeException.java +10 -0
  61. data/src/org/httpkit/client/AbortException.class +0 -0
  62. data/src/org/httpkit/client/AbortException.java +13 -0
  63. data/src/org/httpkit/client/Decoder.class +0 -0
  64. data/src/org/httpkit/client/Decoder.java +182 -0
  65. data/src/org/httpkit/client/Handler.class +0 -0
  66. data/src/org/httpkit/client/HttpClient.class +0 -0
  67. data/src/org/httpkit/client/HttpClient.java +393 -0
  68. data/src/org/httpkit/client/HttpsRequest.class +0 -0
  69. data/src/org/httpkit/client/HttpsRequest.java +141 -0
  70. data/src/org/httpkit/client/IFilter$1.class +0 -0
  71. data/src/org/httpkit/client/IFilter$MaxBodyFilter.class +0 -0
  72. data/src/org/httpkit/client/IFilter.class +0 -0
  73. data/src/org/httpkit/client/IFilter.java +53 -0
  74. data/src/org/httpkit/client/IRespListener.class +0 -0
  75. data/src/org/httpkit/client/IRespListener.java +30 -0
  76. data/src/org/httpkit/client/IResponseHandler.class +0 -0
  77. data/src/org/httpkit/client/IResponseHandler.java +18 -0
  78. data/src/org/httpkit/client/PersistentConn.class +0 -0
  79. data/src/org/httpkit/client/PersistentConn.java +33 -0
  80. data/src/org/httpkit/client/Request.class +0 -0
  81. data/src/org/httpkit/client/Request.java +74 -0
  82. data/src/org/httpkit/client/RequestConfig.class +0 -0
  83. data/src/org/httpkit/client/RequestConfig.java +28 -0
  84. data/src/org/httpkit/client/RespListener.class +0 -0
  85. data/src/org/httpkit/client/RespListener.java +160 -0
  86. data/src/org/httpkit/client/SslContextFactory.class +0 -0
  87. data/src/org/httpkit/client/SslContextFactory.java +79 -0
  88. data/src/org/httpkit/client/State.class +0 -0
  89. data/src/org/httpkit/client/TimeoutException.class +0 -0
  90. data/src/org/httpkit/client/TimeoutException.java +12 -0
  91. data/src/org/httpkit/client/TrustManagerFactory$1.class +0 -0
  92. data/src/org/httpkit/client/TrustManagerFactory.class +0 -0
  93. data/src/org/httpkit/server/AsyncChannel.class +0 -0
  94. data/src/org/httpkit/server/AsyncChannel.java +286 -0
  95. data/src/org/httpkit/server/ClojureRing.class +0 -0
  96. data/src/org/httpkit/server/Frame$BinaryFrame.class +0 -0
  97. data/src/org/httpkit/server/Frame$CloseFrame.class +0 -0
  98. data/src/org/httpkit/server/Frame$PingFrame.class +0 -0
  99. data/src/org/httpkit/server/Frame$TextFrame.class +0 -0
  100. data/src/org/httpkit/server/Frame.class +0 -0
  101. data/src/org/httpkit/server/Frame.java +73 -0
  102. data/src/org/httpkit/server/HttpAtta.class +0 -0
  103. data/src/org/httpkit/server/HttpAtta.java +10 -0
  104. data/src/org/httpkit/server/HttpDecoder$State.class +0 -0
  105. data/src/org/httpkit/server/HttpDecoder.class +0 -0
  106. data/src/org/httpkit/server/HttpDecoder.java +202 -0
  107. data/src/org/httpkit/server/HttpHandler.class +0 -0
  108. data/src/org/httpkit/server/HttpRequest.class +0 -0
  109. data/src/org/httpkit/server/HttpRequest.java +109 -0
  110. data/src/org/httpkit/server/HttpServer.class +0 -0
  111. data/src/org/httpkit/server/HttpServer.java +281 -0
  112. data/src/org/httpkit/server/IHandler.class +0 -0
  113. data/src/org/httpkit/server/IHandler.java +12 -0
  114. data/src/org/httpkit/server/LinkingRunnable.class +0 -0
  115. data/src/org/httpkit/server/Rack.class +0 -0
  116. data/src/org/httpkit/server/RackApplication.class +0 -0
  117. data/src/org/httpkit/server/RackApplication.java +10 -0
  118. data/src/org/httpkit/server/RackHandler$1.class +0 -0
  119. data/src/org/httpkit/server/RackHandler.class +0 -0
  120. data/src/org/httpkit/server/RackHandler.java +259 -0
  121. data/src/org/httpkit/server/RackHttpHandler.class +0 -0
  122. data/src/org/httpkit/server/RackHttpHandler.java +20 -0
  123. data/src/org/httpkit/server/RespCallback.class +0 -0
  124. data/src/org/httpkit/server/RespCallback.java +19 -0
  125. data/src/org/httpkit/server/RingHandler$1.class +0 -0
  126. data/src/org/httpkit/server/RingHandler.class +0 -0
  127. data/src/org/httpkit/server/RingHandler.java +222 -0
  128. data/src/org/httpkit/server/ServerAtta.class +0 -0
  129. data/src/org/httpkit/server/ServerAtta.java +22 -0
  130. data/src/org/httpkit/server/WSDecoder$State.class +0 -0
  131. data/src/org/httpkit/server/WSDecoder.class +0 -0
  132. data/src/org/httpkit/server/WSDecoder.java +181 -0
  133. data/src/org/httpkit/server/WSHandler.class +0 -0
  134. data/src/org/httpkit/server/WsAtta.class +0 -0
  135. data/src/org/httpkit/server/WsAtta.java +11 -0
  136. data/src/org/httpkit/timer/CancelableFutureTask.class +0 -0
  137. data/src/org/httpkit/timer/CancelableFutureTask.java +52 -0
  138. data/src/org/httpkit/timer/TimerService.class +0 -0
  139. data/src/org/httpkit/timer/TimerService.java +89 -0
  140. metadata +241 -0
@@ -0,0 +1,235 @@
1
+ package org.httpkit;
2
+
3
+ import java.util.Arrays;
4
+ import java.util.Queue;
5
+
6
+ /**
7
+ * Copy and modified from java.util.PriorityQueue. Remove unused method. Modify
8
+ * {@code remove} to return the removed element
9
+ * <p/>
10
+ * used by timer and the client
11
+ *
12
+ * @param <E>
13
+ */
14
+ @SuppressWarnings("unchecked")
15
+ public class PriorityQueue<E> {
16
+
17
+ private static final int DEFAULT_INITIAL_CAPACITY = 11;
18
+
19
+ /**
20
+ * Priority queue represented as a balanced binary heap: the two children of
21
+ * queue[n] are queue[2*n+1] and queue[2*(n+1)]. The priority queue is
22
+ * ordered by comparator, or by the elements' natural ordering, if
23
+ * comparator is null: For each node n in the heap and each descendant d of
24
+ * n, n <= d. The element with the lowest value is in queue[0], assuming the
25
+ * queue is nonempty.
26
+ */
27
+ private transient Object[] queue;
28
+
29
+ /**
30
+ * The number of elements in the priority queue.
31
+ */
32
+ private int size = 0;
33
+
34
+ /**
35
+ * Creates a {@code PriorityQueue} with the specified initial capacity that
36
+ * orders its elements according to their {@linkplain Comparable natural
37
+ * ordering}.
38
+ * <p/>
39
+ * the initial capacity for this priority queue
40
+ *
41
+ * @throws IllegalArgumentException if {@code initialCapacity} is less than 1
42
+ */
43
+ public PriorityQueue() {
44
+ this.queue = new Object[DEFAULT_INITIAL_CAPACITY];
45
+ }
46
+
47
+ /**
48
+ * The maximum size of array to allocate. Some VMs reserve some header words
49
+ * in an array. Attempts to allocate larger arrays may result in
50
+ * OutOfMemoryError: Requested array size exceeds VM limit
51
+ */
52
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
53
+
54
+ /**
55
+ * Increases the capacity of the array.
56
+ *
57
+ * @param minCapacity the desired minimum capacity
58
+ */
59
+ private void grow(int minCapacity) {
60
+ int oldCapacity = queue.length;
61
+ // Double size if small; else grow by 50%
62
+ int newCapacity = oldCapacity
63
+ + ((oldCapacity < 64) ? (oldCapacity + 2) : (oldCapacity >> 1));
64
+ // overflow-conscious code
65
+ if (newCapacity - MAX_ARRAY_SIZE > 0)
66
+ newCapacity = hugeCapacity(minCapacity);
67
+ queue = Arrays.copyOf(queue, newCapacity);
68
+ }
69
+
70
+ private static int hugeCapacity(int minCapacity) {
71
+ if (minCapacity < 0) // overflow
72
+ throw new OutOfMemoryError();
73
+ return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
74
+ }
75
+
76
+ /**
77
+ * Inserts the specified element into this priority queue.
78
+ *
79
+ * @return {@code true} (as specified by {@link Queue#offer})
80
+ * @throws ClassCastException if the specified element cannot be compared with elements
81
+ * currently in this priority queue according to the priority
82
+ * queue's ordering
83
+ * @throws NullPointerException if the specified element is null
84
+ */
85
+ public boolean offer(E e) {
86
+ if (e == null)
87
+ throw new NullPointerException();
88
+ int i = size;
89
+ if (i >= queue.length)
90
+ grow(i + 1);
91
+ size = i + 1;
92
+ if (i == 0)
93
+ queue[0] = e;
94
+ else
95
+ siftUp(i, e);
96
+ return true;
97
+ }
98
+
99
+ /**
100
+ * Retrieves, but does not remove, the head of this queue, or returns null
101
+ * if this queue is empty.
102
+ *
103
+ * @return
104
+ */
105
+ public E peek() {
106
+ if (size == 0)
107
+ return null;
108
+ return (E) queue[0];
109
+ }
110
+
111
+ /**
112
+ * Removes a single instance of the specified element from this queue, if it
113
+ * is present. More formally, removes an element {@code e} such that
114
+ * {@code o.equals(e)}, if this queue contains one or more such elements.
115
+ * Returns {@code true} if and only if this queue contained the specified
116
+ * element (or equivalently, if this queue changed as a result of the call).
117
+ *
118
+ * @param o element to be removed from this queue, if present
119
+ * @return Element removed
120
+ */
121
+ public E remove(Object o) {
122
+ for (int i = 0; i < size; i++) {
123
+ if (queue[i].equals(o)) {
124
+ E e = (E) queue[i];
125
+ removeAt(i);
126
+ return e;
127
+ }
128
+ }
129
+ return null;
130
+ }
131
+
132
+ public int size() {
133
+ return size;
134
+ }
135
+
136
+ /**
137
+ * Retrieves and removes the head of this queue, or returns null if this
138
+ * queue is empty.
139
+ */
140
+ public E poll() {
141
+ if (size == 0)
142
+ return null;
143
+ int s = --size;
144
+ E result = (E) queue[0];
145
+ E x = (E) queue[s];
146
+ queue[s] = null;
147
+ if (s != 0)
148
+ siftDown(0, x);
149
+ return result;
150
+ }
151
+
152
+ /**
153
+ * Removes the ith element from queue.
154
+ * <p/>
155
+ * Normally this method leaves the elements at up to i-1, inclusive,
156
+ * untouched. Under these circumstances, it returns null. Occasionally, in
157
+ * order to maintain the heap invariant, it must swap a later element of the
158
+ * list with one earlier than i. Under these circumstances, this method
159
+ * returns the element that was previously at the end of the list and is now
160
+ * at some position before i. This fact is used by iterator.remove so as to
161
+ * avoid missing traversing elements.
162
+ */
163
+ private E removeAt(int i) {
164
+ assert i >= 0 && i < size;
165
+ int s = --size;
166
+ if (s == i) // removed last element
167
+ queue[i] = null;
168
+ else {
169
+ E moved = (E) queue[s];
170
+ queue[s] = null;
171
+ siftDown(i, moved);
172
+ if (queue[i] == moved) {
173
+ siftUp(i, moved);
174
+ if (queue[i] != moved)
175
+ return moved;
176
+ }
177
+ }
178
+ return null;
179
+ }
180
+
181
+ /**
182
+ * Inserts item x at position k, maintaining heap invariant by promoting x
183
+ * up the tree until it is greater than or equal to its parent, or is the
184
+ * root.
185
+ * <p/>
186
+ * To simplify and speed up coercions and comparisons. the Comparable and
187
+ * Comparator versions are separated into different methods that are
188
+ * otherwise identical. (Similarly for siftDown.)
189
+ *
190
+ * @param k the position to fill
191
+ * @param x the item to insert
192
+ */
193
+ private void siftUp(int k, E x) {
194
+ Comparable<? super E> key = (Comparable<? super E>) x;
195
+ while (k > 0) {
196
+ int parent = (k - 1) >>> 1;
197
+ Object e = queue[parent];
198
+ if (key.compareTo((E) e) >= 0)
199
+ break;
200
+ queue[k] = e;
201
+ k = parent;
202
+ }
203
+ queue[k] = key;
204
+ }
205
+
206
+ /**
207
+ * Inserts item x at position k, maintaining heap invariant by demoting x
208
+ * down the tree repeatedly until it is less than or equal to its children
209
+ * or is a leaf.
210
+ *
211
+ * @param k the position to fill
212
+ * @param x the item to insert
213
+ */
214
+ private void siftDown(int k, E x) {
215
+ Comparable<? super E> key = (Comparable<? super E>) x;
216
+ int half = size >>> 1; // loop while a non-leaf
217
+ while (k < half) {
218
+ int child = (k << 1) + 1; // assume left child is least
219
+ Object c = queue[child];
220
+ int right = child + 1;
221
+ if (right < size && ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
222
+ c = queue[child = right];
223
+ if (key.compareTo((E) c) <= 0)
224
+ break;
225
+ queue[k] = c;
226
+ k = child;
227
+ }
228
+ queue[k] = key;
229
+ }
230
+
231
+ @Override
232
+ public String toString() {
233
+ return "size=" + size;
234
+ }
235
+ }
@@ -0,0 +1,10 @@
1
+ package org.httpkit;
2
+
3
+ public class ProtocolException extends HTTPException {
4
+
5
+ private static final long serialVersionUID = 1L;
6
+
7
+ public ProtocolException(String msg) {
8
+ super(msg);
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ package org.httpkit;
2
+
3
+ public class RequestTooLargeException extends HTTPException {
4
+
5
+ private static final long serialVersionUID = 1L;
6
+
7
+ public RequestTooLargeException(String msg) {
8
+ super(msg);
9
+ }
10
+ }
@@ -0,0 +1,13 @@
1
+ package org.httpkit.client;
2
+
3
+ import org.httpkit.HTTPException;
4
+
5
+ public class AbortException extends HTTPException {
6
+
7
+ public AbortException(String msg) {
8
+ super(msg);
9
+ }
10
+
11
+ private static final long serialVersionUID = 1L;
12
+
13
+ }
@@ -0,0 +1,182 @@
1
+ package org.httpkit.client;
2
+
3
+ import org.httpkit.*;
4
+
5
+ import java.nio.ByteBuffer;
6
+ import java.util.Map;
7
+ import java.util.TreeMap;
8
+
9
+ import static org.httpkit.HttpUtils.*;
10
+ import static org.httpkit.HttpVersion.HTTP_1_0;
11
+ import static org.httpkit.HttpVersion.HTTP_1_1;
12
+ import static org.httpkit.client.State.*;
13
+
14
+ enum State {
15
+ ALL_READ, READ_CHUNK_DELIMITER, READ_CHUNK_FOOTER, READ_CHUNK_SIZE,
16
+ READ_CHUNKED_CONTENT, READ_FIXED_LENGTH_CONTENT, READ_HEADER, READ_INITIAL,
17
+ READ_VARIABLE_LENGTH_CONTENT
18
+ }
19
+
20
+ public class Decoder {
21
+
22
+ private final Map<String, Object> headers = new TreeMap<String, Object>();
23
+ // package visible
24
+ final IRespListener listener;
25
+ private final LineReader lineReader;
26
+ int readRemaining = 0;
27
+ State state = READ_INITIAL;
28
+ private final HttpMethod method;
29
+
30
+ private boolean emptyBodyExpected = false;
31
+
32
+ public Decoder(IRespListener listener, HttpMethod method) {
33
+ this.listener = listener;
34
+ this.method = method;
35
+ lineReader = new LineReader(8096);
36
+ }
37
+
38
+ private void parseInitialLine(String sb) throws ProtocolException, AbortException {
39
+ int aStart;
40
+ int aEnd;
41
+ int bStart;
42
+ int bEnd;
43
+ int cStart;
44
+ int cEnd;
45
+
46
+ aStart = findNonWhitespace(sb, 0);
47
+ aEnd = findWhitespace(sb, aStart);
48
+
49
+ bStart = findNonWhitespace(sb, aEnd);
50
+ bEnd = findWhitespace(sb, bStart);
51
+
52
+ cStart = findNonWhitespace(sb, bEnd);
53
+ cEnd = findEndOfString(sb);
54
+
55
+ if ((cStart < cEnd)
56
+ // Account for buggy web servers that omit Reason-Phrase from Status-Line.
57
+ // http://www.w3.org/Protocols/HTTP/1.0/draft-ietf-http-spec.html#Response
58
+ || (cStart == cEnd && bStart < bEnd)) {
59
+ try {
60
+ int status = Integer.parseInt(sb.substring(bStart, bEnd));
61
+ // status is not 1xx, 204 or 304, then the body is unbounded.
62
+ // RFC2616, section 4.4
63
+ emptyBodyExpected = status / 100 == 1 || status == 204 || status == 304;
64
+ HttpStatus s = HttpStatus.valueOf(status);
65
+
66
+ HttpVersion version = HTTP_1_1;
67
+ if ("HTTP/1.0".equals(sb.substring(aStart, aEnd))) {
68
+ version = HTTP_1_0;
69
+ }
70
+
71
+ listener.onInitialLineReceived(version, s);
72
+ state = READ_HEADER;
73
+ } catch (NumberFormatException e) {
74
+ throw new ProtocolException("not http protocol? " + sb);
75
+ }
76
+ } else {
77
+ throw new ProtocolException("not http protocol? " + sb);
78
+ }
79
+ }
80
+
81
+ public State decode(ByteBuffer buffer) throws LineTooLargeException, ProtocolException,
82
+ AbortException {
83
+ String line;
84
+ while (buffer.hasRemaining() && state != State.ALL_READ) {
85
+ switch (state) {
86
+ case READ_INITIAL:
87
+ if ((line = lineReader.readLine(buffer)) != null) {
88
+ parseInitialLine(line);
89
+ }
90
+ break;
91
+ case READ_HEADER:
92
+ readHeaders(buffer);
93
+ break;
94
+ case READ_CHUNK_SIZE:
95
+ line = lineReader.readLine(buffer);
96
+ if (line != null && !line.isEmpty()) {
97
+ readRemaining = getChunkSize(line);
98
+ if (readRemaining == 0) {
99
+ state = READ_CHUNK_FOOTER;
100
+ } else {
101
+ state = READ_CHUNKED_CONTENT;
102
+ }
103
+ }
104
+ break;
105
+ case READ_FIXED_LENGTH_CONTENT:
106
+ readBody(buffer, ALL_READ);
107
+ break;
108
+ case READ_CHUNKED_CONTENT:
109
+ readBody(buffer, READ_CHUNK_DELIMITER);
110
+ break;
111
+ case READ_CHUNK_FOOTER:
112
+ readEmptyLine(buffer);
113
+ state = ALL_READ;
114
+ break;
115
+ case READ_CHUNK_DELIMITER:
116
+ readEmptyLine(buffer);
117
+ state = READ_CHUNK_SIZE;
118
+ break;
119
+ case READ_VARIABLE_LENGTH_CONTENT:
120
+ readBody(buffer, null);
121
+ break;
122
+ }
123
+ }
124
+ return state;
125
+ }
126
+
127
+ private void readBody(ByteBuffer buffer, State nextState) throws AbortException {
128
+ int toRead = Math.min(buffer.remaining(), readRemaining);
129
+ byte[] bytes = new byte[toRead];
130
+ buffer.get(bytes, 0, toRead);
131
+ listener.onBodyReceived(bytes, toRead);
132
+ if (nextState != null) {
133
+ readRemaining -= toRead;
134
+ if (readRemaining == 0) {
135
+ state = nextState;
136
+ }
137
+ }
138
+ }
139
+
140
+ void readEmptyLine(ByteBuffer buffer) {
141
+ byte b = buffer.get();
142
+ if (b == CR && buffer.hasRemaining()) {
143
+ buffer.get(); // should be LF
144
+ }
145
+ }
146
+
147
+ private void readHeaders(ByteBuffer buffer) throws LineTooLargeException, AbortException {
148
+ String line = lineReader.readLine(buffer);
149
+ while (line != null && !line.isEmpty()) {
150
+ HttpUtils.splitAndAddHeader(line, headers);
151
+ line = lineReader.readLine(buffer);
152
+ }
153
+ if (line == null)
154
+ return; // data is not received enough. for next run
155
+ listener.onHeadersReceived(headers);
156
+ if (method == HttpMethod.HEAD) {
157
+ state = ALL_READ;
158
+ return;
159
+ }
160
+
161
+ String te = HttpUtils.getStringValue(headers, TRANSFER_ENCODING);
162
+ if (CHUNKED.equals(te)) {
163
+ state = READ_CHUNK_SIZE;
164
+ } else {
165
+ String cl = HttpUtils.getStringValue(headers, CONTENT_LENGTH);
166
+ if (cl != null) {
167
+ readRemaining = Integer.parseInt(cl);
168
+ if (readRemaining == 0) {
169
+ state = ALL_READ;
170
+ } else {
171
+ state = READ_FIXED_LENGTH_CONTENT;
172
+ }
173
+ } else if (emptyBodyExpected) {
174
+ state = ALL_READ;
175
+ } else {
176
+ state = READ_VARIABLE_LENGTH_CONTENT;
177
+ // for readBody min
178
+ readRemaining = Integer.MAX_VALUE;
179
+ }
180
+ }
181
+ }
182
+ }