jruby-http-kit 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +1 -0
- data/example/config.ru +9 -0
- data/example/hello_world.rb +17 -0
- data/example/rack.rb +11 -0
- data/example/ring.rb +31 -0
- data/example/sinatra/app.rb +9 -0
- data/example/sinatra/config.ru +8 -0
- data/example/webmachine/Gemfile +4 -0
- data/example/webmachine/Gemfile.lock +16 -0
- data/example/webmachine/app.rb +37 -0
- data/jruby-http-kit.gemspec +25 -0
- data/lib/http_kit/rack_handler.rb +139 -0
- data/lib/http_kit/server.rb +62 -0
- data/lib/http_kit/version.rb +3 -0
- data/lib/http_kit.rb +6 -0
- data/lib/java/clojure-1.5.1.jar +0 -0
- data/lib/java/http-kit.jar +0 -0
- data/lib/rack/handler/http_kit.rb +3 -0
- data/lib/rack/http_kit.rb +3 -0
- data/lib/webmachine/adapters/ring.rb +135 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/test_resource.rb +75 -0
- data/spec/webmachine/ring_adapter_spec.rb +127 -0
- data/src/.classpath +7 -0
- data/src/.project +17 -0
- data/src/org/httpkit/BytesInputStream.class +0 -0
- data/src/org/httpkit/BytesInputStream.java +83 -0
- data/src/org/httpkit/DateFormatter.class +0 -0
- data/src/org/httpkit/DynamicBytes.class +0 -0
- data/src/org/httpkit/DynamicBytes.java +76 -0
- data/src/org/httpkit/HTTPException.class +0 -0
- data/src/org/httpkit/HTTPException.java +10 -0
- data/src/org/httpkit/HeaderMap.class +0 -0
- data/src/org/httpkit/HeaderMap.java +98 -0
- data/src/org/httpkit/HttpMethod.class +0 -0
- data/src/org/httpkit/HttpMethod.java +28 -0
- data/src/org/httpkit/HttpStatus.class +0 -0
- data/src/org/httpkit/HttpStatus.java +416 -0
- data/src/org/httpkit/HttpUtils.class +0 -0
- data/src/org/httpkit/HttpUtils.java +484 -0
- data/src/org/httpkit/HttpVersion.class +0 -0
- data/src/org/httpkit/HttpVersion.java +5 -0
- data/src/org/httpkit/LineReader.class +0 -0
- data/src/org/httpkit/LineReader.java +52 -0
- data/src/org/httpkit/LineTooLargeException.class +0 -0
- data/src/org/httpkit/LineTooLargeException.java +13 -0
- data/src/org/httpkit/PrefixThreadFactory.class +0 -0
- data/src/org/httpkit/PrefixThreadFactory.java +20 -0
- data/src/org/httpkit/PriorityQueue.class +0 -0
- data/src/org/httpkit/PriorityQueue.java +235 -0
- data/src/org/httpkit/ProtocolException.class +0 -0
- data/src/org/httpkit/ProtocolException.java +10 -0
- data/src/org/httpkit/RequestTooLargeException.class +0 -0
- data/src/org/httpkit/RequestTooLargeException.java +10 -0
- data/src/org/httpkit/client/AbortException.class +0 -0
- data/src/org/httpkit/client/AbortException.java +13 -0
- data/src/org/httpkit/client/Decoder.class +0 -0
- data/src/org/httpkit/client/Decoder.java +182 -0
- data/src/org/httpkit/client/Handler.class +0 -0
- data/src/org/httpkit/client/HttpClient.class +0 -0
- data/src/org/httpkit/client/HttpClient.java +393 -0
- data/src/org/httpkit/client/HttpsRequest.class +0 -0
- data/src/org/httpkit/client/HttpsRequest.java +141 -0
- data/src/org/httpkit/client/IFilter$1.class +0 -0
- data/src/org/httpkit/client/IFilter$MaxBodyFilter.class +0 -0
- data/src/org/httpkit/client/IFilter.class +0 -0
- data/src/org/httpkit/client/IFilter.java +53 -0
- data/src/org/httpkit/client/IRespListener.class +0 -0
- data/src/org/httpkit/client/IRespListener.java +30 -0
- data/src/org/httpkit/client/IResponseHandler.class +0 -0
- data/src/org/httpkit/client/IResponseHandler.java +18 -0
- data/src/org/httpkit/client/PersistentConn.class +0 -0
- data/src/org/httpkit/client/PersistentConn.java +33 -0
- data/src/org/httpkit/client/Request.class +0 -0
- data/src/org/httpkit/client/Request.java +74 -0
- data/src/org/httpkit/client/RequestConfig.class +0 -0
- data/src/org/httpkit/client/RequestConfig.java +28 -0
- data/src/org/httpkit/client/RespListener.class +0 -0
- data/src/org/httpkit/client/RespListener.java +160 -0
- data/src/org/httpkit/client/SslContextFactory.class +0 -0
- data/src/org/httpkit/client/SslContextFactory.java +79 -0
- data/src/org/httpkit/client/State.class +0 -0
- data/src/org/httpkit/client/TimeoutException.class +0 -0
- data/src/org/httpkit/client/TimeoutException.java +12 -0
- data/src/org/httpkit/client/TrustManagerFactory$1.class +0 -0
- data/src/org/httpkit/client/TrustManagerFactory.class +0 -0
- data/src/org/httpkit/server/AsyncChannel.class +0 -0
- data/src/org/httpkit/server/AsyncChannel.java +286 -0
- data/src/org/httpkit/server/ClojureRing.class +0 -0
- data/src/org/httpkit/server/Frame$BinaryFrame.class +0 -0
- data/src/org/httpkit/server/Frame$CloseFrame.class +0 -0
- data/src/org/httpkit/server/Frame$PingFrame.class +0 -0
- data/src/org/httpkit/server/Frame$TextFrame.class +0 -0
- data/src/org/httpkit/server/Frame.class +0 -0
- data/src/org/httpkit/server/Frame.java +73 -0
- data/src/org/httpkit/server/HttpAtta.class +0 -0
- data/src/org/httpkit/server/HttpAtta.java +10 -0
- data/src/org/httpkit/server/HttpDecoder$State.class +0 -0
- data/src/org/httpkit/server/HttpDecoder.class +0 -0
- data/src/org/httpkit/server/HttpDecoder.java +202 -0
- data/src/org/httpkit/server/HttpHandler.class +0 -0
- data/src/org/httpkit/server/HttpRequest.class +0 -0
- data/src/org/httpkit/server/HttpRequest.java +109 -0
- data/src/org/httpkit/server/HttpServer.class +0 -0
- data/src/org/httpkit/server/HttpServer.java +281 -0
- data/src/org/httpkit/server/IHandler.class +0 -0
- data/src/org/httpkit/server/IHandler.java +12 -0
- data/src/org/httpkit/server/LinkingRunnable.class +0 -0
- data/src/org/httpkit/server/Rack.class +0 -0
- data/src/org/httpkit/server/RackApplication.class +0 -0
- data/src/org/httpkit/server/RackApplication.java +10 -0
- data/src/org/httpkit/server/RackHandler$1.class +0 -0
- data/src/org/httpkit/server/RackHandler.class +0 -0
- data/src/org/httpkit/server/RackHandler.java +259 -0
- data/src/org/httpkit/server/RackHttpHandler.class +0 -0
- data/src/org/httpkit/server/RackHttpHandler.java +20 -0
- data/src/org/httpkit/server/RespCallback.class +0 -0
- data/src/org/httpkit/server/RespCallback.java +19 -0
- data/src/org/httpkit/server/RingHandler$1.class +0 -0
- data/src/org/httpkit/server/RingHandler.class +0 -0
- data/src/org/httpkit/server/RingHandler.java +222 -0
- data/src/org/httpkit/server/ServerAtta.class +0 -0
- data/src/org/httpkit/server/ServerAtta.java +22 -0
- data/src/org/httpkit/server/WSDecoder$State.class +0 -0
- data/src/org/httpkit/server/WSDecoder.class +0 -0
- data/src/org/httpkit/server/WSDecoder.java +181 -0
- data/src/org/httpkit/server/WSHandler.class +0 -0
- data/src/org/httpkit/server/WsAtta.class +0 -0
- data/src/org/httpkit/server/WsAtta.java +11 -0
- data/src/org/httpkit/timer/CancelableFutureTask.class +0 -0
- data/src/org/httpkit/timer/CancelableFutureTask.java +52 -0
- data/src/org/httpkit/timer/TimerService.class +0 -0
- data/src/org/httpkit/timer/TimerService.java +89 -0
- metadata +241 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
package org.httpkit.server;
|
|
2
|
+
|
|
3
|
+
import org.httpkit.ProtocolException;
|
|
4
|
+
|
|
5
|
+
import java.nio.ByteBuffer;
|
|
6
|
+
import java.util.Arrays;
|
|
7
|
+
|
|
8
|
+
public class WSDecoder {
|
|
9
|
+
|
|
10
|
+
public static final byte OPCODE_CONT = 0x0;
|
|
11
|
+
public static final byte OPCODE_TEXT = 0x1;
|
|
12
|
+
public static final byte OPCODE_BINARY = 0x2;
|
|
13
|
+
public static final byte OPCODE_CLOSE = 0x8;
|
|
14
|
+
public static final byte OPCODE_PING = 0x9;
|
|
15
|
+
public static final byte OPCODE_PONG = 0xA;
|
|
16
|
+
|
|
17
|
+
public enum State {
|
|
18
|
+
FRAME_START, READ_LENGTH, READ_2_LENGTH, READ_8_LENGTH, MASKING_KEY, PAYLOAD, CORRUPT
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private State state = State.FRAME_START;
|
|
22
|
+
private byte[] content;
|
|
23
|
+
private int idx = 0;
|
|
24
|
+
|
|
25
|
+
private int payloadLength;
|
|
26
|
+
private int payloadRead;
|
|
27
|
+
private int maskingKey;
|
|
28
|
+
private boolean finalFlag;
|
|
29
|
+
private int opcode = -1;
|
|
30
|
+
private int framePayloadIndex; // masking per frame
|
|
31
|
+
|
|
32
|
+
// 8 bytes are enough
|
|
33
|
+
// protect against long/short/int are not fully received
|
|
34
|
+
private ByteBuffer tmpBuffer = ByteBuffer.allocate(8);
|
|
35
|
+
|
|
36
|
+
private boolean isAvailable(ByteBuffer src, int length) {
|
|
37
|
+
while (tmpBuffer.position() < length) {
|
|
38
|
+
if (src.hasRemaining()) {
|
|
39
|
+
tmpBuffer.put(src.get());
|
|
40
|
+
} else {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
tmpBuffer.flip(); // for read
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public Frame decode(ByteBuffer buffer) throws ProtocolException {
|
|
49
|
+
while (buffer.hasRemaining()) {
|
|
50
|
+
switch (state) {
|
|
51
|
+
case FRAME_START:
|
|
52
|
+
byte b = buffer.get(); // FIN, RSV, OPCODE
|
|
53
|
+
finalFlag = (b & 0x80) != 0;
|
|
54
|
+
|
|
55
|
+
int tmpOp = b & 0x0F;
|
|
56
|
+
if (opcode != -1 && tmpOp != opcode) {
|
|
57
|
+
// TODO ping frame in fragmented text frame
|
|
58
|
+
throw new ProtocolException("opcode mismatch: pre: " + opcode + ", now: "
|
|
59
|
+
+ tmpOp);
|
|
60
|
+
}
|
|
61
|
+
opcode = tmpOp;
|
|
62
|
+
state = State.READ_LENGTH;
|
|
63
|
+
break;
|
|
64
|
+
case READ_LENGTH:
|
|
65
|
+
b = buffer.get(); // MASK, PAYLOAD LEN 1
|
|
66
|
+
boolean masked = (b & 0x80) != 0;
|
|
67
|
+
if (!masked) {
|
|
68
|
+
throw new ProtocolException("unmasked client to server frame");
|
|
69
|
+
}
|
|
70
|
+
payloadLength = b & 0x7F;
|
|
71
|
+
if (payloadLength == 126) {
|
|
72
|
+
state = State.READ_2_LENGTH;
|
|
73
|
+
} else if (payloadLength == 127) {
|
|
74
|
+
state = State.READ_8_LENGTH;
|
|
75
|
+
} else {
|
|
76
|
+
state = State.MASKING_KEY;
|
|
77
|
+
}
|
|
78
|
+
break;
|
|
79
|
+
case READ_2_LENGTH:
|
|
80
|
+
if (isAvailable(buffer, 2)) {
|
|
81
|
+
payloadLength = tmpBuffer.getShort() & 0xFFFF;
|
|
82
|
+
tmpBuffer.clear();
|
|
83
|
+
if (payloadLength < 126) {
|
|
84
|
+
throw new ProtocolException(
|
|
85
|
+
"invalid data frame length (not using minimal length encoding)");
|
|
86
|
+
}
|
|
87
|
+
state = State.MASKING_KEY;
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
case READ_8_LENGTH:
|
|
91
|
+
if (isAvailable(buffer, 8)) {
|
|
92
|
+
long length = tmpBuffer.getLong();
|
|
93
|
+
tmpBuffer.clear();
|
|
94
|
+
// if negative, that too big, drop it.
|
|
95
|
+
if (length < 65536) {
|
|
96
|
+
throw new ProtocolException("invalid data frame length. max payload length 4M");
|
|
97
|
+
}
|
|
98
|
+
abortIfTooLarge(length);
|
|
99
|
+
payloadLength = (int) length;
|
|
100
|
+
state = State.MASKING_KEY;
|
|
101
|
+
}
|
|
102
|
+
break; // wait for more data from TCP
|
|
103
|
+
case MASKING_KEY:
|
|
104
|
+
if (isAvailable(buffer, 4)) {
|
|
105
|
+
maskingKey = tmpBuffer.getInt();
|
|
106
|
+
tmpBuffer.clear();
|
|
107
|
+
if (content == null) {
|
|
108
|
+
content = new byte[payloadLength];
|
|
109
|
+
} else if (payloadLength > 0) {
|
|
110
|
+
abortIfTooLarge(content.length + payloadLength);
|
|
111
|
+
/*
|
|
112
|
+
* TODO if an attacker sent many fragmented frames, only one
|
|
113
|
+
* byte of data per frame, server end up reallocate many
|
|
114
|
+
* times. may not be a problem
|
|
115
|
+
*/
|
|
116
|
+
// resize
|
|
117
|
+
content = Arrays.copyOf(content, content.length + payloadLength);
|
|
118
|
+
}
|
|
119
|
+
framePayloadIndex = 0; // reset
|
|
120
|
+
state = State.PAYLOAD;
|
|
121
|
+
// No break. since payloadLength can be 0
|
|
122
|
+
} else {
|
|
123
|
+
break; // wait for more data from TCP
|
|
124
|
+
}
|
|
125
|
+
case PAYLOAD:
|
|
126
|
+
int read = Math.min(buffer.remaining(), payloadLength - payloadRead);
|
|
127
|
+
if (read > 0) {
|
|
128
|
+
buffer.get(content, idx, read);
|
|
129
|
+
|
|
130
|
+
byte[] mask = ByteBuffer.allocate(4).putInt(maskingKey).array();
|
|
131
|
+
for (int i = 0; i < read; i++) {
|
|
132
|
+
content[i + idx] = (byte) (content[i + idx] ^ mask[(framePayloadIndex + i) % 4]);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
payloadRead += read;
|
|
136
|
+
idx += read;
|
|
137
|
+
}
|
|
138
|
+
framePayloadIndex += read;
|
|
139
|
+
|
|
140
|
+
// all read (this frame)
|
|
141
|
+
if (payloadRead == payloadLength) {
|
|
142
|
+
if (finalFlag) {
|
|
143
|
+
switch (opcode) {
|
|
144
|
+
case OPCODE_TEXT:
|
|
145
|
+
return new Frame.TextFrame(content);
|
|
146
|
+
case OPCODE_BINARY:
|
|
147
|
+
return new Frame.BinaryFrame(content);
|
|
148
|
+
case OPCODE_PING:
|
|
149
|
+
return new Frame.PingFrame(content);
|
|
150
|
+
case OPCODE_CLOSE:
|
|
151
|
+
return new Frame.CloseFrame(content);
|
|
152
|
+
default:
|
|
153
|
+
throw new ProtocolException("not impl for opcode: " + opcode);
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
state = State.FRAME_START;
|
|
157
|
+
payloadRead = 0;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return null; // wait for more bytes
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
public void abortIfTooLarge(long length) throws ProtocolException {
|
|
167
|
+
// TODO configurable
|
|
168
|
+
if (length > 1024 * 1024 * 4) { // 4M, drop if message is too big
|
|
169
|
+
throw new ProtocolException("Max payload length 4m, get: " + length);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public void reset() {
|
|
174
|
+
state = State.FRAME_START;
|
|
175
|
+
payloadRead = 0;
|
|
176
|
+
idx = 0;
|
|
177
|
+
opcode = -1;
|
|
178
|
+
content = null;
|
|
179
|
+
framePayloadIndex = 0;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
package org.httpkit.timer;
|
|
2
|
+
|
|
3
|
+
import clojure.lang.IFn;
|
|
4
|
+
import org.httpkit.PriorityQueue;
|
|
5
|
+
|
|
6
|
+
import java.util.concurrent.atomic.AtomicBoolean;
|
|
7
|
+
|
|
8
|
+
public class CancelableFutureTask implements Comparable<CancelableFutureTask> {
|
|
9
|
+
|
|
10
|
+
private final int timeout;
|
|
11
|
+
private final IFn futureTask;
|
|
12
|
+
public final long timeoutTs;
|
|
13
|
+
|
|
14
|
+
private final AtomicBoolean done = new AtomicBoolean(false);
|
|
15
|
+
private final PriorityQueue<CancelableFutureTask> queue;
|
|
16
|
+
|
|
17
|
+
public CancelableFutureTask(int timeout, IFn task, PriorityQueue<CancelableFutureTask> queue) {
|
|
18
|
+
this.timeoutTs = System.currentTimeMillis() + timeout;
|
|
19
|
+
this.timeout = timeout;
|
|
20
|
+
this.futureTask = task;
|
|
21
|
+
this.queue = queue;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public String toString() {
|
|
25
|
+
long now = System.currentTimeMillis();
|
|
26
|
+
if (done.get()) {
|
|
27
|
+
return "timeout=" + timeout + "ms, done or canceled";
|
|
28
|
+
} else {
|
|
29
|
+
return "timeout=" + timeout + "ms, due in " + (timeoutTs - now) + "ms";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public void runTask() {
|
|
34
|
+
if (done.compareAndSet(false, true)) {
|
|
35
|
+
futureTask.invoke();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public boolean cancel() {
|
|
40
|
+
boolean b = done.compareAndSet(false, true);
|
|
41
|
+
if (b) {// ok, not done
|
|
42
|
+
synchronized (queue) {
|
|
43
|
+
queue.remove(this);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return b;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public int compareTo(CancelableFutureTask o) {
|
|
50
|
+
return (int) (timeoutTs - o.timeoutTs);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
package org.httpkit.timer;
|
|
2
|
+
|
|
3
|
+
import clojure.lang.IFn;
|
|
4
|
+
import org.httpkit.HttpUtils;
|
|
5
|
+
import org.httpkit.PriorityQueue;
|
|
6
|
+
|
|
7
|
+
import java.util.concurrent.atomic.AtomicBoolean;
|
|
8
|
+
|
|
9
|
+
public class TimerService implements Runnable {
|
|
10
|
+
|
|
11
|
+
private final PriorityQueue<CancelableFutureTask> queue = new PriorityQueue<CancelableFutureTask>();
|
|
12
|
+
private final AtomicBoolean started = new AtomicBoolean(false);
|
|
13
|
+
|
|
14
|
+
public CancelableFutureTask scheduleTask(int timeout, IFn task) {
|
|
15
|
+
// start the timer thread, if not started
|
|
16
|
+
if (started.compareAndSet(false, true)) {
|
|
17
|
+
// the timer thread will kill itself when no job to schedule for too
|
|
18
|
+
// much time. restart if new job come it
|
|
19
|
+
Thread t = new Thread(this, "timer-service");
|
|
20
|
+
t.start();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
CancelableFutureTask t = new CancelableFutureTask(timeout, task, queue);
|
|
24
|
+
synchronized (queue) {
|
|
25
|
+
queue.offer(t);
|
|
26
|
+
queue.notify();
|
|
27
|
+
}
|
|
28
|
+
return t;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public static final TimerService SERVICE = new TimerService();
|
|
32
|
+
|
|
33
|
+
@Override
|
|
34
|
+
public String toString() {
|
|
35
|
+
return "pending=" + queue.size() + ", thread started:" + started.get();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public void run() {
|
|
39
|
+
// if 2 checks of the queue, find it empty, stop self
|
|
40
|
+
boolean emptyQueueWaited = false;
|
|
41
|
+
CancelableFutureTask task;
|
|
42
|
+
while (true) {
|
|
43
|
+
synchronized (queue) {
|
|
44
|
+
task = queue.peek();
|
|
45
|
+
}
|
|
46
|
+
if (task == null) {
|
|
47
|
+
synchronized (queue) {
|
|
48
|
+
try {
|
|
49
|
+
// wait 2 minute before kill self
|
|
50
|
+
queue.wait(1000 * 120);
|
|
51
|
+
if (emptyQueueWaited) {
|
|
52
|
+
started.compareAndSet(true, false);
|
|
53
|
+
break; // die, will restart
|
|
54
|
+
} else {
|
|
55
|
+
emptyQueueWaited = true; // queue is empty
|
|
56
|
+
}
|
|
57
|
+
} catch (InterruptedException ignore) {
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
emptyQueueWaited = false;
|
|
62
|
+
long due = task.timeoutTs - System.currentTimeMillis();
|
|
63
|
+
// schedule to run in 1000ms, maybe run in 1000ms, 1001ms, ...
|
|
64
|
+
if (due <= 0) {
|
|
65
|
+
try {
|
|
66
|
+
task.runTask();
|
|
67
|
+
} catch (Exception e) {
|
|
68
|
+
HttpUtils.printError("In timer: " + task, e);
|
|
69
|
+
}
|
|
70
|
+
synchronized (queue) { // remove
|
|
71
|
+
if (task == queue.peek()) {
|
|
72
|
+
queue.poll(); // much faster
|
|
73
|
+
} else {
|
|
74
|
+
queue.remove(task);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
synchronized (queue) {
|
|
79
|
+
try {
|
|
80
|
+
queue.wait(due); // others may notify you
|
|
81
|
+
} catch (InterruptedException ignore) {
|
|
82
|
+
// maybe more urgent job come in
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
metadata
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: jruby-http-kit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Dmitriy Rozhkov
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2013-09-14 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ~>
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.3'
|
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
|
21
|
+
requirements:
|
|
22
|
+
- - ~>
|
|
23
|
+
- !ruby/object:Gem::Version
|
|
24
|
+
version: '1.3'
|
|
25
|
+
prerelease: false
|
|
26
|
+
type: :development
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - '>='
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0'
|
|
39
|
+
prerelease: false
|
|
40
|
+
type: :development
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - '>='
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - '>='
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '0'
|
|
53
|
+
prerelease: false
|
|
54
|
+
type: :development
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: webmachine
|
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - '>='
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '0'
|
|
67
|
+
prerelease: false
|
|
68
|
+
type: :development
|
|
69
|
+
description: ''
|
|
70
|
+
email:
|
|
71
|
+
- rojkov.dmitry@gmail.com
|
|
72
|
+
executables: []
|
|
73
|
+
extensions: []
|
|
74
|
+
extra_rdoc_files: []
|
|
75
|
+
files:
|
|
76
|
+
- .gitignore
|
|
77
|
+
- .rspec
|
|
78
|
+
- Gemfile
|
|
79
|
+
- LICENSE.txt
|
|
80
|
+
- README.md
|
|
81
|
+
- Rakefile
|
|
82
|
+
- example/config.ru
|
|
83
|
+
- example/hello_world.rb
|
|
84
|
+
- example/rack.rb
|
|
85
|
+
- example/ring.rb
|
|
86
|
+
- example/sinatra/app.rb
|
|
87
|
+
- example/sinatra/config.ru
|
|
88
|
+
- example/webmachine/Gemfile
|
|
89
|
+
- example/webmachine/Gemfile.lock
|
|
90
|
+
- example/webmachine/app.rb
|
|
91
|
+
- jruby-http-kit.gemspec
|
|
92
|
+
- lib/http_kit.rb
|
|
93
|
+
- lib/http_kit/rack_handler.rb
|
|
94
|
+
- lib/http_kit/server.rb
|
|
95
|
+
- lib/http_kit/version.rb
|
|
96
|
+
- lib/java/clojure-1.5.1.jar
|
|
97
|
+
- lib/java/http-kit.jar
|
|
98
|
+
- lib/rack/handler/http_kit.rb
|
|
99
|
+
- lib/rack/http_kit.rb
|
|
100
|
+
- lib/webmachine/adapters/ring.rb
|
|
101
|
+
- spec/spec_helper.rb
|
|
102
|
+
- spec/support/test_resource.rb
|
|
103
|
+
- spec/webmachine/ring_adapter_spec.rb
|
|
104
|
+
- src/.classpath
|
|
105
|
+
- src/.project
|
|
106
|
+
- src/org/httpkit/BytesInputStream.class
|
|
107
|
+
- src/org/httpkit/BytesInputStream.java
|
|
108
|
+
- src/org/httpkit/DateFormatter.class
|
|
109
|
+
- src/org/httpkit/DynamicBytes.class
|
|
110
|
+
- src/org/httpkit/DynamicBytes.java
|
|
111
|
+
- src/org/httpkit/HTTPException.class
|
|
112
|
+
- src/org/httpkit/HTTPException.java
|
|
113
|
+
- src/org/httpkit/HeaderMap.class
|
|
114
|
+
- src/org/httpkit/HeaderMap.java
|
|
115
|
+
- src/org/httpkit/HttpMethod.class
|
|
116
|
+
- src/org/httpkit/HttpMethod.java
|
|
117
|
+
- src/org/httpkit/HttpStatus.class
|
|
118
|
+
- src/org/httpkit/HttpStatus.java
|
|
119
|
+
- src/org/httpkit/HttpUtils.class
|
|
120
|
+
- src/org/httpkit/HttpUtils.java
|
|
121
|
+
- src/org/httpkit/HttpVersion.class
|
|
122
|
+
- src/org/httpkit/HttpVersion.java
|
|
123
|
+
- src/org/httpkit/LineReader.class
|
|
124
|
+
- src/org/httpkit/LineReader.java
|
|
125
|
+
- src/org/httpkit/LineTooLargeException.class
|
|
126
|
+
- src/org/httpkit/LineTooLargeException.java
|
|
127
|
+
- src/org/httpkit/PrefixThreadFactory.class
|
|
128
|
+
- src/org/httpkit/PrefixThreadFactory.java
|
|
129
|
+
- src/org/httpkit/PriorityQueue.class
|
|
130
|
+
- src/org/httpkit/PriorityQueue.java
|
|
131
|
+
- src/org/httpkit/ProtocolException.class
|
|
132
|
+
- src/org/httpkit/ProtocolException.java
|
|
133
|
+
- src/org/httpkit/RequestTooLargeException.class
|
|
134
|
+
- src/org/httpkit/RequestTooLargeException.java
|
|
135
|
+
- src/org/httpkit/client/AbortException.class
|
|
136
|
+
- src/org/httpkit/client/AbortException.java
|
|
137
|
+
- src/org/httpkit/client/Decoder.class
|
|
138
|
+
- src/org/httpkit/client/Decoder.java
|
|
139
|
+
- src/org/httpkit/client/Handler.class
|
|
140
|
+
- src/org/httpkit/client/HttpClient.class
|
|
141
|
+
- src/org/httpkit/client/HttpClient.java
|
|
142
|
+
- src/org/httpkit/client/HttpsRequest.class
|
|
143
|
+
- src/org/httpkit/client/HttpsRequest.java
|
|
144
|
+
- src/org/httpkit/client/IFilter$1.class
|
|
145
|
+
- src/org/httpkit/client/IFilter$MaxBodyFilter.class
|
|
146
|
+
- src/org/httpkit/client/IFilter.class
|
|
147
|
+
- src/org/httpkit/client/IFilter.java
|
|
148
|
+
- src/org/httpkit/client/IRespListener.class
|
|
149
|
+
- src/org/httpkit/client/IRespListener.java
|
|
150
|
+
- src/org/httpkit/client/IResponseHandler.class
|
|
151
|
+
- src/org/httpkit/client/IResponseHandler.java
|
|
152
|
+
- src/org/httpkit/client/PersistentConn.class
|
|
153
|
+
- src/org/httpkit/client/PersistentConn.java
|
|
154
|
+
- src/org/httpkit/client/Request.class
|
|
155
|
+
- src/org/httpkit/client/Request.java
|
|
156
|
+
- src/org/httpkit/client/RequestConfig.class
|
|
157
|
+
- src/org/httpkit/client/RequestConfig.java
|
|
158
|
+
- src/org/httpkit/client/RespListener.class
|
|
159
|
+
- src/org/httpkit/client/RespListener.java
|
|
160
|
+
- src/org/httpkit/client/SslContextFactory.class
|
|
161
|
+
- src/org/httpkit/client/SslContextFactory.java
|
|
162
|
+
- src/org/httpkit/client/State.class
|
|
163
|
+
- src/org/httpkit/client/TimeoutException.class
|
|
164
|
+
- src/org/httpkit/client/TimeoutException.java
|
|
165
|
+
- src/org/httpkit/client/TrustManagerFactory$1.class
|
|
166
|
+
- src/org/httpkit/client/TrustManagerFactory.class
|
|
167
|
+
- src/org/httpkit/server/AsyncChannel.class
|
|
168
|
+
- src/org/httpkit/server/AsyncChannel.java
|
|
169
|
+
- src/org/httpkit/server/ClojureRing.class
|
|
170
|
+
- src/org/httpkit/server/Frame$BinaryFrame.class
|
|
171
|
+
- src/org/httpkit/server/Frame$CloseFrame.class
|
|
172
|
+
- src/org/httpkit/server/Frame$PingFrame.class
|
|
173
|
+
- src/org/httpkit/server/Frame$TextFrame.class
|
|
174
|
+
- src/org/httpkit/server/Frame.class
|
|
175
|
+
- src/org/httpkit/server/Frame.java
|
|
176
|
+
- src/org/httpkit/server/HttpAtta.class
|
|
177
|
+
- src/org/httpkit/server/HttpAtta.java
|
|
178
|
+
- src/org/httpkit/server/HttpDecoder$State.class
|
|
179
|
+
- src/org/httpkit/server/HttpDecoder.class
|
|
180
|
+
- src/org/httpkit/server/HttpDecoder.java
|
|
181
|
+
- src/org/httpkit/server/HttpHandler.class
|
|
182
|
+
- src/org/httpkit/server/HttpRequest.class
|
|
183
|
+
- src/org/httpkit/server/HttpRequest.java
|
|
184
|
+
- src/org/httpkit/server/HttpServer.class
|
|
185
|
+
- src/org/httpkit/server/HttpServer.java
|
|
186
|
+
- src/org/httpkit/server/IHandler.class
|
|
187
|
+
- src/org/httpkit/server/IHandler.java
|
|
188
|
+
- src/org/httpkit/server/LinkingRunnable.class
|
|
189
|
+
- src/org/httpkit/server/Rack.class
|
|
190
|
+
- src/org/httpkit/server/RackApplication.class
|
|
191
|
+
- src/org/httpkit/server/RackApplication.java
|
|
192
|
+
- src/org/httpkit/server/RackHandler$1.class
|
|
193
|
+
- src/org/httpkit/server/RackHandler.class
|
|
194
|
+
- src/org/httpkit/server/RackHandler.java
|
|
195
|
+
- src/org/httpkit/server/RackHttpHandler.class
|
|
196
|
+
- src/org/httpkit/server/RackHttpHandler.java
|
|
197
|
+
- src/org/httpkit/server/RespCallback.class
|
|
198
|
+
- src/org/httpkit/server/RespCallback.java
|
|
199
|
+
- src/org/httpkit/server/RingHandler$1.class
|
|
200
|
+
- src/org/httpkit/server/RingHandler.class
|
|
201
|
+
- src/org/httpkit/server/RingHandler.java
|
|
202
|
+
- src/org/httpkit/server/ServerAtta.class
|
|
203
|
+
- src/org/httpkit/server/ServerAtta.java
|
|
204
|
+
- src/org/httpkit/server/WSDecoder$State.class
|
|
205
|
+
- src/org/httpkit/server/WSDecoder.class
|
|
206
|
+
- src/org/httpkit/server/WSDecoder.java
|
|
207
|
+
- src/org/httpkit/server/WSHandler.class
|
|
208
|
+
- src/org/httpkit/server/WsAtta.class
|
|
209
|
+
- src/org/httpkit/server/WsAtta.java
|
|
210
|
+
- src/org/httpkit/timer/CancelableFutureTask.class
|
|
211
|
+
- src/org/httpkit/timer/CancelableFutureTask.java
|
|
212
|
+
- src/org/httpkit/timer/TimerService.class
|
|
213
|
+
- src/org/httpkit/timer/TimerService.java
|
|
214
|
+
homepage: https://github.com/nLight/jruby-http-kit
|
|
215
|
+
licenses:
|
|
216
|
+
- ''
|
|
217
|
+
metadata: {}
|
|
218
|
+
post_install_message:
|
|
219
|
+
rdoc_options: []
|
|
220
|
+
require_paths:
|
|
221
|
+
- lib
|
|
222
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
223
|
+
requirements:
|
|
224
|
+
- - '>='
|
|
225
|
+
- !ruby/object:Gem::Version
|
|
226
|
+
version: '0'
|
|
227
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
228
|
+
requirements:
|
|
229
|
+
- - '>='
|
|
230
|
+
- !ruby/object:Gem::Version
|
|
231
|
+
version: '0'
|
|
232
|
+
requirements: []
|
|
233
|
+
rubyforge_project:
|
|
234
|
+
rubygems_version: 2.1.0
|
|
235
|
+
signing_key:
|
|
236
|
+
specification_version: 4
|
|
237
|
+
summary: JRuby wrapper for Clojure HTTP Kit library.
|
|
238
|
+
test_files:
|
|
239
|
+
- spec/spec_helper.rb
|
|
240
|
+
- spec/support/test_resource.rb
|
|
241
|
+
- spec/webmachine/ring_adapter_spec.rb
|