Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jetty-spdy')
-rw-r--r--jetty-spdy/pom.xml88
-rw-r--r--jetty-spdy/spdy-alpn-tests/pom.xml93
-rw-r--r--jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/ALPNNegotiationTest.java198
-rw-r--r--jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/ALPNSynReplyTest.java149
-rw-r--r--jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractALPNTest.java78
-rw-r--r--jetty-spdy/spdy-alpn-tests/src/test/resources/jetty-logging.properties2
-rw-r--r--jetty-spdy/spdy-alpn-tests/src/test/resources/keystore.jksbin2206 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-alpn-tests/src/test/resources/truststore.jksbin916 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-client/pom.xml66
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/FlowControlStrategyFactory.java43
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnection.java82
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnectionFactory.java50
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java440
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClientConnectionFactory.java98
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYConnection.java191
-rw-r--r--jetty-spdy/spdy-core/pom.xml35
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/CompressionDictionary.java87
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/CompressionFactory.java46
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Controller.java30
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/FlowControlStrategy.java92
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Flusher.java266
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java39
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IStream.java120
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IdleListener.java24
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/PushSynInfo.java60
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/SPDYv3FlowControlStrategy.java90
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/SessionException.java48
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardCompressionFactory.java92
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java1303
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java602
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StreamException.java50
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/ByteBufferDataInfo.java90
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/BytesDataInfo.java83
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/DataInfo.java264
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/GoAwayInfo.java38
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/GoAwayResultInfo.java57
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/HeadersInfo.java135
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Info.java52
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PingInfo.java38
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PingResultInfo.java44
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PushInfo.java101
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/ReplyInfo.java107
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/RstInfo.java78
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SPDY.java39
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SPDYException.java50
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Session.java261
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionFrameListener.java163
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionStatus.java68
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Settings.java228
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SettingsInfo.java61
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Stream.java237
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StreamFrameListener.java110
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StreamStatus.java128
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StringDataInfo.java38
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SynInfo.java128
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/server/ServerSessionFrameListener.java50
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/ControlFrame.java56
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/ControlFrameType.java59
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/CredentialFrame.java51
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/DataFrame.java63
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/GoAwayFrame.java51
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/HeadersFrame.java61
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/NoOpFrame.java29
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/PingFrame.java41
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/RstStreamFrame.java51
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SettingsFrame.java49
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SynReplyFrame.java56
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SynStreamFrame.java83
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/WindowUpdateFrame.java48
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/ControlFrameGenerator.java51
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/CredentialGenerator.java87
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/DataFrameGenerator.java57
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/Generator.java63
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/GoAwayGenerator.java67
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/HeadersBlockGenerator.java150
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/HeadersGenerator.java76
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/NoOpGenerator.java49
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/PingGenerator.java51
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/RstStreamGenerator.java52
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SettingsGenerator.java91
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SynReplyGenerator.java104
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SynStreamGenerator.java94
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/WindowUpdateGenerator.java52
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/ControlFrameBodyParser.java26
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/ControlFrameParser.java213
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/CredentialBodyParser.java274
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/DataFrameParser.java155
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/GoAwayBodyParser.java159
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/HeadersBlockParser.java230
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/HeadersBodyParser.java173
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/NoOpBodyParser.java41
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/Parser.java240
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/PingBodyParser.java98
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/RstStreamBodyParser.java127
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SettingsBodyParser.java200
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SynReplyBodyParser.java184
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SynStreamBodyParser.java236
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/UnknownControlFrameBodyParser.java72
-rw-r--r--jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/WindowUpdateBodyParser.java127
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java159
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java681
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardStreamTest.java258
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/api/ClientUsageTest.java260
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/api/ServerUsageTest.java121
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/CredentialGenerateParseTest.java104
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/DataGenerateParseTest.java144
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/GoAwayGenerateParseTest.java85
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/HeadersGenerateParseTest.java103
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/NoOpGenerateParseTest.java74
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/PingGenerateParseTest.java81
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/RstStreamGenerateParseTest.java92
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SettingsGenerateParseTest.java89
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SynReplyGenerateParseTest.java91
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SynStreamGenerateParseTest.java105
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/TestSPDYParserListener.java70
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/WindowUpdateGenerateParseTest.java85
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/generator/DataFrameGeneratorTest.java110
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/BrokenFrameTest.java287
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/LiveChromiumRequestParserTest.java100
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/ParseVersusCacheBenchmarkTest.java90
-rw-r--r--jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/UnknownControlFrameTest.java82
-rw-r--r--jetty-spdy/spdy-core/src/test/resources/jetty-logging.properties2
-rw-r--r--jetty-spdy/spdy-core/src/test/resources/keystore.jksbin2206 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-core/src/test/resources/truststore.jksbin916 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-example-webapp/pom.xml84
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/config/example-jetty-spdy-proxy.xml147
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/config/example-jetty-spdy.xml138
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/resources/jetty-logging.properties2
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/resources/keystore.jksbin2206 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/resources/truststore.jksbin916 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/webapp/WEB-INF/web.xml6
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/webapp/form.jsp3
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/webapp/included.jsp3
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/webapp/index.jsp37
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/webapp/logo.jpgbin5748 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-example-webapp/src/main/webapp/stylesheet.css9
-rw-r--r--jetty-spdy/spdy-http-client-transport/pom.xml71
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpChannelOverSPDY.java78
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpClientTransportOverSPDY.java107
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpConnectionOverSPDY.java82
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpDestinationOverSPDY.java38
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpReceiverOverSPDY.java152
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpSenderOverSPDY.java118
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/AbstractHttpClientServerTest.java107
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/EmptyServerHandler.java37
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/HttpClientCustomProxyTest.java262
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/HttpClientTest.java467
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/test/resources/jetty-logging.properties4
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/test/resources/keystore.jksbin2206 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-http-client-transport/src/test/resources/truststore.jksbin916 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-http-common/pom.xml48
-rw-r--r--jetty-spdy/spdy-http-common/src/main/java/org/eclipse/jetty/spdy/http/HTTPSPDYHeader.java82
-rw-r--r--jetty-spdy/spdy-http-server/pom.xml120
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/etc/jetty-spdy-proxy.xml158
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/etc/jetty-spdy.xml139
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/etc/protonego-npn.xml21
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_04.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_05.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_06.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_07.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_09.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_10.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_11.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_13.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_15.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_17.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_21.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_25.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_40.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_45.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_51.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_55.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_60.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_65.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_67.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_71.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_72.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_75.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_76.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_79.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_80.mod8
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod37
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/spdy.mod26
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HTTPSPDYServerConnectionFactory.java167
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HTTPSPDYServerConnector.java82
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java246
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpInputOverSPDY.java49
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java423
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/PushStrategy.java55
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategy.java342
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPProxyEngine.java276
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPSPDYProxyServerConnector.java63
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyEngine.java129
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyEngineSelector.java203
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPConnectionFactory.java57
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPSPDYConnection.java385
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/SPDYProxyEngine.java631
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/AbstractHTTPSPDYTest.java136
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ConcurrentStreamsTest.java128
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDYTest.java288
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/PushStrategyBenchmarkTest.java397
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyTest.java1138
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyUnitTest.java149
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SPDYTestUtils.java51
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SSLExternalServerTest.java108
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ServerHTTPSPDYTest.java1625
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SimpleHTTPBenchmarkTest.java160
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPToSPDYTest.java408
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPLoadTest.java319
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPTest.java545
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYLoadTest.java275
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYTest.java553
-rw-r--r--jetty-spdy/spdy-http-server/src/test/resources/big_script.js791
-rw-r--r--jetty-spdy/spdy-http-server/src/test/resources/jetty-logging.properties10
-rw-r--r--jetty-spdy/spdy-http-server/src/test/resources/keystore.jksbin2206 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-http-server/src/test/resources/truststore.jksbin916 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-npn-tests/pom.xml93
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractNPNTest.java77
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNModuleTest.java193
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNNegotiationTest.java207
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLEngineLeakTest.java71
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLSynReplyTest.java150
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPLoadTest.java29
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPTest.java27
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYLoadTest.java27
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYTest.java27
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/resources/jetty-logging.properties2
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/resources/keystore.jksbin2206 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/resources/truststore.jksbin916 -> 0 bytes
-rw-r--r--jetty-spdy/spdy-server/pom.xml72
-rw-r--r--jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnection.java68
-rw-r--r--jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java61
-rw-r--r--jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnectionFactory.java245
-rw-r--r--jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnector.java52
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/AbstractTest.java150
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ClosedStreamTest.java273
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/FlowControlTest.java493
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/GoAwayTest.java234
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/HeadersTest.java86
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/IdleTimeoutTest.java257
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/MaxConcurrentStreamTest.java121
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/PingTest.java106
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ProtocolViolationsTest.java185
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/PushStreamTest.java591
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ResetStreamTest.java204
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SPDYClientFactoryTest.java75
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SPDYServerConnectorTest.java70
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SettingsTest.java168
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SynDataReplyDataLoadTest.java288
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SynReplyTest.java375
-rw-r--r--jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/UnsupportedVersionTest.java100
-rw-r--r--jetty-spdy/spdy-server/src/test/resources/jetty-logging.properties2
252 files changed, 0 insertions, 32931 deletions
diff --git a/jetty-spdy/pom.xml b/jetty-spdy/pom.xml
deleted file mode 100644
index 7b5466489c..0000000000
--- a/jetty-spdy/pom.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-project</artifactId>
- <version>9.2.15-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-parent</artifactId>
- <packaging>pom</packaging>
- <name>Jetty :: SPDY :: Parent</name>
- <url>http://www.eclipse.org/jetty</url>
-
- <modules>
- <module>spdy-core</module>
- <module>spdy-client</module>
- <module>spdy-server</module>
- <module>spdy-http-common</module>
- <module>spdy-http-server</module>
- <module>spdy-http-client-transport</module>
- <module>spdy-example-webapp</module>
- <module>spdy-alpn-tests</module>
- </modules>
-
- <profiles>
- <profile>
- <id>npn</id>
- <activation>
- <jdk>1.7</jdk>
- </activation>
- <modules>
-<!--
- <module>spdy-npn-tests</module>
--->
- </modules>
- </profile>
- </profiles>
-
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-pmd-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>manifest</goal>
- </goals>
- <configuration>
- <instructions>
- <Export-Package>org.eclipse.jetty.spdy.*;version="9.1"</Export-Package>
- <Import-Package>org.eclipse.jetty.*;version="[9.0,10.0)",*</Import-Package>
- <_nouses>true</_nouses>
- </instructions>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
- </archive>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty.toolchain</groupId>
- <artifactId>jetty-test-helper</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/jetty-spdy/spdy-alpn-tests/pom.xml b/jetty-spdy/spdy-alpn-tests/pom.xml
deleted file mode 100644
index 3bca84b9a0..0000000000
--- a/jetty-spdy/spdy-alpn-tests/pom.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-parent</artifactId>
- <version>9.2.15-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>spdy-alpn-tests</artifactId>
- <name>Jetty :: SPDY :: ALPN Tests</name>
-
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copy</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.mortbay.jetty.alpn</groupId>
- <artifactId>alpn-boot</artifactId>
- <version>${alpn.version}</version>
- <type>jar</type>
- <overWrite>false</overWrite>
- <outputDirectory>${project.build.directory}/alpn</outputDirectory>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>-Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar</argLine>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty.alpn</groupId>
- <artifactId>alpn-api</artifactId>
- <version>${alpn.api.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-alpn-server</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-server</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-server</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-http-server</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-http-server</artifactId>
- <version>${project.version}</version>
- <classifier>tests</classifier>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/ALPNNegotiationTest.java b/jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/ALPNNegotiationTest.java
deleted file mode 100644
index 767cec96b0..0000000000
--- a/jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/ALPNNegotiationTest.java
+++ /dev/null
@@ -1,198 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-
-import org.eclipse.jetty.alpn.ALPN;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ALPNNegotiationTest extends AbstractALPNTest
-{
- @Test
- public void testClientAdvertisingHTTPServerSpeaksHTTP() throws Exception
- {
- InetSocketAddress address = prepare();
- connector.addConnectionFactory(new HttpConnectionFactory());
-
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLContext sslContext = sslContextFactory.getSslContext();
-
- try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort()))
- {
- client.setUseClientMode(true);
- client.setSoTimeout(5000);
-
- ALPN.put(client, new ALPN.ClientProvider()
- {
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public List<String> protocols()
- {
- return Arrays.asList("http/1.1");
- }
-
- @Override
- public void selected(String protocol)
- {
- Assert.assertEquals("http/1.1", protocol);
- }
- });
-
- client.startHandshake();
-
- // Verify that the server really speaks http/1.1
-
- OutputStream output = client.getOutputStream();
- output.write(("" +
- "GET / HTTP/1.1\r\n" +
- "Host: localhost:" + address.getPort() + "\r\n" +
- "\r\n" +
- "").getBytes(StandardCharsets.UTF_8));
- output.flush();
-
- InputStream input = client.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
- String line = reader.readLine();
- Assert.assertTrue(line.contains(" 404 "));
- }
- }
-
- @Test
- public void testClientAdvertisingMultipleProtocolsServerSpeaksHTTPWhenNegotiated() throws Exception
- {
- InetSocketAddress address = prepare();
- connector.addConnectionFactory(new HttpConnectionFactory());
-
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLContext sslContext = sslContextFactory.getSslContext();
- try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort()))
- {
- client.setUseClientMode(true);
- client.setSoTimeout(5000);
-
- ALPN.put(client, new ALPN.ClientProvider()
- {
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public List<String> protocols()
- {
- return Arrays.asList("unknown/1.0", "http/1.1");
- }
-
- @Override
- public void selected(String protocol)
- {
- Assert.assertEquals("http/1.1", protocol);
- }
- });
-
- client.startHandshake();
-
- // Verify that the server really speaks http/1.1
-
- OutputStream output = client.getOutputStream();
- output.write(("" +
- "GET / HTTP/1.1\r\n" +
- "Host: localhost:" + address.getPort() + "\r\n" +
- "\r\n" +
- "").getBytes(StandardCharsets.UTF_8));
- output.flush();
-
- InputStream input = client.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
- String line = reader.readLine();
- Assert.assertTrue(line.contains(" 404 "));
- }
- }
-
- @Test
- public void testClientNotSupportingALPNServerSpeaksDefaultProtocol() throws Exception
- {
- InetSocketAddress address = prepare();
- connector.addConnectionFactory(new HttpConnectionFactory());
-
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLContext sslContext = sslContextFactory.getSslContext();
- try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort()))
- {
- client.setUseClientMode(true);
- client.setSoTimeout(5000);
-
- ALPN.put(client, new ALPN.ClientProvider()
- {
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public List<String> protocols()
- {
- return null;
- }
-
- @Override
- public void selected(String s)
- {
- }
- });
-
- client.startHandshake();
-
- // Verify that the server really speaks http/1.1
-
- OutputStream output = client.getOutputStream();
- output.write(("" +
- "GET / HTTP/1.1\r\n" +
- "Host: localhost:" + address.getPort() + "\r\n" +
- "\r\n" +
- "").getBytes(StandardCharsets.UTF_8));
- output.flush();
-
- InputStream input = client.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
- String line = reader.readLine();
- Assert.assertTrue(line.contains(" 404 "));
- }
- }
-}
diff --git a/jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/ALPNSynReplyTest.java b/jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/ALPNSynReplyTest.java
deleted file mode 100644
index 42e0e194dc..0000000000
--- a/jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/ALPNSynReplyTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.Arrays;
-import java.util.List;
-import javax.net.ssl.SSLEngine;
-
-import org.eclipse.jetty.alpn.ALPN;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ALPNSynReplyTest extends AbstractALPNTest
-{
- @Test
- public void testGentleCloseDuringHandshake() throws Exception
- {
- InetSocketAddress address = prepare();
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
- sslEngine.setUseClientMode(true);
- ALPN.put(sslEngine, new ALPN.ClientProvider()
- {
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public List<String> protocols()
- {
- return Arrays.asList("test");
- }
-
- @Override
- public void selected(String protocol)
- {
- }
- });
- sslEngine.beginHandshake();
-
- ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
- sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
- encrypted.flip();
-
- try (SocketChannel channel = SocketChannel.open(address))
- {
- // Send ClientHello, immediately followed by TLS Close Alert and then by FIN
- channel.write(encrypted);
- sslEngine.closeOutbound();
- encrypted.clear();
- sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
- encrypted.flip();
- channel.write(encrypted);
- channel.shutdownOutput();
-
- // Read ServerHello from server
- encrypted.clear();
- int read = channel.read(encrypted);
- encrypted.flip();
- Assert.assertTrue(read > 0);
- // Cannot decrypt, as the SSLEngine has been already closed
-
- // Now if we read more, we should either read the TLS Close Alert, or directly -1
- encrypted.clear();
- read = channel.read(encrypted);
- // Sending a TLS Close Alert during handshake results in an exception when
- // unwrapping that the server react to by closing the connection abruptly.
- Assert.assertTrue(read < 0);
- }
- }
-
- @Test
- public void testAbruptCloseDuringHandshake() throws Exception
- {
- InetSocketAddress address = prepare();
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
- sslEngine.setUseClientMode(true);
- ALPN.put(sslEngine, new ALPN.ClientProvider()
- {
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public List<String> protocols()
- {
- return Arrays.asList("test");
- }
-
- @Override
- public void selected(String s)
- {
- }
- });
- sslEngine.beginHandshake();
-
- ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
- sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
- encrypted.flip();
-
- try (SocketChannel channel = SocketChannel.open(address))
- {
- // Send ClientHello, immediately followed by FIN (no TLS Close Alert)
- channel.write(encrypted);
- channel.shutdownOutput();
-
- // Read ServerHello from server
- encrypted.clear();
- int read = channel.read(encrypted);
- encrypted.flip();
- Assert.assertTrue(read > 0);
- ByteBuffer decrypted = ByteBuffer.allocate(sslEngine.getSession().getApplicationBufferSize());
- sslEngine.unwrap(encrypted, decrypted);
-
- // Now if we read more, we should either read the TLS Close Alert, or directly -1
- encrypted.clear();
- read = channel.read(encrypted);
- // Since we have close the connection abruptly, the server also does so
- Assert.assertTrue(read < 0);
- }
- }
-}
diff --git a/jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractALPNTest.java b/jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractALPNTest.java
deleted file mode 100644
index 53a6c0b264..0000000000
--- a/jetty-spdy/spdy-alpn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractALPNTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.net.InetSocketAddress;
-
-import org.eclipse.jetty.alpn.ALPN;
-import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.toolchain.test.TestTracker;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.junit.After;
-import org.junit.Rule;
-
-public class AbstractALPNTest
-{
- @Rule
- public final TestTracker tracker = new TestTracker();
- protected Server server;
- protected SPDYServerConnector connector;
- protected SPDYClient.Factory clientFactory;
-
- protected InetSocketAddress prepare() throws Exception
- {
- server = new Server();
- connector = new SPDYServerConnector(server, newSslContextFactory(), null, new ALPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"));
- connector.setPort(0);
- connector.setIdleTimeout(30000);
- server.addConnector(connector);
- server.start();
-
- QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setName(threadPool.getName() + "-client");
- clientFactory = new SPDYClient.Factory(threadPool);
- clientFactory.start();
-
- ALPN.debug = true;
-
- return new InetSocketAddress("localhost", connector.getLocalPort());
- }
-
- protected SslContextFactory newSslContextFactory()
- {
- SslContextFactory sslContextFactory = new SslContextFactory();
- sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
- sslContextFactory.setKeyStorePassword("storepwd");
- sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
- sslContextFactory.setTrustStorePassword("storepwd");
- sslContextFactory.setProtocol("TLSv1");
- sslContextFactory.setIncludeProtocols("TLSv1");
- return sslContextFactory;
- }
-
- @After
- public void dispose() throws Exception
- {
- clientFactory.stop();
- server.stop();
- }
-}
diff --git a/jetty-spdy/spdy-alpn-tests/src/test/resources/jetty-logging.properties b/jetty-spdy/spdy-alpn-tests/src/test/resources/jetty-logging.properties
deleted file mode 100644
index ead13ec197..0000000000
--- a/jetty-spdy/spdy-alpn-tests/src/test/resources/jetty-logging.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-#org.eclipse.jetty.spdy.LEVEL=DEBUG
diff --git a/jetty-spdy/spdy-alpn-tests/src/test/resources/keystore.jks b/jetty-spdy/spdy-alpn-tests/src/test/resources/keystore.jks
deleted file mode 100644
index 428ba54776..0000000000
--- a/jetty-spdy/spdy-alpn-tests/src/test/resources/keystore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-alpn-tests/src/test/resources/truststore.jks b/jetty-spdy/spdy-alpn-tests/src/test/resources/truststore.jks
deleted file mode 100644
index 839cb8c351..0000000000
--- a/jetty-spdy/spdy-alpn-tests/src/test/resources/truststore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-client/pom.xml b/jetty-spdy/spdy-client/pom.xml
deleted file mode 100644
index 7b3bed1ee0..0000000000
--- a/jetty-spdy/spdy-client/pom.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-parent</artifactId>
- <version>9.2.15-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>spdy-client</artifactId>
- <name>Jetty :: SPDY :: Client Binding</name>
-
- <properties>
- <bundle-symbolic-name>${project.groupId}.client</bundle-symbolic-name>
- </properties>
-
- <url>http://www.eclipse.org/jetty</url>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>manifest</goal>
- </goals>
- <configuration>
- <instructions>
- <Export-Package>org.eclipse.jetty.spdy.client;version="9.1"</Export-Package>
- <Import-Package>!org.eclipse.jetty.npn,!org.eclipse.jetty.alpn,org.eclipse.jetty.*;version="[9.0,10.0)",*</Import-Package>
- </instructions>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-core</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-alpn-client</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.alpn</groupId>
- <artifactId>alpn-api</artifactId>
- <version>${alpn.api.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.npn</groupId>
- <artifactId>npn-api</artifactId>
- <version>${npn.api.version}</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/FlowControlStrategyFactory.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/FlowControlStrategyFactory.java
deleted file mode 100644
index 439b32a4e0..0000000000
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/FlowControlStrategyFactory.java
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client;
-
-import org.eclipse.jetty.spdy.FlowControlStrategy;
-import org.eclipse.jetty.spdy.SPDYv3FlowControlStrategy;
-import org.eclipse.jetty.spdy.api.SPDY;
-
-public class FlowControlStrategyFactory
-{
- private FlowControlStrategyFactory()
- {
- }
-
- public static FlowControlStrategy newFlowControlStrategy(short version)
- {
- switch (version)
- {
- case SPDY.V2:
- return new FlowControlStrategy.None();
- case SPDY.V3:
- return new SPDYv3FlowControlStrategy();
- default:
- throw new IllegalStateException();
- }
- }
-}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnection.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnection.java
deleted file mode 100644
index 10c2a13b83..0000000000
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnection.java
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executor;
-import javax.net.ssl.SSLEngine;
-
-import org.eclipse.jetty.io.ClientConnectionFactory;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.NegotiatingClientConnection;
-import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class NPNClientConnection extends NegotiatingClientConnection implements NextProtoNego.ClientProvider
-{
- private static final Logger LOG = Log.getLogger(NPNClientConnection.class);
-
- private final String protocol;
-
- public NPNClientConnection(EndPoint endPoint, Executor executor, ClientConnectionFactory connectionFactory, SSLEngine sslEngine, Map<String, Object> context, String protocol)
- {
- super(endPoint, executor, sslEngine, connectionFactory, context);
- this.protocol = protocol;
- NextProtoNego.put(sslEngine, this);
- }
-
- @Override
- public boolean supports()
- {
- return true;
- }
-
- @Override
- public void unsupported()
- {
- NextProtoNego.remove(getSSLEngine());
- completed();
- }
-
- @Override
- public String selectProtocol(List<String> protocols)
- {
- if (protocols.contains(protocol))
- {
- NextProtoNego.remove(getSSLEngine());
- completed();
- return protocol;
- }
- else
- {
- LOG.info("Could not negotiate protocol: server {} - client {}", protocols, protocol);
- close();
- return null;
- }
- }
-
- @Override
- public void close()
- {
- NextProtoNego.remove(getSSLEngine());
- super.close();
- }
-}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnectionFactory.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnectionFactory.java
deleted file mode 100644
index 2f23057aff..0000000000
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnectionFactory.java
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.Executor;
-import javax.net.ssl.SSLEngine;
-
-import org.eclipse.jetty.io.ClientConnectionFactory;
-import org.eclipse.jetty.io.Connection;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.NegotiatingClientConnectionFactory;
-import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
-
-public class NPNClientConnectionFactory extends NegotiatingClientConnectionFactory
-{
- private final Executor executor;
- private final String protocol;
-
- public NPNClientConnectionFactory(Executor executor, ClientConnectionFactory connectionFactory, String protocol)
- {
- super(connectionFactory);
- this.executor = executor;
- this.protocol = protocol;
- }
-
- @Override
- public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
- {
- return new NPNClientConnection(endPoint, executor, getClientConnectionFactory(),
- (SSLEngine)context.get(SslClientConnectionFactory.SSL_ENGINE_CONTEXT_KEY), context, protocol);
- }
-}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
deleted file mode 100644
index c1b8ee5b9a..0000000000
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
+++ /dev/null
@@ -1,440 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.ClientConnectionFactory;
-import org.eclipse.jetty.io.Connection;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.io.NegotiatingClientConnectionFactory;
-import org.eclipse.jetty.io.SelectChannelEndPoint;
-import org.eclipse.jetty.io.SelectorManager;
-import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
-import org.eclipse.jetty.spdy.FlowControlStrategy;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.FuturePromise;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
-import org.eclipse.jetty.util.thread.Scheduler;
-
-/**
- * A {@link SPDYClient} allows applications to connect to one or more SPDY servers,
- * obtaining {@link Session} objects that can be used to send/receive SPDY frames.
- * <p/>
- * {@link SPDYClient} instances are created through a {@link Factory}:
- * <pre>
- * SPDYClient.Factory factory = new SPDYClient.Factory();
- * SPDYClient client = factory.newSPDYClient(SPDY.V3);
- * </pre>
- * and then used to connect to the server:
- * <pre>
- * FuturePromise&lt;Session&gt; promise = new FuturePromise&lt;&gt;();
- * client.connect("server.com", null, promise);
- * Session session = promise.get();
- * </pre>
- */
-public class SPDYClient
-{
- private final short version;
- private final Factory factory;
- private volatile SocketAddress bindAddress;
- private volatile long idleTimeout = -1;
- private volatile int initialWindowSize;
- private volatile boolean dispatchIO;
- private volatile ClientConnectionFactory connectionFactory;
-
- protected SPDYClient(short version, Factory factory)
- {
- this.version = version;
- this.factory = factory;
- setInitialWindowSize(65536);
- setDispatchIO(true);
- }
-
- public short getVersion()
- {
- return version;
- }
-
- public Factory getFactory()
- {
- return factory;
- }
-
- /**
- * Equivalent to:
- * <pre>
- * Future&lt;Session&gt; promise = new FuturePromise&lt;&gt;();
- * connect(address, listener, promise);
- * </pre>
- *
- * @param address the address to connect to
- * @param listener the session listener that will be notified of session events
- * @return a {@link Session} when connected
- */
- public Session connect(SocketAddress address, SessionFrameListener listener) throws ExecutionException, InterruptedException
- {
- FuturePromise<Session> promise = new FuturePromise<>();
- connect(address, listener, promise);
- return promise.get();
- }
-
- /**
- * Equivalent to:
- * <pre>
- * connect(address, listener, promise, null);
- * </pre>
- *
- * @param address the address to connect to
- * @param listener the session listener that will be notified of session events
- * @param promise the promise notified of connection success/failure
- */
- public void connect(SocketAddress address, SessionFrameListener listener, Promise<Session> promise)
- {
- connect(address, listener, promise, new HashMap<String, Object>());
- }
-
- /**
- * Connects to the given {@code address}, binding the given {@code listener} to session events,
- * and notified the given {@code promise} of the connect result.
- * <p/>
- * If the connect operation is successful, the {@code promise} will be invoked with the {@link Session}
- * object that applications can use to perform SPDY requests.
- *
- * @param address the address to connect to
- * @param listener the session listener that will be notified of session events
- * @param promise the promise notified of connection success/failure
- * @param context a context object passed to the {@link #getClientConnectionFactory() ConnectionFactory}
- * for the creation of the connection
- */
- public void connect(final SocketAddress address, final SessionFrameListener listener, final Promise<Session> promise, Map<String, Object> context)
- {
- if (!factory.isStarted())
- throw new IllegalStateException(Factory.class.getSimpleName() + " is not started");
-
- try
- {
- SocketChannel channel = SocketChannel.open();
- if (bindAddress != null)
- channel.bind(bindAddress);
- configure(channel);
- channel.configureBlocking(false);
-
- context.put(SslClientConnectionFactory.SSL_PEER_HOST_CONTEXT_KEY, ((InetSocketAddress)address).getHostString());
- context.put(SslClientConnectionFactory.SSL_PEER_PORT_CONTEXT_KEY, ((InetSocketAddress)address).getPort());
- context.put(SPDYClientConnectionFactory.SPDY_CLIENT_CONTEXT_KEY, this);
- context.put(SPDYClientConnectionFactory.SPDY_SESSION_LISTENER_CONTEXT_KEY, listener);
- context.put(SPDYClientConnectionFactory.SPDY_SESSION_PROMISE_CONTEXT_KEY, promise);
-
- if (channel.connect(address))
- factory.selector.accept(channel, context);
- else
- factory.selector.connect(channel, context);
- }
- catch (IOException x)
- {
- promise.failed(x);
- }
- }
-
- protected void configure(SocketChannel channel) throws IOException
- {
- channel.socket().setTcpNoDelay(true);
- }
-
- /**
- * @return the address to bind the socket channel to
- * @see #setBindAddress(SocketAddress)
- */
- public SocketAddress getBindAddress()
- {
- return bindAddress;
- }
-
- /**
- * @param bindAddress the address to bind the socket channel to
- * @see #getBindAddress()
- */
- public void setBindAddress(SocketAddress bindAddress)
- {
- this.bindAddress = bindAddress;
- }
-
- public long getIdleTimeout()
- {
- return idleTimeout;
- }
-
- public void setIdleTimeout(long idleTimeout)
- {
- this.idleTimeout = idleTimeout;
- }
-
- public int getInitialWindowSize()
- {
- return initialWindowSize;
- }
-
- public void setInitialWindowSize(int initialWindowSize)
- {
- this.initialWindowSize = initialWindowSize;
- }
-
- public boolean isDispatchIO()
- {
- return dispatchIO;
- }
-
- public void setDispatchIO(boolean dispatchIO)
- {
- this.dispatchIO = dispatchIO;
- }
-
- public ClientConnectionFactory getClientConnectionFactory()
- {
- return connectionFactory;
- }
-
- public void setClientConnectionFactory(ClientConnectionFactory connectionFactory)
- {
- this.connectionFactory = connectionFactory;
- }
-
- protected FlowControlStrategy newFlowControlStrategy()
- {
- return FlowControlStrategyFactory.newFlowControlStrategy(version);
- }
-
- public static class Factory extends ContainerLifeCycle
- {
- private final Queue<Session> sessions = new ConcurrentLinkedQueue<>();
- private final Scheduler scheduler;
- private final Executor executor;
- private final ByteBufferPool bufferPool;
- private final SslContextFactory sslContextFactory;
- private final SelectorManager selector;
- private final long idleTimeout;
- private long connectTimeout;
-
- public Factory()
- {
- this(null, null);
- }
-
- public Factory(SslContextFactory sslContextFactory)
- {
- this(null, null, sslContextFactory);
- }
-
- public Factory(Executor executor)
- {
- this(executor, null);
- }
-
- public Factory(Executor executor, Scheduler scheduler)
- {
- this(executor, scheduler, null);
- }
-
- public Factory(Executor executor, Scheduler scheduler, SslContextFactory sslContextFactory)
- {
- this(executor, scheduler, sslContextFactory, 30000);
- }
-
- public Factory(Executor executor, Scheduler scheduler, SslContextFactory sslContextFactory, long idleTimeout)
- {
- this(executor, scheduler, null, sslContextFactory, idleTimeout);
- }
-
- public Factory(Executor executor, Scheduler scheduler, ByteBufferPool bufferPool, SslContextFactory sslContextFactory, long idleTimeout)
- {
- this.idleTimeout = idleTimeout;
- setConnectTimeout(15000);
-
- if (executor == null)
- executor = new QueuedThreadPool();
- this.executor = executor;
- addBean(executor);
-
- if (scheduler == null)
- scheduler = new ScheduledExecutorScheduler();
- this.scheduler = scheduler;
- addBean(scheduler);
-
- if (bufferPool == null)
- bufferPool = new MappedByteBufferPool();
- this.bufferPool = bufferPool;
- addBean(bufferPool);
-
- this.sslContextFactory = sslContextFactory;
- if (sslContextFactory != null)
- addBean(sslContextFactory);
-
- selector = new ClientSelectorManager(executor, scheduler);
- selector.setConnectTimeout(getConnectTimeout());
- addBean(selector);
- }
-
- public ByteBufferPool getByteBufferPool()
- {
- return bufferPool;
- }
-
- public Scheduler getScheduler()
- {
- return scheduler;
- }
-
- public Executor getExecutor()
- {
- return executor;
- }
-
- public SslContextFactory getSslContextFactory()
- {
- return sslContextFactory;
- }
-
- public long getConnectTimeout()
- {
- return connectTimeout;
- }
-
- public void setConnectTimeout(long connectTimeout)
- {
- this.connectTimeout = connectTimeout;
- }
-
- public SPDYClient newSPDYClient(short version)
- {
- return newSPDYClient(version, new NPNClientConnectionFactory(getExecutor(), new SPDYClientConnectionFactory(), "spdy/" + version));
- }
-
- public SPDYClient newSPDYClient(short version, NegotiatingClientConnectionFactory negotiatingFactory)
- {
- SPDYClient client = new SPDYClient(version, this);
-
- ClientConnectionFactory connectionFactory = negotiatingFactory.getClientConnectionFactory();
- if (sslContextFactory != null)
- connectionFactory = new SslClientConnectionFactory(getSslContextFactory(), getByteBufferPool(), getExecutor(), negotiatingFactory);
-
- client.setClientConnectionFactory(connectionFactory);
- return client;
- }
-
- @Override
- protected void doStop() throws Exception
- {
- closeConnections();
- super.doStop();
- }
-
- boolean sessionOpened(Session session)
- {
- // Add sessions only if the factory is not stopping
- return isRunning() && sessions.offer(session);
- }
-
- boolean sessionClosed(Session session)
- {
- // Remove sessions only if the factory is not stopping
- // to avoid concurrent removes during iterations
- return isRunning() && sessions.remove(session);
- }
-
- private void closeConnections()
- {
- for (Session session : sessions)
- session.goAway(new GoAwayInfo(), Callback.Adapter.INSTANCE);
- sessions.clear();
- }
-
- public Collection<Session> getSessions()
- {
- return Collections.unmodifiableCollection(sessions);
- }
-
- @Override
- protected void dumpThis(Appendable out) throws IOException
- {
- super.dumpThis(out);
- dump(out, "", sessions);
- }
-
- private class ClientSelectorManager extends SelectorManager
- {
- private ClientSelectorManager(Executor executor, Scheduler scheduler)
- {
- super(executor, scheduler);
- }
-
- @Override
- protected EndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
- {
- @SuppressWarnings("unchecked")
- Map<String, Object> context = (Map<String, Object>)key.attachment();
- SPDYClient client = (SPDYClient)context.get(SPDYClientConnectionFactory.SPDY_CLIENT_CONTEXT_KEY);
- long clientIdleTimeout = client.getIdleTimeout();
- if (clientIdleTimeout < 0)
- clientIdleTimeout = idleTimeout;
- return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), clientIdleTimeout);
- }
-
- @Override
- public Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment) throws IOException
- {
- @SuppressWarnings("unchecked")
- Map<String, Object> context = (Map<String, Object>)attachment;
- try
- {
- SPDYClient client = (SPDYClient)context.get(SPDYClientConnectionFactory.SPDY_CLIENT_CONTEXT_KEY);
- return client.getClientConnectionFactory().newConnection(endPoint, context);
- }
- catch (Throwable x)
- {
- @SuppressWarnings("unchecked")
- Promise<Session> promise = (Promise<Session>)context.get(SPDYClientConnectionFactory.SPDY_SESSION_PROMISE_CONTEXT_KEY);
- promise.failed(x);
- throw x;
- }
- }
- }
- }
-}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClientConnectionFactory.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClientConnectionFactory.java
deleted file mode 100644
index dc6663228f..0000000000
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClientConnectionFactory.java
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.ClientConnectionFactory;
-import org.eclipse.jetty.io.Connection;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.FlowControlStrategy;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.StandardSession;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient.Factory;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.util.Promise;
-
-public class SPDYClientConnectionFactory implements ClientConnectionFactory
-{
- public static final String SPDY_CLIENT_CONTEXT_KEY = "spdy.client";
- public static final String SPDY_SESSION_LISTENER_CONTEXT_KEY = "spdy.session.listener";
- public static final String SPDY_SESSION_PROMISE_CONTEXT_KEY = "spdy.session.promise";
-
- @Override
- public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
- {
- SPDYClient client = (SPDYClient)context.get(SPDY_CLIENT_CONTEXT_KEY);
- SPDYClient.Factory factory = client.getFactory();
- ByteBufferPool byteBufferPool = factory.getByteBufferPool();
- CompressionFactory compressionFactory = new StandardCompressionFactory();
- Parser parser = new Parser(compressionFactory.newDecompressor());
- Generator generator = new Generator(byteBufferPool, compressionFactory.newCompressor());
-
- SPDYConnection connection = new ClientSPDYConnection(endPoint, byteBufferPool, parser, factory, client.isDispatchIO());
-
- FlowControlStrategy flowControlStrategy = client.newFlowControlStrategy();
-
- SessionFrameListener listener = (SessionFrameListener)context.get(SPDY_SESSION_LISTENER_CONTEXT_KEY);
- StandardSession session = new StandardSession(client.getVersion(), byteBufferPool,
- factory.getScheduler(), connection, endPoint, connection, 1, listener, generator, flowControlStrategy);
-
- session.setWindowSize(client.getInitialWindowSize());
- parser.addListener(session);
- connection.setSession(session);
-
- @SuppressWarnings("unchecked")
- Promise<Session> promise = (Promise<Session>)context.get(SPDY_SESSION_PROMISE_CONTEXT_KEY);
- promise.succeeded(session);
-
- return connection;
- }
-
- private class ClientSPDYConnection extends SPDYConnection
- {
- private final Factory factory;
-
- public ClientSPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Factory factory, boolean dispatchIO)
- {
- super(endPoint, bufferPool, parser, factory.getExecutor(), dispatchIO);
- this.factory = factory;
- }
-
- @Override
- public void onOpen()
- {
- super.onOpen();
- factory.sessionOpened(getSession());
- }
-
- @Override
- public void onClose()
- {
- super.onClose();
- factory.sessionClosed(getSession());
- }
- }
-}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYConnection.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYConnection.java
deleted file mode 100644
index 3a6719876a..0000000000
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYConnection.java
+++ /dev/null
@@ -1,191 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.concurrent.Executor;
-
-import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.RuntimeIOException;
-import org.eclipse.jetty.spdy.Controller;
-import org.eclipse.jetty.spdy.ISession;
-import org.eclipse.jetty.spdy.IdleListener;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class SPDYConnection extends AbstractConnection implements Controller, IdleListener
-{
- private static final Logger LOG = Log.getLogger(SPDYConnection.class);
- private final ByteBufferPool bufferPool;
- private final Parser parser;
- private final int bufferSize;
- private volatile ISession session;
- private volatile boolean idle = false;
-
- public SPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Executor executor, boolean dispatchIO)
- {
- this(endPoint, bufferPool, parser, executor, dispatchIO, 8192);
- }
-
- public SPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Executor executor, boolean dispatchIO, int bufferSize)
- {
- // Since SPDY is multiplexed, onFillable() must never block while calling application code. In fact,
- // the SPDY code always dispatches to a new thread when calling application code,
- // so here we can safely pass false as last parameter, and avoid to dispatch to onFillable().
- // The IO operation (read, parse, etc.) will not block and will be fast in almost all cases.
- // Big uploads to a server, however, might occupy the Selector thread for a long time and
- // therefore starve other connections, so by default dispatchIO is true.
- super(endPoint, executor, dispatchIO);
- this.bufferPool = bufferPool;
- this.parser = parser;
- onIdle(true);
- this.bufferSize = bufferSize;
- }
-
- @Override
- public void onOpen()
- {
- super.onOpen();
- fillInterested();
- }
-
- @Override
- public void onFillable()
- {
- ByteBuffer buffer = bufferPool.acquire(bufferSize, false);
- boolean readMore = read(buffer) == 0;
- bufferPool.release(buffer);
- if (readMore)
- fillInterested();
- }
-
- protected int read(ByteBuffer buffer)
- {
- EndPoint endPoint = getEndPoint();
- while (true)
- {
- int filled = fill(endPoint, buffer);
- if (LOG.isDebugEnabled()) // Avoid boxing of variable 'filled'
- LOG.debug("Read {} bytes", filled);
- if (filled == 0)
- {
- return 0;
- }
- else if (filled < 0)
- {
- shutdown(session);
- return -1;
- }
- else
- {
- parser.parse(buffer);
- }
- }
- }
-
- private int fill(EndPoint endPoint, ByteBuffer buffer)
- {
- try
- {
- if (endPoint.isInputShutdown())
- return -1;
- return endPoint.fill(buffer);
- }
- catch (IOException x)
- {
- endPoint.close();
- throw new RuntimeIOException(x);
- }
- }
-
- @Override
- public void write(final Callback callback, ByteBuffer... buffers)
- {
- EndPoint endPoint = getEndPoint();
- endPoint.write(callback, buffers);
- }
-
- @Override
- public void close()
- {
- goAway(session);
- }
-
- @Override
- public void close(boolean onlyOutput)
- {
- EndPoint endPoint = getEndPoint();
- // We need to gently close first, to allow
- // SSL close alerts to be sent by Jetty
- if (LOG.isDebugEnabled())
- LOG.debug("Shutting down output {}", endPoint);
- endPoint.shutdownOutput();
- if (!onlyOutput)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Closing {}", endPoint);
- endPoint.close();
- }
- }
-
- @Override
- public void onIdle(boolean idle)
- {
- this.idle = idle;
- }
-
- @Override
- protected boolean onReadTimeout()
- {
- boolean idle = this.idle;
- if (LOG.isDebugEnabled())
- LOG.debug("Idle timeout on {}, idle={}", this, idle);
- if (idle)
- goAway(session);
- return false;
- }
-
- protected void goAway(ISession session)
- {
- if (session != null)
- session.goAway(new GoAwayInfo(), Callback.Adapter.INSTANCE);
- }
-
- private void shutdown(ISession session)
- {
- if (session != null && !getEndPoint().isOutputShutdown())
- session.shutdown();
- }
-
- protected ISession getSession()
- {
- return session;
- }
-
- public void setSession(ISession session)
- {
- this.session = session;
- }
-}
diff --git a/jetty-spdy/spdy-core/pom.xml b/jetty-spdy/spdy-core/pom.xml
deleted file mode 100644
index 2cb325d492..0000000000
--- a/jetty-spdy/spdy-core/pom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-parent</artifactId>
- <version>9.2.15-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>spdy-core</artifactId>
- <name>Jetty :: SPDY :: Core</name>
-
- <properties>
- <bundle-symbolic-name>${project.groupId}.core</bundle-symbolic-name>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-util</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-io</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/CompressionDictionary.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/CompressionDictionary.java
deleted file mode 100644
index c97b579dea..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/CompressionDictionary.java
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import org.eclipse.jetty.spdy.api.SPDY;
-
-public class CompressionDictionary
-{
- private static final byte[] DICTIONARY_V2 = ("" +
- "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-" +
- "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi" +
- "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser" +
- "-agent10010120020120220320420520630030130230330430530630740040140240340440" +
- "5406407408409410411412413414415416417500501502503504505accept-rangesageeta" +
- "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic" +
- "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran" +
- "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati" +
- "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo" +
- "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe" +
- "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic" +
- "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1" +
- ".1statusversionurl" +
- // Must be NUL terminated
- "\u0000").getBytes();
-
- private static final byte[] DICTIONARY_V3 = ("" +
- "\u0000\u0000\u0000\u0007options\u0000\u0000\u0000\u0004head\u0000\u0000\u0000\u0004post" +
- "\u0000\u0000\u0000\u0003put\u0000\u0000\u0000\u0006delete\u0000\u0000\u0000\u0005trace" +
- "\u0000\u0000\u0000\u0006accept\u0000\u0000\u0000\u000Eaccept-charset" +
- "\u0000\u0000\u0000\u000Faccept-encoding\u0000\u0000\u0000\u000Faccept-language" +
- "\u0000\u0000\u0000\raccept-ranges\u0000\u0000\u0000\u0003age\u0000\u0000\u0000\u0005allow" +
- "\u0000\u0000\u0000\rauthorization\u0000\u0000\u0000\rcache-control" +
- "\u0000\u0000\u0000\nconnection\u0000\u0000\u0000\fcontent-base\u0000\u0000\u0000\u0010content-encoding" +
- "\u0000\u0000\u0000\u0010content-language\u0000\u0000\u0000\u000Econtent-length" +
- "\u0000\u0000\u0000\u0010content-location\u0000\u0000\u0000\u000Bcontent-md5" +
- "\u0000\u0000\u0000\rcontent-range\u0000\u0000\u0000\fcontent-type\u0000\u0000\u0000\u0004date" +
- "\u0000\u0000\u0000\u0004etag\u0000\u0000\u0000\u0006expect\u0000\u0000\u0000\u0007expires" +
- "\u0000\u0000\u0000\u0004from\u0000\u0000\u0000\u0004host\u0000\u0000\u0000\bif-match" +
- "\u0000\u0000\u0000\u0011if-modified-since\u0000\u0000\u0000\rif-none-match\u0000\u0000\u0000\bif-range" +
- "\u0000\u0000\u0000\u0013if-unmodified-since\u0000\u0000\u0000\rlast-modified" +
- "\u0000\u0000\u0000\blocation\u0000\u0000\u0000\fmax-forwards\u0000\u0000\u0000\u0006pragma" +
- "\u0000\u0000\u0000\u0012proxy-authenticate\u0000\u0000\u0000\u0013proxy-authorization" +
- "\u0000\u0000\u0000\u0005range\u0000\u0000\u0000\u0007referer\u0000\u0000\u0000\u000Bretry-after" +
- "\u0000\u0000\u0000\u0006server\u0000\u0000\u0000\u0002te\u0000\u0000\u0000\u0007trailer" +
- "\u0000\u0000\u0000\u0011transfer-encoding\u0000\u0000\u0000\u0007upgrade\u0000\u0000\u0000\nuser-agent" +
- "\u0000\u0000\u0000\u0004vary\u0000\u0000\u0000\u0003via\u0000\u0000\u0000\u0007warning" +
- "\u0000\u0000\u0000\u0010www-authenticate\u0000\u0000\u0000\u0006method\u0000\u0000\u0000\u0003get" +
- "\u0000\u0000\u0000\u0006status\u0000\u0000\u0000\u0006200 OK\u0000\u0000\u0000\u0007version" +
- "\u0000\u0000\u0000\bHTTP/1.1\u0000\u0000\u0000\u0003url\u0000\u0000\u0000\u0006public" +
- "\u0000\u0000\u0000\nset-cookie\u0000\u0000\u0000\nkeep-alive\u0000\u0000\u0000\u0006origin" +
- "100101201202205206300302303304305306307402405406407408409410411412413414415416417502504505" +
- "203 Non-Authoritative Information204 No Content301 Moved Permanently400 Bad Request401 Unauthorized" +
- "403 Forbidden404 Not Found500 Internal Server Error501 Not Implemented503 Service Unavailable" +
- "Jan Feb Mar Apr May Jun Jul Aug Sept Oct Nov Dec 00:00:00 Mon, Tue, Wed, Thu, Fri, Sat, Sun, GMT" +
- "chunked,text/html,image/png,image/jpg,image/gif,application/xml,application/xhtml+xml,text/plain," +
- "text/javascript,publicprivatemax-age=gzip,deflate,sdchcharset=utf-8charset=iso-8859-1,utf-,*,enq=0.")
- .getBytes();
-
- public static byte[] get(short version)
- {
- switch (version)
- {
- case SPDY.V2:
- return DICTIONARY_V2;
- case SPDY.V3:
- return DICTIONARY_V3;
- default:
- throw new IllegalStateException();
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/CompressionFactory.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/CompressionFactory.java
deleted file mode 100644
index 6955bbfa80..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/CompressionFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.util.zip.ZipException;
-
-public interface CompressionFactory
-{
- public Compressor newCompressor();
-
- public Decompressor newDecompressor();
-
- public interface Compressor
- {
- public void setInput(byte[] input);
-
- public void setDictionary(byte[] dictionary);
-
- public int compress(byte[] output);
- }
-
- public interface Decompressor
- {
- public void setDictionary(byte[] dictionary);
-
- public void setInput(byte[] input);
-
- public int decompress(byte[] output) throws ZipException;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Controller.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Controller.java
deleted file mode 100644
index b63695332c..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Controller.java
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.util.Callback;
-
-public interface Controller
-{
- public void write(Callback callback, ByteBuffer... buffers);
-
- public void close(boolean onlyOutput);
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/FlowControlStrategy.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/FlowControlStrategy.java
deleted file mode 100644
index d367b5e3e8..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/FlowControlStrategy.java
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import org.eclipse.jetty.spdy.api.DataInfo;
-
-// TODO: add methods that tell how much written and whether we're TCP congested ?
-public interface FlowControlStrategy
-{
- public int getWindowSize(ISession session);
-
- public void setWindowSize(ISession session, int windowSize);
-
- public void onNewStream(ISession session, IStream stream);
-
- public void onWindowUpdate(ISession session, IStream stream, int delta);
-
- public void updateWindow(ISession session, IStream stream, int delta);
-
- public void onDataReceived(ISession session, IStream stream, DataInfo dataInfo);
-
- public void onDataConsumed(ISession session, IStream stream, DataInfo dataInfo, int delta);
-
- public static class None implements FlowControlStrategy
- {
- private volatile int windowSize;
-
- public None()
- {
- this(65536);
- }
-
- public None(int windowSize)
- {
- this.windowSize = windowSize;
- }
-
- @Override
- public int getWindowSize(ISession session)
- {
- return windowSize;
- }
-
- @Override
- public void setWindowSize(ISession session, int windowSize)
- {
- this.windowSize = windowSize;
- }
-
- @Override
- public void onNewStream(ISession session, IStream stream)
- {
- stream.updateWindowSize(windowSize);
- }
-
- @Override
- public void onWindowUpdate(ISession session, IStream stream, int delta)
- {
- }
-
- @Override
- public void updateWindow(ISession session, IStream stream, int delta)
- {
- }
-
- @Override
- public void onDataReceived(ISession session, IStream stream, DataInfo dataInfo)
- {
- }
-
- @Override
- public void onDataConsumed(ISession session, IStream stream, DataInfo dataInfo, int delta)
- {
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Flusher.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Flusher.java
deleted file mode 100644
index 9bb7125833..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/Flusher.java
+++ /dev/null
@@ -1,266 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.jetty.spdy.StandardSession.FrameBytes;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.util.ArrayQueue;
-import org.eclipse.jetty.util.IteratingCallback;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class Flusher
-{
- private static final Logger LOG = Log.getLogger(Flusher.class);
-
- private final IteratingCallback callback = new FlusherCallback();
- private final Object lock = new Object();
- private final ArrayQueue<StandardSession.FrameBytes> queue = new ArrayQueue<>(ArrayQueue.DEFAULT_CAPACITY, ArrayQueue.DEFAULT_GROWTH, lock);
- private final Controller controller;
- private final int maxGather;
- private Throwable failure;
-
- public Flusher(Controller controller)
- {
- this(controller, 8);
- }
-
- public Flusher(Controller controller, int maxGather)
- {
- this.controller = controller;
- this.maxGather = maxGather;
- }
-
- public void removeFrameBytesFromQueue(Stream stream)
- {
- synchronized (lock)
- {
- for (StandardSession.FrameBytes frameBytes : queue)
- if (frameBytes.getStream() == stream)
- queue.remove(frameBytes);
- }
- }
-
- public Throwable prepend(StandardSession.FrameBytes frameBytes)
- {
- synchronized (lock)
- {
- Throwable failure = this.failure;
- if (failure == null)
- {
- // Scan from the front of the queue looking to skip higher priority messages
- int index = 0;
- int size = queue.size();
- while (index < size)
- {
- StandardSession.FrameBytes element = queue.getUnsafe(index);
- if (element.compareTo(frameBytes) <= 0)
- break;
- ++index;
- }
- queue.add(index, frameBytes);
- }
- return failure;
- }
- }
-
- public Throwable append(StandardSession.FrameBytes frameBytes)
- {
- synchronized (lock)
- {
- Throwable failure = this.failure;
- if (failure == null)
- {
- // Non DataFrameBytes are inserted last
- queue.add(frameBytes);
- }
- return failure;
- }
- }
-
- public Throwable append(StandardSession.DataFrameBytes frameBytes)
- {
- synchronized (lock)
- {
- Throwable failure = this.failure;
- if (failure == null)
- {
- // DataFrameBytes are inserted by priority
- int index = queue.size();
- while (index > 0)
- {
- StandardSession.FrameBytes element = queue.getUnsafe(index - 1);
- if (element.compareTo(frameBytes) >= 0)
- break;
- --index;
- }
- queue.add(index, frameBytes);
- }
- return failure;
- }
- }
-
- public void flush()
- {
- callback.iterate();
- }
-
- public int getQueueSize()
- {
- synchronized (lock)
- {
- return queue.size();
- }
- }
-
- private class FlusherCallback extends IteratingCallback
- {
- private final List<StandardSession.FrameBytes> active = new ArrayList<>(maxGather);
- private final List<StandardSession.FrameBytes> succeeded = new ArrayList<>(maxGather);
- private final Set<IStream> stalled = new HashSet<>();
-
- @Override
- protected Action process() throws Exception
- {
- synchronized (lock)
- {
- // Scan queue for data to write from first non stalled stream.
- int index = 0; // The index of the first non-stalled frame.
- int size = queue.size();
- while (index < size)
- {
- FrameBytes frameBytes = queue.getUnsafe(index);
- IStream stream = frameBytes.getStream();
-
- if (stream != null)
- {
- // Is it a frame belonging to an already stalled stream ?
- if (stalled.size() > 0 && stalled.contains(stream))
- {
- ++index;
- continue;
- }
-
- // Has the stream consumed all its flow control window ?
- if (stream.getWindowSize() <= 0)
- {
- stalled.add(stream);
- ++index;
- continue;
- }
- }
-
- // We will be possibly writing this frame, so take the frame off the queue.
- queue.remove(index);
- --size;
-
- // Has the stream been reset for this data frame ?
- if (stream != null && stream.isReset() && frameBytes instanceof StandardSession.DataFrameBytes)
- {
- // TODO: notify from within sync block !
- frameBytes.failed(new StreamException(frameBytes.getStream().getId(),
- StreamStatus.INVALID_STREAM, "Stream: " + frameBytes.getStream() + " is reset!"));
- continue;
- }
-
- active.add(frameBytes);
- }
- stalled.clear();
-
- if (LOG.isDebugEnabled())
- LOG.debug("Flushing {} of {} frame(s) in queue", active.size(), queue.size());
- }
-
- if (active.isEmpty())
- return Action.IDLE;
-
- // Get the bytes to write
- ByteBuffer[] buffers = new ByteBuffer[active.size()];
- for (int i = 0; i < buffers.length; i++)
- buffers[i] = active.get(i).getByteBuffer();
-
- if (controller != null)
- controller.write(this, buffers);
-
- // TODO: optimization
- // If the callback completely immediately, it means that
- // the connection is not congested, and therefore we can
- // write more data without blocking.
- // Therefore we should check this condition and increase
- // the write window, which means two things: autotune the
- // maxGather parameter, and/or autotune the buffer returned
- // by FrameBytes.getByteBuffer() (see also comment there).
-
- return Action.SCHEDULED;
- }
-
- @Override
- protected void onCompleteSuccess()
- {
- // will never be called as process always returns SCHEDULED or IDLE
- throw new IllegalStateException();
- }
-
- @Override
- public void succeeded()
- {
- synchronized (lock)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Succeeded write of {}, q={}", active, queue.size());
- succeeded.addAll(active);
- active.clear();
- }
- // Notify outside the synchronized block.
- for (FrameBytes frame : succeeded)
- frame.succeeded();
- succeeded.clear();
- super.succeeded();
- }
-
- @Override
- public void onCompleteFailure(Throwable x)
- {
- List<StandardSession.FrameBytes> failed = new ArrayList<>();
- synchronized (lock)
- {
- failure = x;
- if (LOG.isDebugEnabled())
- {
- String logMessage = String.format("Failed write of %s, failing all %d frame(s) in queue", this, queue.size());
- LOG.debug(logMessage, x);
- }
- failed.addAll(active);
- active.clear();
- failed.addAll(queue);
- queue.clear();
- }
- // Notify outside the synchronized block.
- for (StandardSession.FrameBytes frame : failed)
- frame.failed(x);
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java
deleted file mode 100644
index 23a5a47f5d..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.util.Callback;
-
-public interface ISession extends Session
-{
- public void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback callback);
-
- public void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Callback callback);
-
- /**
- * <p>Gracefully shuts down this session.</p>
- * <p>A special item is queued that will close the connection when it will be dequeued.</p>
- */
- public void shutdown();
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IStream.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IStream.java
deleted file mode 100644
index 43582700f9..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IStream.java
+++ /dev/null
@@ -1,120 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.util.Callback;
-
-/**
- * <p>The internal interface that represents a stream.</p>
- * <p>{@link IStream} contains additional methods used by a SPDY
- * implementation (and not by an application).</p>
- */
-public interface IStream extends Stream, Callback
-{
- /**
- * <p>Senders of data frames need to know the current window size
- * to determine whether they can send more data.</p>
- *
- * @return the current window size for this stream.
- * @see #updateWindowSize(int)
- */
- public int getWindowSize();
-
- /**
- * <p>Updates the window size for this stream by the given amount,
- * that can be positive or negative.</p>
- * <p>Senders and recipients of data frames update the window size,
- * respectively, with negative values and positive values.</p>
- *
- * @param delta the signed amount the window size needs to be updated
- * @see #getWindowSize()
- */
- public void updateWindowSize(int delta);
-
- /**
- * @param listener the stream frame listener associated to this stream
- * as returned by {@link SessionFrameListener#onSyn(Stream, SynInfo)}
- */
- public void setStreamFrameListener(StreamFrameListener listener);
-
- /**
- * @return the stream frame listener associated to this stream
- */
- public StreamFrameListener getStreamFrameListener();
-
- /**
- * <p>A stream can be open, {@link #isHalfClosed() half closed} or
- * {@link #isClosed() closed} and this method updates the close state
- * of this stream.</p>
- * <p>If the stream is open, calling this method with a value of true
- * puts the stream into half closed state.</p>
- * <p>If the stream is half closed, calling this method with a value
- * of true puts the stream into closed state.</p>
- *
- * @param close whether the close state should be updated
- * @param local whether the close is local or remote
- */
- public void updateCloseState(boolean close, boolean local);
-
- /**
- * <p>Processes the given control frame,
- * for example by updating the stream's state or by calling listeners.</p>
- *
- * @param frame the control frame to process
- * @see #process(DataInfo)
- */
- public void process(ControlFrame frame);
-
- /**
- * <p>Processes the given {@code dataInfo},
- * for example by updating the stream's state or by calling listeners.</p>
- *
- * @param dataInfo the DataInfo to process
- * @see #process(ControlFrame)
- */
- public void process(DataInfo dataInfo);
-
- /**
- * <p>Associate the given {@link IStream} to this {@link IStream}.</p>
- *
- * @param stream the stream to associate with this stream
- */
- public void associate(IStream stream);
-
- /**
- * <p>remove the given associated {@link IStream} from this stream</p>
- *
- * @param stream the stream to be removed
- */
- public void disassociate(IStream stream);
-
- /**
- * <p>Overrides Stream.getAssociatedStream() to return an instance of IStream instead of Stream
- *
- * @see Stream#getAssociatedStream()
- */
- @Override
- public IStream getAssociatedStream();
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IdleListener.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IdleListener.java
deleted file mode 100644
index ff190d474e..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/IdleListener.java
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-public interface IdleListener
-{
- public void onIdle(boolean idle);
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/PushSynInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/PushSynInfo.java
deleted file mode 100644
index 39d13112ca..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/PushSynInfo.java
+++ /dev/null
@@ -1,60 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-
-/* ------------------------------------------------------------ */
-/**
- * <p>A subclass container of {@link SynInfo} for unidirectional streams</p>
- */
-public class PushSynInfo extends SynInfo
-{
- public static final byte FLAG_UNIDIRECTIONAL = 2;
-
- private int associatedStreamId;
-
- public PushSynInfo(int associatedStreamId, PushInfo pushInfo){
- super(pushInfo.getTimeout(), pushInfo.getUnit(), pushInfo.getHeaders(), pushInfo.isClose(), (byte)0);
- this.associatedStreamId = associatedStreamId;
- }
-
- /**
- * @return the close and unidirectional flags as integer
- * @see #FLAG_CLOSE
- * @see #FLAG_UNIDIRECTIONAL
- */
- @Override
- public byte getFlags()
- {
- byte flags = super.getFlags();
- flags += FLAG_UNIDIRECTIONAL;
- return flags;
- }
-
- /**
- * @return the id of the associated stream
- */
- public int getAssociatedStreamId()
- {
- return associatedStreamId;
- }
-
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/SPDYv3FlowControlStrategy.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/SPDYv3FlowControlStrategy.java
deleted file mode 100644
index fe37965aa2..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/SPDYv3FlowControlStrategy.java
+++ /dev/null
@@ -1,90 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
-import org.eclipse.jetty.util.Callback;
-
-public class SPDYv3FlowControlStrategy implements FlowControlStrategy
-{
- private volatile int windowSize;
-
- @Override
- public int getWindowSize(ISession session)
- {
- return windowSize;
- }
-
- @Override
- public void setWindowSize(ISession session, int windowSize)
- {
- int prevWindowSize = this.windowSize;
- this.windowSize = windowSize;
- for (Stream stream : session.getStreams())
- ((IStream)stream).updateWindowSize(windowSize - prevWindowSize);
- }
-
- @Override
- public void onNewStream(ISession session, IStream stream)
- {
- stream.updateWindowSize(windowSize);
- }
-
- @Override
- public void onWindowUpdate(ISession session, IStream stream, int delta)
- {
- if (stream != null)
- stream.updateWindowSize(delta);
- }
-
- @Override
- public void updateWindow(ISession session, IStream stream, int delta)
- {
- stream.updateWindowSize(delta);
- }
-
- @Override
- public void onDataReceived(ISession session, IStream stream, DataInfo dataInfo)
- {
- // Do nothing
- }
-
- @Override
- public void onDataConsumed(ISession session, IStream stream, DataInfo dataInfo, int delta)
- {
- // This is the algorithm for flow control.
- // This method may be called multiple times with delta=1, but we only send a window
- // update when the whole dataInfo has been consumed.
- // Other policies may be to send window updates when consumed() is greater than
- // a certain threshold, etc. but for now the policy is not pluggable for simplicity.
- // Note that the frequency of window updates depends on the read buffer, that
- // should not be too smaller than the window size to avoid frequent window updates.
- // Therefore, a pluggable policy should be able to modify the read buffer capacity.
- int length = dataInfo.length();
- if (dataInfo.consumed() == length && !stream.isClosed() && length > 0)
- {
- WindowUpdateFrame windowUpdateFrame = new WindowUpdateFrame(session.getVersion(), stream.getId(), length);
- session.control(stream, windowUpdateFrame, 0, TimeUnit.MILLISECONDS, Callback.Adapter.INSTANCE);
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/SessionException.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/SessionException.java
deleted file mode 100644
index 26bc843e5c..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/SessionException.java
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import org.eclipse.jetty.spdy.api.SessionStatus;
-
-public class SessionException extends RuntimeException
-{
- private final SessionStatus sessionStatus;
-
- public SessionException(SessionStatus sessionStatus)
- {
- this.sessionStatus = sessionStatus;
- }
-
- public SessionException(SessionStatus sessionStatus, String message)
- {
- super(message);
- this.sessionStatus = sessionStatus;
- }
-
- public SessionException(SessionStatus sessionStatus, Throwable cause)
- {
- super(cause);
- this.sessionStatus = sessionStatus;
- }
-
- public SessionStatus getSessionStatus()
- {
- return sessionStatus;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardCompressionFactory.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardCompressionFactory.java
deleted file mode 100644
index 35150cfae0..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardCompressionFactory.java
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.util.zip.DataFormatException;
-import java.util.zip.Deflater;
-import java.util.zip.Inflater;
-import java.util.zip.ZipException;
-
-public class StandardCompressionFactory implements CompressionFactory
-{
- @Override
- public Compressor newCompressor()
- {
- return new StandardCompressor();
- }
-
- @Override
- public Decompressor newDecompressor()
- {
- return new StandardDecompressor();
- }
-
- public static class StandardCompressor implements Compressor
- {
- private final Deflater deflater = new Deflater();
-
- @Override
- public void setInput(byte[] input)
- {
- deflater.setInput(input);
- }
-
- @Override
- public void setDictionary(byte[] dictionary)
- {
- deflater.setDictionary(dictionary);
- }
-
- @Override
- public int compress(byte[] output)
- {
- return deflater.deflate(output, 0, output.length, Deflater.SYNC_FLUSH);
- }
- }
-
- public static class StandardDecompressor implements CompressionFactory.Decompressor
- {
- private final Inflater inflater = new Inflater();
-
- @Override
- public void setDictionary(byte[] dictionary)
- {
- inflater.setDictionary(dictionary);
- }
-
- @Override
- public void setInput(byte[] input)
- {
- inflater.setInput(input);
- }
-
- @Override
- public int decompress(byte[] output) throws ZipException
- {
- try
- {
- return inflater.inflate(output);
- }
- catch (DataFormatException x)
- {
- throw (ZipException)new ZipException().initCause(x);
- }
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java
deleted file mode 100644
index c03cb4bf51..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java
+++ /dev/null
@@ -1,1303 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.InterruptedByTimeoutException;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.PingInfo;
-import org.eclipse.jetty.spdy.api.PingResultInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.SPDYException;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.api.Settings;
-import org.eclipse.jetty.spdy.api.SettingsInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.ControlFrameType;
-import org.eclipse.jetty.spdy.frames.CredentialFrame;
-import org.eclipse.jetty.spdy.frames.DataFrame;
-import org.eclipse.jetty.spdy.frames.GoAwayFrame;
-import org.eclipse.jetty.spdy.frames.HeadersFrame;
-import org.eclipse.jetty.spdy.frames.PingFrame;
-import org.eclipse.jetty.spdy.frames.RstStreamFrame;
-import org.eclipse.jetty.spdy.frames.SettingsFrame;
-import org.eclipse.jetty.spdy.frames.SynReplyFrame;
-import org.eclipse.jetty.spdy.frames.SynStreamFrame;
-import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.util.Atomics;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.FutureCallback;
-import org.eclipse.jetty.util.FuturePromise;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.component.ContainerLifeCycle;
-import org.eclipse.jetty.util.component.Dumpable;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.Scheduler;
-
-public class StandardSession implements ISession, Parser.Listener, Dumpable
-{
- private static final Logger LOG = Log.getLogger(Session.class);
-
- private final Flusher flusher;
- private final Map<String, Object> attributes = new ConcurrentHashMap<>();
- private final List<Listener> listeners = new CopyOnWriteArrayList<>();
- private final ConcurrentMap<Integer, IStream> streams = new ConcurrentHashMap<>();
- private final ByteBufferPool bufferPool;
- private final Scheduler scheduler;
- private final short version;
- private final Controller controller;
- private final EndPoint endPoint;
- private final IdleListener idleListener;
- private final AtomicInteger streamIds;
- private final AtomicInteger pingIds;
- private final SessionFrameListener listener;
- private final Generator generator;
- private final AtomicBoolean goAwaySent = new AtomicBoolean();
- private final AtomicBoolean goAwayReceived = new AtomicBoolean();
- private final AtomicInteger lastStreamId = new AtomicInteger();
- private final AtomicInteger localStreamCount = new AtomicInteger(0);
- private final FlowControlStrategy flowControlStrategy;
- private volatile int maxConcurrentLocalStreams = -1;
-
- public StandardSession(short version, ByteBufferPool bufferPool, Scheduler scheduler,
- Controller controller, EndPoint endPoint, IdleListener idleListener, int initialStreamId,
- SessionFrameListener listener, Generator generator, FlowControlStrategy flowControlStrategy)
- {
- // TODO this should probably be an aggregate lifecycle
- this.version = version;
- this.bufferPool = bufferPool;
- this.scheduler = scheduler;
- this.controller = controller;
- this.endPoint = endPoint;
- this.idleListener = idleListener;
- this.streamIds = new AtomicInteger(initialStreamId);
- this.pingIds = new AtomicInteger(initialStreamId);
- this.listener = listener;
- this.generator = generator;
- this.flowControlStrategy = flowControlStrategy;
- this.flusher = new Flusher(controller);
- }
-
- @Override
- public short getVersion()
- {
- return version;
- }
-
- @Override
- public void addListener(Listener listener)
- {
- listeners.add(listener);
- }
-
- @Override
- public void removeListener(Listener listener)
- {
- listeners.remove(listener);
- }
-
- @Override
- public Stream syn(SynInfo synInfo, StreamFrameListener listener) throws ExecutionException, InterruptedException, TimeoutException
- {
- FuturePromise<Stream> result = new FuturePromise<>();
- syn(synInfo, listener, result);
- if (synInfo.getTimeout() > 0)
- return result.get(synInfo.getTimeout(), synInfo.getUnit());
- else
- return result.get();
- }
-
- @Override
- public void syn(SynInfo synInfo, StreamFrameListener listener, Promise<Stream> promise)
- {
- // Synchronization is necessary.
- // SPEC v3, 2.3.1 requires that the stream creation be monotonically crescent
- // so we cannot allow thread1 to create stream1 and thread2 create stream3 and
- // have stream3 hit the network before stream1, not only to comply with the spec
- // but also because the compression context for the headers would be wrong, as the
- // frame with a compression history will come before the first compressed frame.
- int associatedStreamId = 0;
- if (synInfo instanceof PushSynInfo)
- associatedStreamId = ((PushSynInfo)synInfo).getAssociatedStreamId();
-
- synchronized (this)
- {
- int streamId = streamIds.getAndAdd(2);
- // TODO: for SPDYv3 we need to support the "slot" argument
- SynStreamFrame synStream = new SynStreamFrame(version, synInfo.getFlags(), streamId, associatedStreamId, synInfo.getPriority(), (short)0, synInfo.getHeaders());
- IStream stream = createStream(synStream, listener, true, promise);
- if (stream == null)
- return;
- generateAndEnqueueControlFrame(stream, synStream, synInfo.getTimeout(), synInfo.getUnit(), stream);
- }
- }
-
- @Override
- public void rst(RstInfo rstInfo) throws InterruptedException, ExecutionException, TimeoutException
- {
- FutureCallback result = new FutureCallback();
- rst(rstInfo, result);
- if (rstInfo.getTimeout() > 0)
- result.get(rstInfo.getTimeout(), rstInfo.getUnit());
- else
- result.get();
- }
-
- @Override
- public void rst(RstInfo rstInfo, Callback callback)
- {
- // SPEC v3, 2.2.2
- if (goAwaySent.get())
- {
- complete(callback);
- }
- else
- {
- int streamId = rstInfo.getStreamId();
- IStream stream = streams.get(streamId);
- RstStreamFrame frame = new RstStreamFrame(version, streamId, rstInfo.getStreamStatus().getCode(version));
- control(stream, frame, rstInfo.getTimeout(), rstInfo.getUnit(), callback);
- if (stream != null)
- {
- stream.process(frame);
- flusher.removeFrameBytesFromQueue(stream);
- removeStream(stream);
- }
- }
- }
-
- @Override
- public void settings(SettingsInfo settingsInfo) throws ExecutionException, InterruptedException, TimeoutException
- {
- FutureCallback result = new FutureCallback();
- settings(settingsInfo, result);
- if (settingsInfo.getTimeout() > 0)
- result.get(settingsInfo.getTimeout(), settingsInfo.getUnit());
- else
- result.get();
- }
-
- @Override
- public void settings(SettingsInfo settingsInfo, Callback callback)
- {
- SettingsFrame frame = new SettingsFrame(version, settingsInfo.getFlags(), settingsInfo.getSettings());
- control(null, frame, settingsInfo.getTimeout(), settingsInfo.getUnit(), callback);
- }
-
- @Override
- public PingResultInfo ping(PingInfo pingInfo) throws ExecutionException, InterruptedException, TimeoutException
- {
- FuturePromise<PingResultInfo> result = new FuturePromise<>();
- ping(pingInfo, result);
- if (pingInfo.getTimeout() > 0)
- return result.get(pingInfo.getTimeout(), pingInfo.getUnit());
- else
- return result.get();
- }
-
- @Override
- public void ping(PingInfo pingInfo, Promise<PingResultInfo> promise)
- {
- int pingId = pingIds.getAndAdd(2);
- PingInfoCallback pingInfoCallback = new PingInfoCallback(pingId, promise);
- PingFrame frame = new PingFrame(version, pingId);
- control(null, frame, pingInfo.getTimeout(), pingInfo.getUnit(), pingInfoCallback);
- }
-
- @Override
- public void goAway(GoAwayInfo goAwayInfo) throws ExecutionException, InterruptedException, TimeoutException
- {
- goAway(goAwayInfo, SessionStatus.OK);
- }
-
- private void goAway(GoAwayInfo goAwayInfo, SessionStatus sessionStatus) throws ExecutionException, InterruptedException, TimeoutException
- {
- FutureCallback result = new FutureCallback();
- goAway(sessionStatus, goAwayInfo.getTimeout(), goAwayInfo.getUnit(), result);
- if (goAwayInfo.getTimeout() > 0)
- result.get(goAwayInfo.getTimeout(), goAwayInfo.getUnit());
- else
- result.get();
- }
-
- @Override
- public void goAway(GoAwayInfo goAwayInfo, Callback callback)
- {
- goAway(SessionStatus.OK, goAwayInfo.getTimeout(), goAwayInfo.getUnit(), callback);
- }
-
- private void goAway(SessionStatus sessionStatus, long timeout, TimeUnit unit, Callback callback)
- {
- if (goAwaySent.compareAndSet(false, true))
- {
- if (!goAwayReceived.get())
- {
- GoAwayFrame frame = new GoAwayFrame(version, lastStreamId.get(), sessionStatus.getCode());
- control(null, frame, timeout, unit, callback);
- return;
- }
- }
- complete(callback);
- }
-
- @Override
- public Set<Stream> getStreams()
- {
- Set<Stream> result = new HashSet<>();
- result.addAll(streams.values());
- return result;
- }
-
- @Override
- public IStream getStream(int streamId)
- {
- return streams.get(streamId);
- }
-
- @Override
- public Object getAttribute(String key)
- {
- return attributes.get(key);
- }
-
- @Override
- public void setAttribute(String key, Object value)
- {
- attributes.put(key, value);
- }
-
- @Override
- public Object removeAttribute(String key)
- {
- return attributes.remove(key);
- }
-
- @Override
- public InetSocketAddress getLocalAddress()
- {
- return endPoint.getLocalAddress();
- }
-
- @Override
- public InetSocketAddress getRemoteAddress()
- {
- return endPoint.getRemoteAddress();
- }
-
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- notifyIdle(idleListener, false);
- try
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Processing {}", frame);
-
- if (goAwaySent.get())
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Skipped processing of {}", frame);
- return;
- }
-
- switch (frame.getType())
- {
- case SYN_STREAM:
- {
- onSyn((SynStreamFrame)frame);
- break;
- }
- case SYN_REPLY:
- {
- onReply((SynReplyFrame)frame);
- break;
- }
- case RST_STREAM:
- {
- onRst((RstStreamFrame)frame);
- break;
- }
- case SETTINGS:
- {
- onSettings((SettingsFrame)frame);
- break;
- }
- case NOOP:
- {
- // Just ignore it
- break;
- }
- case PING:
- {
- onPing((PingFrame)frame);
- break;
- }
- case GO_AWAY:
- {
- onGoAway((GoAwayFrame)frame);
- break;
- }
- case HEADERS:
- {
- onHeaders((HeadersFrame)frame);
- break;
- }
- case WINDOW_UPDATE:
- {
- onWindowUpdate((WindowUpdateFrame)frame);
- break;
- }
- case CREDENTIAL:
- {
- onCredential((CredentialFrame)frame);
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- finally
- {
- notifyIdle(idleListener, true);
- }
- }
-
- @Override
- public void onDataFrame(DataFrame frame, ByteBuffer data)
- {
- notifyIdle(idleListener, false);
- try
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Processing {}, {} data bytes", frame, data.remaining());
-
- if (goAwaySent.get())
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Skipped processing of {}", frame);
- return;
- }
-
- int streamId = frame.getStreamId();
- IStream stream = streams.get(streamId);
- if (stream == null)
- {
- RstInfo rstInfo = new RstInfo(streamId, StreamStatus.INVALID_STREAM);
- if (LOG.isDebugEnabled())
- LOG.debug("Unknown stream {}", rstInfo);
- rst(rstInfo, Callback.Adapter.INSTANCE);
- }
- else
- {
- processData(stream, frame, data);
- }
- }
- finally
- {
- notifyIdle(idleListener, true);
- }
- }
-
- private void notifyIdle(IdleListener listener, boolean idle)
- {
- if (listener != null)
- listener.onIdle(idle);
- }
-
- private void processData(final IStream stream, DataFrame frame, ByteBuffer data)
- {
- ByteBufferDataInfo dataInfo = new ByteBufferDataInfo(data, frame.isClose())
- {
- @Override
- public void consume(int delta)
- {
- super.consume(delta);
- flowControlStrategy.onDataConsumed(StandardSession.this, stream, this, delta);
- }
- };
- flowControlStrategy.onDataReceived(this, stream, dataInfo);
- stream.process(dataInfo);
- if (stream.isClosed())
- removeStream(stream);
- }
-
- @Override
- public void onStreamException(StreamException x)
- {
- notifyOnFailure(listener, x); // TODO: notify StreamFrameListener if exists?
- rst(new RstInfo(x.getStreamId(), x.getStreamStatus()), Callback.Adapter.INSTANCE);
- }
-
- @Override
- public void onSessionException(SessionException x)
- {
- Throwable cause = x.getCause();
- notifyOnFailure(listener, cause == null ? x : cause);
- goAway(x.getSessionStatus(), 0, TimeUnit.SECONDS, Callback.Adapter.INSTANCE);
- }
-
- private void onSyn(final SynStreamFrame frame)
- {
- IStream stream = createStream(frame, null, false, new Promise.Adapter<Stream>()
- {
- @Override
- public void failed(Throwable x)
- {
- LOG.debug("Received: {} but creating new Stream failed: {}", frame, x.getMessage());
- }
- });
- if (stream != null)
- processSyn(listener, stream, frame);
- }
-
- private void processSyn(SessionFrameListener listener, IStream stream, SynStreamFrame frame)
- {
- stream.process(frame);
- // Update the last stream id before calling the application (which may send a GO_AWAY)
- updateLastStreamId(stream);
- StreamFrameListener streamListener;
- if (stream.isUnidirectional())
- {
- PushInfo pushInfo = new PushInfo(frame.getHeaders(), frame.isClose());
- streamListener = notifyOnPush(stream.getAssociatedStream().getStreamFrameListener(), stream, pushInfo);
- }
- else
- {
- SynInfo synInfo = new SynInfo(frame.getHeaders(), frame.isClose(), frame.getPriority());
- streamListener = notifyOnSyn(listener, stream, synInfo);
- }
- stream.setStreamFrameListener(streamListener);
- // The onSyn() listener may have sent a frame that closed the stream
- if (stream.isClosed())
- removeStream(stream);
- }
-
- private IStream createStream(SynStreamFrame frame, StreamFrameListener listener, boolean local, Promise<Stream> promise)
- {
- IStream associatedStream = streams.get(frame.getAssociatedStreamId());
- IStream stream = new StandardStream(frame.getStreamId(), frame.getPriority(), this, associatedStream,
- scheduler, promise);
- stream.setIdleTimeout(endPoint.getIdleTimeout());
- flowControlStrategy.onNewStream(this, stream);
-
- stream.updateCloseState(frame.isClose(), local);
- stream.setStreamFrameListener(listener);
-
- if (stream.isUnidirectional())
- {
- // Unidirectional streams are implicitly half closed
- stream.updateCloseState(true, !local);
- if (!stream.isClosed())
- stream.getAssociatedStream().associate(stream);
- }
-
- int streamId = stream.getId();
-
- if (local)
- {
- while (true)
- {
- int oldStreamCountValue = localStreamCount.get();
- int maxConcurrentStreams = maxConcurrentLocalStreams;
- if (maxConcurrentStreams > -1 && oldStreamCountValue >= maxConcurrentStreams)
- {
- String message = String.format("Max concurrent local streams (%d) exceeded.",
- maxConcurrentStreams);
- LOG.debug(message);
- promise.failed(new SPDYException(message));
- return null;
- }
- if (localStreamCount.compareAndSet(oldStreamCountValue, oldStreamCountValue + 1))
- break;
- }
- }
-
- if (streams.putIfAbsent(streamId, stream) != null)
- {
- String message = "Duplicate stream id " + streamId;
- IllegalStateException duplicateIdException = new IllegalStateException(message);
- promise.failed(duplicateIdException);
- if (local)
- {
- localStreamCount.decrementAndGet();
- throw duplicateIdException;
- }
- RstInfo rstInfo = new RstInfo(streamId, StreamStatus.PROTOCOL_ERROR);
- if (LOG.isDebugEnabled())
- LOG.debug("Duplicate stream, {}", rstInfo);
- rst(rstInfo, Callback.Adapter.INSTANCE); // We don't care (too much) if the reset fails.
- return null;
- }
- else
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Created {}", stream);
- notifyStreamCreated(stream);
- return stream;
- }
- }
-
- private void notifyStreamCreated(IStream stream)
- {
- for (Listener listener : listeners)
- {
- if (listener instanceof StreamListener)
- {
- try
- {
- ((StreamListener)listener).onStreamCreated(stream);
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
- }
- }
-
- private void removeStream(IStream stream)
- {
- if (stream.isUnidirectional())
- stream.getAssociatedStream().disassociate(stream);
-
- IStream removed = streams.remove(stream.getId());
- if (removed != null)
- {
- assert removed == stream;
-
- if (streamIds.get() % 2 == stream.getId() % 2)
- localStreamCount.decrementAndGet();
-
- if (LOG.isDebugEnabled())
- LOG.debug("Removed {}", stream);
- notifyStreamClosed(stream);
- }
- }
-
- private void notifyStreamClosed(IStream stream)
- {
- for (Listener listener : listeners)
- {
- if (listener instanceof StreamListener)
- {
- try
- {
- ((StreamListener)listener).onStreamClosed(stream);
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
- }
- }
-
- private void onReply(SynReplyFrame frame)
- {
- int streamId = frame.getStreamId();
- IStream stream = streams.get(streamId);
- if (stream == null)
- {
- RstInfo rstInfo = new RstInfo(streamId, StreamStatus.INVALID_STREAM);
- if (LOG.isDebugEnabled())
- LOG.debug("Unknown stream {}", rstInfo);
- rst(rstInfo, Callback.Adapter.INSTANCE);
- }
- else
- {
- processReply(stream, frame);
- }
- }
-
- private void processReply(IStream stream, SynReplyFrame frame)
- {
- stream.process(frame);
- if (stream.isClosed())
- removeStream(stream);
- }
-
- private void onRst(RstStreamFrame frame)
- {
- IStream stream = streams.get(frame.getStreamId());
-
- if (stream != null)
- stream.process(frame);
-
- RstInfo rstInfo = new RstInfo(frame.getStreamId(), StreamStatus.from(frame.getVersion(), frame.getStatusCode()));
- notifyOnRst(listener, rstInfo);
-
- if (stream != null)
- removeStream(stream);
- }
-
- private void onSettings(SettingsFrame frame)
- {
- Settings.Setting windowSizeSetting = frame.getSettings().get(Settings.ID.INITIAL_WINDOW_SIZE);
- if (windowSizeSetting != null)
- {
- int windowSize = windowSizeSetting.value();
- setWindowSize(windowSize);
- if (LOG.isDebugEnabled())
- LOG.debug("Updated session window size to {}", windowSize);
- }
- Settings.Setting maxConcurrentStreamsSetting = frame.getSettings().get(Settings.ID.MAX_CONCURRENT_STREAMS);
- if (maxConcurrentStreamsSetting != null)
- {
- int maxConcurrentStreamsValue = maxConcurrentStreamsSetting.value();
- maxConcurrentLocalStreams = maxConcurrentStreamsValue;
- if (LOG.isDebugEnabled())
- LOG.debug("Updated session maxConcurrentLocalStreams to {}", maxConcurrentStreamsValue);
- }
- SettingsInfo settingsInfo = new SettingsInfo(frame.getSettings(), frame.isClearPersisted());
- notifyOnSettings(listener, settingsInfo);
- }
-
- private void onPing(PingFrame frame)
- {
- int pingId = frame.getPingId();
- if (pingId % 2 == pingIds.get() % 2)
- {
- PingResultInfo pingResultInfo = new PingResultInfo(frame.getPingId());
- notifyOnPing(listener, pingResultInfo);
- }
- else
- {
- control(null, frame, 0, TimeUnit.MILLISECONDS, Callback.Adapter.INSTANCE);
- }
- }
-
- private void onGoAway(GoAwayFrame frame)
- {
- if (goAwayReceived.compareAndSet(false, true))
- {
- GoAwayResultInfo goAwayResultInfo = new GoAwayResultInfo(frame.getLastStreamId(), SessionStatus.from(frame.getStatusCode()));
- notifyOnGoAway(listener, goAwayResultInfo);
- // SPDY does not require to send back a response to a GO_AWAY.
- // We notified the application of the last good stream id and
- // tried our best to flush remaining data.
- }
- }
-
- private void onHeaders(HeadersFrame frame)
- {
- int streamId = frame.getStreamId();
- IStream stream = streams.get(streamId);
- if (stream == null)
- {
- RstInfo rstInfo = new RstInfo(streamId, StreamStatus.INVALID_STREAM);
- if (LOG.isDebugEnabled())
- LOG.debug("Unknown stream, {}", rstInfo);
- rst(rstInfo, Callback.Adapter.INSTANCE);
- }
- else
- {
- processHeaders(stream, frame);
- }
- }
-
- private void processHeaders(IStream stream, HeadersFrame frame)
- {
- stream.process(frame);
- if (stream.isClosed())
- removeStream(stream);
- }
-
- private void onWindowUpdate(WindowUpdateFrame frame)
- {
- int streamId = frame.getStreamId();
- IStream stream = streams.get(streamId);
- flowControlStrategy.onWindowUpdate(this, stream, frame.getWindowDelta());
- flusher.flush();
- }
-
- private void onCredential(CredentialFrame frame)
- {
- LOG.warn("{} frame not yet supported", frame.getType());
- }
-
- protected void close()
- {
- // Check for null to support tests
- if (controller != null)
- controller.close(false);
- }
-
- private void notifyOnFailure(SessionFrameListener listener, Throwable x)
- {
- try
- {
- if (listener != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Invoking callback with {} on listener {}", x, listener);
- listener.onFailure(this, x);
- }
- }
- catch (Exception xx)
- {
- LOG.info("Exception while notifying listener " + listener, xx);
- }
- catch (Error xx)
- {
- LOG.info("Exception while notifying listener " + listener, xx);
- throw xx;
- }
- }
-
- private StreamFrameListener notifyOnPush(StreamFrameListener listener, Stream stream, PushInfo pushInfo)
- {
- try
- {
- if (listener == null)
- return null;
- if (LOG.isDebugEnabled())
- LOG.debug("Invoking callback with {} on listener {}", pushInfo, listener);
- return listener.onPush(stream, pushInfo);
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- return null;
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
-
- private StreamFrameListener notifyOnSyn(SessionFrameListener listener, Stream stream, SynInfo synInfo)
- {
- try
- {
- if (listener == null)
- return null;
- if (LOG.isDebugEnabled())
- LOG.debug("Invoking callback with {} on listener {}", synInfo, listener);
- return listener.onSyn(stream, synInfo);
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- return null;
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
-
- private void notifyOnRst(SessionFrameListener listener, RstInfo rstInfo)
- {
- try
- {
- if (listener != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Invoking callback with {} on listener {}", rstInfo, listener);
- listener.onRst(this, rstInfo);
- }
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
-
- private void notifyOnSettings(SessionFrameListener listener, SettingsInfo settingsInfo)
- {
- try
- {
- if (listener != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Invoking callback with {} on listener {}", settingsInfo, listener);
- listener.onSettings(this, settingsInfo);
- }
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
-
- private void notifyOnPing(SessionFrameListener listener, PingResultInfo pingResultInfo)
- {
- try
- {
- if (listener != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Invoking callback with {} on listener {}", pingResultInfo, listener);
- listener.onPing(this, pingResultInfo);
- }
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
-
- private void notifyOnGoAway(SessionFrameListener listener, GoAwayResultInfo goAwayResultInfo)
- {
- try
- {
- if (listener != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Invoking callback with {} on listener {}", goAwayResultInfo, listener);
- listener.onGoAway(this, goAwayResultInfo);
- }
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
-
- @Override
- public void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback callback)
- {
- generateAndEnqueueControlFrame(stream, frame, timeout, unit, callback);
- }
-
- private void generateAndEnqueueControlFrame(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback callback)
- {
- try
- {
- // Synchronization is necessary, since we may have concurrent replies
- // and those needs to be generated and enqueued atomically in order
- // to maintain a correct compression context
- ControlFrameBytes frameBytes;
- Throwable throwable;
- synchronized (this)
- {
- ByteBuffer buffer = generator.control(frame);
- if (LOG.isDebugEnabled())
- LOG.debug("Queuing {} on {}", frame, stream);
- frameBytes = new ControlFrameBytes(stream, callback, frame, buffer);
- if (timeout > 0)
- frameBytes.task = scheduler.schedule(frameBytes, timeout, unit);
-
- // Special handling for PING frames, they must be sent as soon as possible
- if (ControlFrameType.PING == frame.getType())
- throwable = flusher.prepend(frameBytes);
- else
- throwable = flusher.append(frameBytes);
- }
- // Flush MUST be done outside synchronized blocks
- flush(frameBytes, throwable);
- }
- catch (Exception x)
- {
- notifyCallbackFailed(callback, x);
- }
- }
-
- private void updateLastStreamId(IStream stream)
- {
- int streamId = stream.getId();
- if (streamId % 2 != streamIds.get() % 2)
- Atomics.updateMax(lastStreamId, streamId);
- }
-
- @Override
- public void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Callback callback)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Queuing {} on {}", dataInfo, stream);
- DataFrameBytes frameBytes = new DataFrameBytes(stream, callback, dataInfo);
- if (timeout > 0)
- frameBytes.task = scheduler.schedule(frameBytes, timeout, unit);
- flush(frameBytes, flusher.append(frameBytes));
- }
-
- @Override
- public void shutdown()
- {
- CloseFrameBytes frameBytes = new CloseFrameBytes();
- flush(frameBytes, flusher.append(frameBytes));
- }
-
- private void flush(FrameBytes frameBytes, Throwable throwable)
- {
- if (throwable != null)
- frameBytes.failed(throwable);
- else
- flusher.flush();
- }
-
- private void complete(final Callback callback)
- {
- try
- {
- if (callback != null)
- callback.succeeded();
- }
- catch (Throwable x)
- {
- LOG.info("Exception while notifying callback " + callback, x);
- }
- }
-
- private void notifyCallbackFailed(Callback callback, Throwable failure)
- {
- try
- {
- if (callback != null)
- callback.failed(failure);
- }
- catch (Throwable x)
- {
- LOG.info("Exception while notifying callback " + callback, x);
- }
- }
-
- public int getWindowSize()
- {
- return flowControlStrategy.getWindowSize(this);
- }
-
- public void setWindowSize(int initialWindowSize)
- {
- flowControlStrategy.setWindowSize(this, initialWindowSize);
- }
-
- @Override
- public String toString()
- {
- return String.format("%s@%x{v%d,queueSize=%d,windowSize=%d,streams=%d}", getClass().getSimpleName(),
- hashCode(), version, flusher.getQueueSize(), getWindowSize(), streams.size());
- }
-
- @Override
- public String dump()
- {
- return ContainerLifeCycle.dump(this);
- }
-
- @Override
- public void dump(Appendable out, String indent) throws IOException
- {
- ContainerLifeCycle.dumpObject(out, this);
- ContainerLifeCycle.dump(out, indent, Collections.singletonList(controller), streams.values());
- }
-
- public interface FrameBytes extends Comparable<FrameBytes>, Callback
- {
- public IStream getStream();
-
- public abstract ByteBuffer getByteBuffer();
- }
-
- abstract class AbstractFrameBytes implements FrameBytes, Runnable
- {
- private final IStream stream;
- private final Callback callback;
- protected volatile Scheduler.Task task;
-
- protected AbstractFrameBytes(IStream stream, Callback callback)
- {
- this.stream = stream;
- this.callback = Objects.requireNonNull(callback);
- }
-
- @Override
- public IStream getStream()
- {
- return stream;
- }
-
- @Override
- public int compareTo(FrameBytes that)
- {
- // FrameBytes may have or not have a related stream (for example, PING do not have a related stream)
- // FrameBytes without related streams have higher priority
- IStream thisStream = getStream();
- IStream thatStream = that.getStream();
- if (thisStream == null)
- return thatStream == null ? 0 : -1;
- if (thatStream == null)
- return 1;
- // If this.stream.priority > that.stream.priority => this.stream has less priority than that.stream
- return thatStream.getPriority() - thisStream.getPriority();
- }
-
- private void cancelTask()
- {
- Scheduler.Task task = this.task;
- if (task != null)
- task.cancel();
- }
-
- @Override
- public void run()
- {
- close();
- failed(new InterruptedByTimeoutException());
- }
-
- @Override
- public void succeeded()
- {
- cancelTask();
- StandardSession.this.complete(callback);
- }
-
- @Override
- public void failed(Throwable x)
- {
- cancelTask();
- notifyCallbackFailed(callback, x);
- }
- }
-
- protected class ControlFrameBytes extends AbstractFrameBytes
- {
- private final ControlFrame frame;
- private final ByteBuffer buffer;
-
- private ControlFrameBytes(IStream stream, Callback callback, ControlFrame frame, ByteBuffer buffer)
- {
- super(stream, callback);
- this.frame = frame;
- this.buffer = buffer;
- }
-
- @Override
- public ByteBuffer getByteBuffer()
- {
- return buffer;
- }
-
- @Override
- public void succeeded()
- {
- bufferPool.release(buffer);
-
- super.succeeded();
-
- if (frame.getType() == ControlFrameType.GO_AWAY)
- {
- // After sending a GO_AWAY we need to hard close the connection.
- // Recipients will know the last good stream id and act accordingly.
- close();
- }
- IStream stream = getStream();
- if (stream != null && stream.isClosed())
- removeStream(stream);
- }
-
- @Override
- public String toString()
- {
- return frame.toString();
- }
- }
-
- protected class DataFrameBytes extends AbstractFrameBytes
- {
- private final DataInfo dataInfo;
- private int size;
- private volatile ByteBuffer buffer;
-
- private DataFrameBytes(IStream stream, Callback handler, DataInfo dataInfo)
- {
- super(stream, handler);
- this.dataInfo = dataInfo;
- }
-
- @Override
- public ByteBuffer getByteBuffer()
- {
- try
- {
- IStream stream = getStream();
- int windowSize = stream.getWindowSize();
-
- // TODO: optimization
- // Right now, we use the windowSize to chunk big buffers.
- // However, if the window size is large, we may congest the
- // connection, or favor one stream that does a big download,
- // starving the other streams.
- // Also, SPDY DATA frames have a maximum of 16 MiB size, which
- // is not enforced here.
- // We should have a configurable "preferredDataFrameSize"
- // (or even better autotuning) that will allow to send chunks
- // that will not starve other streams and small enough to
- // not congest the connection, while avoiding to send too many
- // TCP packets.
- // See also comment in class Flusher.
-
- size = dataInfo.available();
- if (size > windowSize)
- size = windowSize;
-
- buffer = generator.data(stream.getId(), size, dataInfo);
- return buffer;
- }
- catch (Throwable x)
- {
- failed(x);
- return null;
- }
- }
-
- @Override
- public void succeeded()
- {
- bufferPool.release(buffer);
- IStream stream = getStream();
- dataInfo.consume(size);
- flowControlStrategy.updateWindow(StandardSession.this, stream, -size);
- if (dataInfo.available() > 0)
- {
- // We have written a frame out of this DataInfo, but there is more to write.
- // We need to keep the correct ordering of frames, to avoid that another
- // DataInfo for the same stream is written before this one is finished.
- flush(this, flusher.prepend(this));
- }
- else
- {
- super.succeeded();
- stream.updateCloseState(dataInfo.isClose(), true);
- if (stream.isClosed())
- removeStream(stream);
- }
- }
-
- @Override
- public String toString()
- {
- return String.format("DATA bytes @%x available=%d consumed=%d on %s", dataInfo.hashCode(), dataInfo.available(), dataInfo.consumed(), getStream());
- }
- }
-
- protected class CloseFrameBytes extends AbstractFrameBytes
- {
- private CloseFrameBytes()
- {
- super(null, Callback.Adapter.INSTANCE);
- }
-
- @Override
- public ByteBuffer getByteBuffer()
- {
- return BufferUtil.EMPTY_BUFFER;
- }
-
- @Override
- public void succeeded()
- {
- super.succeeded();
- close();
- }
- }
-
- private static class PingInfoCallback extends PingResultInfo implements Callback
- {
- private final Promise<PingResultInfo> promise;
-
- public PingInfoCallback(int pingId, Promise<PingResultInfo> promise)
- {
- super(pingId);
- this.promise = promise;
- }
-
- @Override
- public void succeeded()
- {
- if (promise != null)
- promise.succeeded(this);
- }
-
- @Override
- public void failed(Throwable x)
- {
- if (promise != null)
- promise.failed(x);
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java
deleted file mode 100644
index e5f5641e8a..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java
+++ /dev/null
@@ -1,602 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.eclipse.jetty.io.IdleTimeout;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.HeadersFrame;
-import org.eclipse.jetty.spdy.frames.SynReplyFrame;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.FutureCallback;
-import org.eclipse.jetty.util.FuturePromise;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.Scheduler;
-
-public class StandardStream extends IdleTimeout implements IStream
-{
- private static final Logger LOG = Log.getLogger(Stream.class);
- private final Map<String, Object> attributes = new ConcurrentHashMap<>();
- private final int id;
- private final byte priority;
- private final ISession session;
- private final IStream associatedStream;
- private final Promise<Stream> promise;
- private final AtomicInteger windowSize = new AtomicInteger();
- private final Set<Stream> pushedStreams = Collections.newSetFromMap(new ConcurrentHashMap<Stream, Boolean>());
- private volatile StreamFrameListener listener;
- private volatile OpenState openState = OpenState.SYN_SENT;
- private volatile CloseState closeState = CloseState.OPENED;
- private volatile boolean reset = false;
-
- public StandardStream(int id, byte priority, ISession session, IStream associatedStream, Scheduler scheduler, Promise<Stream> promise)
- {
- super(scheduler);
- this.id = id;
- this.priority = priority;
- this.session = session;
- this.associatedStream = associatedStream;
- this.promise = promise;
- }
-
- @Override
- public int getId()
- {
- return id;
- }
-
- @Override
- public IStream getAssociatedStream()
- {
- return associatedStream;
- }
-
- @Override
- public Set<Stream> getPushedStreams()
- {
- return pushedStreams;
- }
-
- @Override
- public void associate(IStream stream)
- {
- pushedStreams.add(stream);
- }
-
- @Override
- public void disassociate(IStream stream)
- {
- pushedStreams.remove(stream);
- }
-
- @Override
- public byte getPriority()
- {
- return priority;
- }
-
- @Override
- protected void onIdleExpired(TimeoutException timeout)
- {
- StreamFrameListener listener = this.listener;
- if (listener != null)
- listener.onFailure(this, timeout);
- // The stream is now gone, we must close it to
- // avoid that its idle timeout is rescheduled.
- close();
- }
-
- private void close()
- {
- closeState = CloseState.CLOSED;
- onClose();
- }
-
- @Override
- public boolean isOpen()
- {
- return !isClosed();
- }
-
- @Override
- public int getWindowSize()
- {
- return windowSize.get();
- }
-
- @Override
- public void updateWindowSize(int delta)
- {
- int size = windowSize.addAndGet(delta);
- if (LOG.isDebugEnabled())
- LOG.debug("Updated window size {} -> {} for {}", size - delta, size, this);
- }
-
- @Override
- public ISession getSession()
- {
- return session;
- }
-
- @Override
- public Object getAttribute(String key)
- {
- return attributes.get(key);
- }
-
- @Override
- public void setAttribute(String key, Object value)
- {
- attributes.put(key, value);
- }
-
- @Override
- public Object removeAttribute(String key)
- {
- return attributes.remove(key);
- }
-
- @Override
- public void setStreamFrameListener(StreamFrameListener listener)
- {
- this.listener = listener;
- }
-
- @Override
- public StreamFrameListener getStreamFrameListener()
- {
- return listener;
- }
-
- @Override
- public void updateCloseState(boolean close, boolean local)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("{} close={} local={}", this, close, local);
- if (close)
- {
- switch (closeState)
- {
- case OPENED:
- {
- closeState = local ? CloseState.LOCALLY_CLOSED : CloseState.REMOTELY_CLOSED;
- break;
- }
- case LOCALLY_CLOSED:
- {
- if (local)
- throw new IllegalStateException();
- else
- close();
- break;
- }
- case REMOTELY_CLOSED:
- {
- if (local)
- close();
- else
- throw new IllegalStateException();
- break;
- }
- default:
- {
- LOG.warn("Already CLOSED! {} local={}", this, local);
- }
- }
- }
- }
-
- @Override
- public void process(ControlFrame frame)
- {
- notIdle();
- switch (frame.getType())
- {
- case SYN_STREAM:
- {
- openState = OpenState.SYN_RECV;
- break;
- }
- case SYN_REPLY:
- {
- openState = OpenState.REPLY_RECV;
- SynReplyFrame synReply = (SynReplyFrame)frame;
- updateCloseState(synReply.isClose(), false);
- ReplyInfo replyInfo = new ReplyInfo(synReply.getHeaders(), synReply.isClose());
- notifyOnReply(replyInfo);
- break;
- }
- case HEADERS:
- {
- HeadersFrame headers = (HeadersFrame)frame;
- updateCloseState(headers.isClose(), false);
- HeadersInfo headersInfo = new HeadersInfo(headers.getHeaders(), headers.isClose(), headers.isResetCompression());
- notifyOnHeaders(headersInfo);
- break;
- }
- case RST_STREAM:
- {
- reset = true;
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
-
- @Override
- public void process(DataInfo dataInfo)
- {
- notIdle();
- // TODO: in v3 we need to send a rst instead of just ignoring
- // ignore data frame if this stream is remotelyClosed already
- if (isRemotelyClosed())
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Stream is remotely closed, ignoring {}", dataInfo);
- return;
- }
-
- if (!canReceive())
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Protocol error receiving {}, resetting", dataInfo);
- session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR), Callback.Adapter.INSTANCE);
- return;
- }
-
- updateCloseState(dataInfo.isClose(), false);
- notifyOnData(dataInfo);
- }
-
- @Override
- public void succeeded()
- {
- if (promise != null)
- promise.succeeded(this);
- }
-
- @Override
- public void failed(Throwable x)
- {
- if (promise != null)
- promise.failed(x);
- }
-
- private void notifyOnReply(ReplyInfo replyInfo)
- {
- final StreamFrameListener listener = this.listener;
- try
- {
- if (listener != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Invoking reply callback with {} on listener {}", replyInfo, listener);
- listener.onReply(this, replyInfo);
- }
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
-
- private void notifyOnHeaders(HeadersInfo headersInfo)
- {
- final StreamFrameListener listener = this.listener;
- try
- {
- if (listener != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Invoking headers callback with {} on listener {}", headersInfo, listener);
- listener.onHeaders(this, headersInfo);
- }
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
-
- private void notifyOnData(DataInfo dataInfo)
- {
- final StreamFrameListener listener = this.listener;
- try
- {
- if (listener != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Invoking data callback with {} on listener {}", dataInfo, listener);
- listener.onData(this, dataInfo);
- if (LOG.isDebugEnabled())
- LOG.debug("Invoked data callback with {} on listener {}", dataInfo, listener);
- }
- }
- catch (Exception x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- }
- catch (Error x)
- {
- LOG.info("Exception while notifying listener " + listener, x);
- throw x;
- }
- }
-
- @Override
- public Stream push(PushInfo pushInfo) throws InterruptedException, ExecutionException, TimeoutException
- {
- FuturePromise<Stream> result = new FuturePromise<>();
- push(pushInfo, result);
- if (pushInfo.getTimeout() > 0)
- return result.get(pushInfo.getTimeout(), pushInfo.getUnit());
- else
- return result.get();
- }
-
- @Override
- public void push(PushInfo pushInfo, Promise<Stream> promise)
- {
- notIdle();
- if (isClosed() || isReset())
- {
- close();
- promise.failed(new StreamException(getId(), StreamStatus.STREAM_ALREADY_CLOSED,
- "Stream: " + this + " already closed or reset!"));
- return;
- }
- PushSynInfo pushSynInfo = new PushSynInfo(getId(), pushInfo);
- session.syn(pushSynInfo, null, new StreamPromise(promise));
- }
-
- @Override
- public void reply(ReplyInfo replyInfo) throws InterruptedException, ExecutionException, TimeoutException
- {
- FutureCallback result = new FutureCallback();
- reply(replyInfo, result);
- if (replyInfo.getTimeout() > 0)
- result.get(replyInfo.getTimeout(), replyInfo.getUnit());
- else
- result.get();
- }
-
- @Override
- public void reply(ReplyInfo replyInfo, Callback callback)
- {
- notIdle();
- if (isUnidirectional())
- {
- close();
- throw new IllegalStateException("Protocol violation: cannot send SYN_REPLY frames in unidirectional streams");
- }
- openState = OpenState.REPLY_SENT;
- updateCloseState(replyInfo.isClose(), true);
- SynReplyFrame frame = new SynReplyFrame(session.getVersion(), replyInfo.getFlags(), getId(), replyInfo.getHeaders());
- session.control(this, frame, replyInfo.getTimeout(), replyInfo.getUnit(), new StreamCallback(callback));
- }
-
- @Override
- public void data(DataInfo dataInfo) throws InterruptedException, ExecutionException, TimeoutException
- {
- FutureCallback result = new FutureCallback();
- data(dataInfo, result);
- if (dataInfo.getTimeout() > 0)
- result.get(dataInfo.getTimeout(), dataInfo.getUnit());
- else
- result.get();
- }
-
- @Override
- public void data(DataInfo dataInfo, Callback callback)
- {
- notIdle();
- if (!canSend())
- {
- session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR), new StreamCallback());
- throw new IllegalStateException("Protocol violation: cannot send a DATA frame before a SYN_REPLY frame");
- }
- if (isLocallyClosed())
- {
- session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR), new StreamCallback());
- throw new IllegalStateException("Protocol violation: cannot send a DATA frame on a locally closed stream");
- }
-
- // Cannot update the close state here, because the data that we send may
- // be flow controlled, so we need the stream to update the window size.
- session.data(this, dataInfo, dataInfo.getTimeout(), dataInfo.getUnit(), new StreamCallback(callback));
- }
-
- @Override
- public void headers(HeadersInfo headersInfo) throws InterruptedException, ExecutionException, TimeoutException
- {
- FutureCallback result = new FutureCallback();
- headers(headersInfo, result);
- if (headersInfo.getTimeout() > 0)
- result.get(headersInfo.getTimeout(), headersInfo.getUnit());
- else
- result.get();
- }
-
- @Override
- public void headers(HeadersInfo headersInfo, Callback callback)
- {
- notIdle();
- if (!canSend())
- {
- session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR), new StreamCallback());
- throw new IllegalStateException("Protocol violation: cannot send a HEADERS frame before a SYN_REPLY frame");
- }
- if (isLocallyClosed())
- {
- session.rst(new RstInfo(getId(), StreamStatus.PROTOCOL_ERROR), new StreamCallback());
- throw new IllegalStateException("Protocol violation: cannot send a HEADERS frame on a closed stream");
- }
-
- updateCloseState(headersInfo.isClose(), true);
- HeadersFrame frame = new HeadersFrame(session.getVersion(), headersInfo.getFlags(), getId(), headersInfo.getHeaders());
- session.control(this, frame, headersInfo.getTimeout(), headersInfo.getUnit(), new StreamCallback(callback));
- }
-
- @Override
- public boolean isUnidirectional()
- {
- return associatedStream != null;
- }
-
- @Override
- public boolean isReset()
- {
- return reset;
- }
-
- @Override
- public boolean isHalfClosed()
- {
- CloseState closeState = this.closeState;
- return closeState == CloseState.LOCALLY_CLOSED || closeState == CloseState.REMOTELY_CLOSED || closeState == CloseState.CLOSED;
- }
-
- @Override
- public boolean isClosed()
- {
- return closeState == CloseState.CLOSED;
- }
-
- private boolean isLocallyClosed()
- {
- CloseState closeState = this.closeState;
- return closeState == CloseState.LOCALLY_CLOSED || closeState == CloseState.CLOSED;
- }
-
- private boolean isRemotelyClosed()
- {
- CloseState closeState = this.closeState;
- return closeState == CloseState.REMOTELY_CLOSED || closeState == CloseState.CLOSED;
- }
-
- @Override
- public String toString()
- {
- return String.format("stream=%d v%d windowSize=%d reset=%s prio=%d %s %s", getId(), session.getVersion(),
- getWindowSize(), isReset(), priority, openState, closeState);
- }
-
- private boolean canSend()
- {
- OpenState openState = this.openState;
- return openState == OpenState.SYN_SENT || openState == OpenState.REPLY_RECV || openState == OpenState.REPLY_SENT;
- }
-
- private boolean canReceive()
- {
- OpenState openState = this.openState;
- return openState == OpenState.SYN_RECV || openState == OpenState.REPLY_RECV || openState == OpenState.REPLY_SENT;
- }
-
- private enum OpenState
- {
- SYN_SENT, SYN_RECV, REPLY_SENT, REPLY_RECV
- }
-
- private enum CloseState
- {
- OPENED, LOCALLY_CLOSED, REMOTELY_CLOSED, CLOSED
- }
-
- private class StreamCallback implements Callback
- {
- private final Callback callback;
-
- private StreamCallback()
- {
- this(Callback.Adapter.INSTANCE);
- }
-
- private StreamCallback(Callback callback)
- {
- this.callback = callback;
- }
-
- @Override
- public void succeeded()
- {
- callback.succeeded();
- }
-
- @Override
- public void failed(Throwable x)
- {
- close();
- callback.failed(x);
- }
- }
-
- private class StreamPromise implements Promise<Stream>
- {
- private final Promise<Stream> promise;
-
- public StreamPromise(Promise<Stream> promise)
- {
- this.promise = promise;
- }
-
- @Override
- public void succeeded(Stream result)
- {
- promise.succeeded(result);
- }
-
- @Override
- public void failed(Throwable x)
- {
- close();
- promise.failed(x);
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StreamException.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StreamException.java
deleted file mode 100644
index cb1c400219..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StreamException.java
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import org.eclipse.jetty.spdy.api.StreamStatus;
-
-public class StreamException extends RuntimeException
-{
- private final int streamId;
- private final StreamStatus streamStatus;
-
- public StreamException(int streamId, StreamStatus streamStatus)
- {
- this.streamId = streamId;
- this.streamStatus = streamStatus;
- }
-
- public StreamException(int streamId, StreamStatus streamStatus, String message)
- {
- super(message);
- this.streamId = streamId;
- this.streamStatus = streamStatus;
- }
-
- public int getStreamId()
- {
- return streamId;
- }
-
- public StreamStatus getStreamStatus()
- {
- return streamStatus;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/ByteBufferDataInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/ByteBufferDataInfo.java
deleted file mode 100644
index 163f3449b7..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/ByteBufferDataInfo.java
+++ /dev/null
@@ -1,90 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.TimeUnit;
-
-/**
- * <p>Specialized {@link DataInfo} for {@link ByteBuffer} content.</p>
- */
-public class ByteBufferDataInfo extends DataInfo
-{
- private final ByteBuffer buffer;
- private final int length;
-
- public ByteBufferDataInfo(ByteBuffer buffer, boolean close)
- {
- this(0, TimeUnit.SECONDS, buffer, close);
- }
-
- public ByteBufferDataInfo(long timeout, TimeUnit unit, ByteBuffer buffer, boolean close)
- {
- super(timeout, unit, close);
- this.buffer = buffer;
- this.length = buffer.remaining();
- }
-
- @Override
- public int length()
- {
- return length;
- }
-
- @Override
- public int available()
- {
- return buffer.remaining();
- }
-
- @Override
- public int readInto(ByteBuffer output)
- {
- int space = output.remaining();
- if (available() > space)
- {
- int limit = buffer.limit();
- buffer.limit(buffer.position() + space);
- output.put(buffer);
- buffer.limit(limit);
- }
- else
- {
- space = buffer.remaining();
- output.put(buffer);
- }
- return space;
- }
-
- @Override
- public int readInto(byte[] bytes, int offset, int length)
- {
- int available = available();
- if (available < length)
- length = available;
- buffer.get(bytes, offset, length);
- return length;
- }
-
- @Override
- protected ByteBuffer allocate(int size)
- {
- return buffer.isDirect() ? ByteBuffer.allocateDirect(size) : super.allocate(size);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/BytesDataInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/BytesDataInfo.java
deleted file mode 100644
index 05cd88ea5c..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/BytesDataInfo.java
+++ /dev/null
@@ -1,83 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.TimeUnit;
-
-/**
- * <p>Specialized {@link DataInfo} for byte array content.</p>
- */
-public class BytesDataInfo extends DataInfo
-{
- private final byte[] bytes;
- private final int offset;
- private final int length;
- private int index;
-
- public BytesDataInfo(byte[] bytes, boolean close)
- {
- this(0, TimeUnit.SECONDS, bytes, close);
- }
-
- public BytesDataInfo(long timeout, TimeUnit unit, byte[] bytes, boolean close)
- {
- this(timeout, unit, bytes, 0, bytes.length, close);
- }
-
- public BytesDataInfo(long timeout, TimeUnit unit, byte[] bytes, int offset, int length, boolean close)
- {
- super(timeout, unit, close);
- this.bytes = bytes;
- this.offset = offset;
- this.length = length;
- this.index = offset;
- }
-
- @Override
- public int length()
- {
- return length;
- }
-
- @Override
- public int available()
- {
- return length - index + offset;
- }
-
- @Override
- public int readInto(ByteBuffer output)
- {
- int space = output.remaining();
- int chunk = Math.min(available(), space);
- output.put(bytes, index, chunk);
- index += chunk;
- return chunk;
- }
-
- @Override
- public int readInto(byte[] bytes, int offset, int length)
- {
- int chunk = Math.min(available(), length);
- System.arraycopy(this.bytes, index, bytes, offset, chunk);
- index += chunk;
- return chunk;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/DataInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/DataInfo.java
deleted file mode 100644
index c2c1018530..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/DataInfo.java
+++ /dev/null
@@ -1,264 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * <p>A container for DATA frames metadata and content bytes.</p>
- * <p>Specialized subclasses (like {@link StringDataInfo}) may be used by applications
- * to send specific types of content.</p>
- * <p>Applications may send multiple instances of {@link DataInfo}, usually of the same
- * type, via {@link Stream#data(DataInfo)}. The last instance must have the
- * {@link #isClose() close flag} set, so that the client knows that no more content is
- * expected.</p>
- * <p>Receivers of {@link DataInfo} via {@link StreamFrameListener#onData(Stream, DataInfo)}
- * have two different APIs to read the data content bytes: a {@link #readInto(ByteBuffer) read}
- * API that does not interact with flow control, and a {@link #consumeInto(ByteBuffer) drain}
- * API that interacts with flow control.</p>
- * <p>Flow control is defined so that when the sender wants to sends a number of bytes larger
- * than the {@link Settings.ID#INITIAL_WINDOW_SIZE} value, it will stop sending as soon as it
- * has sent a number of bytes equal to the window size. The receiver has to <em>consume</em>
- * the data bytes that it received in order to tell the sender to send more bytes.</p>
- * <p>Consuming the data bytes can be done only via {@link #consumeInto(ByteBuffer)} or by a combination
- * of {@link #readInto(ByteBuffer)} and {@link #consume(int)} (possibly at different times).</p>
- */
-public abstract class DataInfo extends Info
-{
- /**
- * <p>Flag that indicates that this {@link DataInfo} is the last frame in the stream.</p>
- *
- * @see #isClose()
- * @see #getFlags()
- */
- public final static byte FLAG_CLOSE = 1;
-
- private final AtomicInteger consumed = new AtomicInteger();
- private boolean close;
-
- /**
- * <p>Creates a new {@link DataInfo} with the given close flag and no compression flag.</p>
- *
- * @param close the value of the close flag
- */
- public DataInfo(boolean close)
- {
- setClose(close);
- }
-
- /**
- * <p>Creates a new {@link DataInfo} with the given close flag and no compression flag.</p>
- *
- * @param timeout
- * @param unit
- * @param close the value of the close flag
- */
- protected DataInfo(long timeout, TimeUnit unit, boolean close)
- {
- super(timeout, unit);
- this.close = close;
- }
-
- /**
- * @return the value of the close flag
- * @see #setClose(boolean)
- */
- public boolean isClose()
- {
- return close;
- }
-
- /**
- * @param close the value of the close flag
- * @see #isClose()
- */
- public void setClose(boolean close)
- {
- this.close = close;
- }
-
- /**
- * @return the close and compress flags as integer
- * @see #FLAG_CLOSE
- */
- public byte getFlags()
- {
- return isClose() ? FLAG_CLOSE : 0;
- }
-
- /**
- * @return the total number of content bytes
- * @see #available()
- */
- public abstract int length();
-
- /**
- * <p>Returns the available content bytes that can be read via {@link #readInto(ByteBuffer)}.</p>
- * <p>Each invocation to {@link #readInto(ByteBuffer)} modifies the value returned by this method,
- * until no more content bytes are available.</p>
- *
- * @return the available content bytes
- * @see #readInto(ByteBuffer)
- */
- public abstract int available();
-
- /**
- * <p>Copies the content bytes of this {@link DataInfo} into the given {@link ByteBuffer}.</p>
- * <p>If the given {@link ByteBuffer} cannot contain the whole content of this {@link DataInfo}
- * then after the read {@link #available()} will return a positive value, and further content
- * may be retrieved by invoking again this method with a new output buffer.</p>
- *
- * @param output the {@link ByteBuffer} to copy the bytes into
- * @return the number of bytes copied
- * @see #available()
- * @see #consumeInto(ByteBuffer)
- */
- public abstract int readInto(ByteBuffer output);
-
- /**
- * <p>Copies the content bytes of this {@link DataInfo} into the given byte array.</p>
- * <p>If the given byte array cannot contain the whole content of this {@link DataInfo}
- * then after the read {@link #available()} will return a positive value, and further content
- * may be retrieved by invoking again this method with a new byte array.</p>
- *
- * @param bytes the byte array to copy the bytes into
- * @param offset the index of the byte array to start copying
- * @param length the number of bytes to copy
- * @return the number of bytes copied
- */
- public abstract int readInto(byte[] bytes, int offset, int length);
-
- /**
- * <p>Reads and consumes the content bytes of this {@link DataInfo} into the given {@link ByteBuffer}.</p>
- *
- * @param output the {@link ByteBuffer} to copy the bytes into
- * @return the number of bytes copied
- * @see #consume(int)
- */
- public int consumeInto(ByteBuffer output)
- {
- int read = readInto(output);
- consume(read);
- return read;
- }
-
- /**
- * <p>Reads and consumes the content bytes of this {@link DataInfo} into the given byte array,
- * starting from index {@code offset} for {@code length} bytes.</p>
- *
- * @param bytes the byte array to copy the bytes into
- * @param offset the offset of the byte array to start copying
- * @param length the number of bytes to copy
- * @return the number of bytes copied
- */
- public int consumeInto(byte[] bytes, int offset, int length)
- {
- int read = readInto(bytes, offset, length);
- consume(read);
- return read;
- }
-
- /**
- * <p>Consumes the given number of bytes from this {@link DataInfo}.</p>
- *
- * @param delta the number of bytes consumed
- */
- public void consume(int delta)
- {
- if (delta < 0)
- throw new IllegalArgumentException();
- int read = length() - available();
- int newConsumed = consumed() + delta;
-// if (newConsumed > read)
-// throw new IllegalStateException("Consuming without reading: consumed " + newConsumed + " but only read " + read);
- consumed.addAndGet(delta);
- }
-
- /**
- * @return the number of bytes consumed
- */
- public int consumed()
- {
- return consumed.get();
- }
-
- /**
- *
- * @param charset the charset used to convert the bytes
- * @param consume whether to consume the content
- * @return a String with the content of this {@link DataInfo}
- */
- public String asString(String charset, boolean consume)
- {
- return asString(Charset.forName(charset), consume);
- }
-
- /**
- *
- * @param charset the charset used to convert the bytes
- * @param consume whether to consume the content
- * @return a String with the content of this {@link DataInfo}
- */
- public String asString(Charset charset, boolean consume)
- {
- ByteBuffer buffer = asByteBuffer(consume);
- return charset.decode(buffer).toString();
- }
-
- /**
- * @return a byte array with the content of this {@link DataInfo}
- * @param consume whether to consume the content
- */
- public byte[] asBytes(boolean consume)
- {
- ByteBuffer buffer = asByteBuffer(consume);
- byte[] result = new byte[buffer.remaining()];
- buffer.get(result);
- return result;
- }
-
- /**
- * @return a {@link ByteBuffer} with the content of this {@link DataInfo}
- * @param consume whether to consume the content
- */
- public ByteBuffer asByteBuffer(boolean consume)
- {
- ByteBuffer buffer = allocate(available());
- if (consume)
- consumeInto(buffer);
- else
- readInto(buffer);
- buffer.flip();
- return buffer;
- }
-
- protected ByteBuffer allocate(int size)
- {
- return ByteBuffer.allocate(size);
- }
-
- @Override
- public String toString()
- {
- return String.format("DATA @%x available=%d consumed=%d close=%b", hashCode(), available(), consumed(), isClose());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/GoAwayInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/GoAwayInfo.java
deleted file mode 100644
index e97f6c5f60..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/GoAwayInfo.java
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * A GoAwayInfo container. Currently adding nothing to it's base class, but serves to keep the api unchanged in
- * future versions when we need to pass more info to the methods having a {@link GoAwayInfo} parameter.
- */
-public class GoAwayInfo extends Info
-{
- public GoAwayInfo(long timeout, TimeUnit unit)
- {
- super(timeout, unit);
- }
-
- public GoAwayInfo()
- {
- super();
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/GoAwayResultInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/GoAwayResultInfo.java
deleted file mode 100644
index 42f17cc695..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/GoAwayResultInfo.java
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-/**
- * <p>A container for GOAWAY frames metadata: the last good stream id and
- * the session status.</p>
- */
-public class GoAwayResultInfo
-{
- private final int lastStreamId;
- private final SessionStatus sessionStatus;
-
- /**
- * <p>Creates a new {@link GoAwayResultInfo} with the given last good stream id and session status</p>
- *
- * @param lastStreamId the last good stream id
- * @param sessionStatus the session status
- */
- public GoAwayResultInfo(int lastStreamId, SessionStatus sessionStatus)
- {
- this.lastStreamId = lastStreamId;
- this.sessionStatus = sessionStatus;
- }
-
- /**
- * @return the last good stream id
- */
- public int getLastStreamId()
- {
- return lastStreamId;
- }
-
- /**
- * @return the session status
- */
- public SessionStatus getSessionStatus()
- {
- return sessionStatus;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/HeadersInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/HeadersInfo.java
deleted file mode 100644
index 2b5e5ce427..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/HeadersInfo.java
+++ /dev/null
@@ -1,135 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.util.Fields;
-
-/**
- * <p>A container for HEADERS frame metadata and headers.</p>
- */
-public class HeadersInfo extends Info
-{
- /**
- * <p>Flag that indicates that this {@link HeadersInfo} is the last frame in the stream.</p>
- *
- * @see #isClose()
- * @see #getFlags()
- */
- public static final byte FLAG_CLOSE = 1;
- /**
- * <p>Flag that indicates that the compression of the stream must be reset.</p>
- *
- * @see #isResetCompression()
- * @see #getFlags()
- */
- public static final byte FLAG_RESET_COMPRESSION = 2;
-
- private final boolean close;
- private final boolean resetCompression;
- private final Fields headers;
-
- /**
- * <p>Creates a new {@link HeadersInfo} instance with the given headers, the given close flag and no reset
- * compression flag</p>
- *
- * @param headers the {@link Fields}
- * @param close the value of the close flag
- */
- public HeadersInfo(Fields headers, boolean close)
- {
- this(headers, close, false);
- }
-
- /**
- * <p>Creates a new {@link HeadersInfo} instance with the given headers, the given close flag and the given reset
- * compression flag</p>
- *
- * @param headers the {@link Fields}
- * @param close the value of the close flag
- * @param resetCompression the value of the reset compression flag
- */
- public HeadersInfo(Fields headers, boolean close, boolean resetCompression)
- {
- this.headers = headers;
- this.close = close;
- this.resetCompression = resetCompression;
- }
-
- /**
- * <p>Creates a new {@link HeadersInfo} instance with the given headers, the given close flag and the given reset
- * compression flag</p>
- *
- * @param timeout the operation's timeout
- * @param unit the timeout's unit
- * @param headers the {@link Fields}
- * @param close the value of the close flag
- * @param resetCompression the value of the reset compression flag
- */
- public HeadersInfo(long timeout, TimeUnit unit, boolean close, boolean resetCompression, Fields headers)
- {
- super(timeout, unit);
- this.close = close;
- this.resetCompression = resetCompression;
- this.headers = headers;
- }
-
- /**
- * @return the value of the close flag
- */
- public boolean isClose()
- {
- return close;
- }
-
- /**
- * @return the value of the reset compression flag
- */
- public boolean isResetCompression()
- {
- return resetCompression;
- }
-
- /**
- * @return the {@link Fields}
- */
- public Fields getHeaders()
- {
- return headers;
- }
-
- /**
- * @return the close and reset compression flags as integer
- * @see #FLAG_CLOSE
- * @see #FLAG_RESET_COMPRESSION
- */
- public byte getFlags()
- {
- byte flags = isClose() ? FLAG_CLOSE : 0;
- flags += isResetCompression() ? FLAG_RESET_COMPRESSION : 0;
- return flags;
- }
-
- @Override
- public String toString()
- {
- return String.format("HEADER close=%b %s", close, headers);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Info.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Info.java
deleted file mode 100644
index 315a9572a3..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Info.java
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * A base class for all *Info classes providing timeout and unit and api to access them
- */
-public class Info
-{
- private final long timeout;
- private final TimeUnit unit;
-
- public Info(long timeout, TimeUnit unit)
- {
- this.timeout = timeout;
- this.unit = unit;
- }
-
- public Info()
- {
- timeout = 0;
- unit = TimeUnit.SECONDS;
- }
-
- public long getTimeout()
- {
- return timeout;
- }
-
- public TimeUnit getUnit()
- {
- return unit;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PingInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PingInfo.java
deleted file mode 100644
index 0cc693593f..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PingInfo.java
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * A PingInfo container. Currently adding nothing to it's base class, but serves to keep the api unchanged in
- * future versions when we need to pass more info to the methods having a {@link PingInfo} parameter.
- */
-public class PingInfo extends Info
-{
- public PingInfo(long timeout, TimeUnit unit)
- {
- super(timeout, unit);
- }
-
- public PingInfo()
- {
- this(0, TimeUnit.SECONDS);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PingResultInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PingResultInfo.java
deleted file mode 100644
index ef71eb3f65..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PingResultInfo.java
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-/**
- * <p>A container for PING frames data.</p>
- */
-public class PingResultInfo
-{
- private final int pingId;
-
- /**
- * <p>Creates a {@link PingResultInfo} with the given ping id</p>
- * @param pingId the ping id
- */
- public PingResultInfo(int pingId)
- {
- this.pingId = pingId;
- }
-
- /**
- * @return the ping id
- */
- public int getPingId()
- {
- return pingId;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PushInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PushInfo.java
deleted file mode 100644
index 8f7598b8f0..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/PushInfo.java
+++ /dev/null
@@ -1,101 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.util.Fields;
-
-/**
- * <p>A container for PUSH_SYN_STREAM frames metadata and data.</p>
- */
-public class PushInfo extends Info
-{
- /**
- * <p>Flag that indicates that this {@link PushInfo} is the last frame in the stream.</p>
- *
- * @see #isClose()
- * @see #getFlags()
- */
- public static final byte FLAG_CLOSE = 1;
-
- private final boolean close;
- private final Fields headers;
-
- /**
- * <p>Creates a {@link PushInfo} instance with the given headers and the given close flag,
- * not unidirectional, without associated stream, and with default priority.</p>
- *
- * @param headers the {@link Fields}
- * @param close the value of the close flag
- */
- public PushInfo(Fields headers, boolean close)
- {
- this(0, TimeUnit.SECONDS, headers, close);
- // either builder or setters for timeout
- }
-
- /**
- * <p>
- * Creates a {@link PushInfo} instance with the given headers, the given close flag and with the given priority.
- * </p>
- * @param timeout the timeout value
- * @param unit the TimeUnit of the timeout
- * @param headers
- * the {@link Fields}
- * @param close
- */
- public PushInfo(long timeout, TimeUnit unit, Fields headers, boolean close)
- {
- super(timeout, unit);
- this.close = close;
- this.headers = headers;
- }
-
- /**
- * @return the value of the close flag
- */
- public boolean isClose()
- {
- return close;
- }
-
- /**
- * @return the {@link Fields}
- */
- public Fields getHeaders()
- {
- return headers;
- }
-
- /**
- * @return the close flag as integer
- * @see #FLAG_CLOSE
- */
- public byte getFlags()
- {
- return isClose() ? FLAG_CLOSE : 0;
- }
-
- @Override
- public String toString()
- {
- return String.format("SYN push close=%b headers=%s", close, headers);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/ReplyInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/ReplyInfo.java
deleted file mode 100644
index 6586eeb0ae..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/ReplyInfo.java
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.util.Fields;
-
-/**
- * <p>A container for SYN_REPLY frames metadata and headers.</p>
- */
-public class ReplyInfo extends Info
-{
- /**
- * <p>Flag that indicates that this {@link ReplyInfo} is the last frame in the stream.</p>
- *
- * @see #isClose()
- * @see #getFlags()
- */
- public static final byte FLAG_CLOSE = 1;
-
- private final Fields headers;
- private final boolean close;
-
- /**
- * <p>Creates a new {@link ReplyInfo} instance with empty headers and the given close flag.</p>
- *
- * @param close the value of the close flag
- */
- public ReplyInfo(boolean close)
- {
- this(new Fields(), close);
- }
-
- /**
- * <p>Creates a {@link ReplyInfo} instance with the given headers and the given close flag.</p>
- *
- * @param headers the {@link Fields}
- * @param close the value of the close flag
- */
- public ReplyInfo(Fields headers, boolean close)
- {
- this(0, TimeUnit.SECONDS, headers, close);
- }
-
- /**
- * <p>Creates a {@link ReplyInfo} instance with the given headers and the given close flag.</p>
- *
- * @param timeout the timeout
- * @param unit the time unit for the timeout
- * @param headers the {@link Fields}
- * @param close the value of the close flag
- */
- public ReplyInfo(long timeout, TimeUnit unit, Fields headers, boolean close)
- {
- super(timeout, unit);
- this.headers = headers;
- this.close = close;
- }
-
- /**
- * @return the {@link Fields}
- */
- public Fields getHeaders()
- {
- return headers;
- }
-
- /**
- * @return the value of the close flag
- */
- public boolean isClose()
- {
- return close;
- }
-
- /**
- * @return the close and reset compression flags as integer
- * @see #FLAG_CLOSE
- */
- public byte getFlags()
- {
- return isClose() ? FLAG_CLOSE : 0;
- }
-
- @Override
- public String toString()
- {
- return String.format("REPLY close=%b %s", close, headers);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/RstInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/RstInfo.java
deleted file mode 100644
index bbf1fc9e95..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/RstInfo.java
+++ /dev/null
@@ -1,78 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * <p>A container for RST_STREAM frames data: the stream id and the stream status.</p>
- */
-public class RstInfo extends Info
-{
- private final int streamId;
- private final StreamStatus streamStatus;
-
- /**
- * <p>Creates a new {@link RstInfo} with the given stream id and stream status</p>
- *
- * @param timeout the operation's timeout
- * @param unit the timeout's unit
- * @param streamId the stream id
- * @param streamStatus the stream status
- */
- public RstInfo(long timeout, TimeUnit unit, int streamId, StreamStatus streamStatus)
- {
- super(timeout, unit);
- this.streamId = streamId;
- this.streamStatus = streamStatus;
- }
-
- /**
- * <p>Creates a new {@link RstInfo} with the given stream id and stream status</p>
- *
- * @param streamId
- * @param streamStatus
- */
- public RstInfo(int streamId, StreamStatus streamStatus)
- {
- this(0, TimeUnit.SECONDS, streamId, streamStatus);
- }
-
- /**
- * @return the stream id
- */
- public int getStreamId()
- {
- return streamId;
- }
-
- /**
- * @return the stream status
- */
- public StreamStatus getStreamStatus()
- {
- return streamStatus;
- }
-
- @Override
- public String toString()
- {
- return String.format("RST stream=%d %s", streamId, streamStatus);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SPDY.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SPDY.java
deleted file mode 100644
index 9374843737..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SPDY.java
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-/**
- * <p>Helper class that holds useful SPDY constants.</p>
- */
-public class SPDY
-{
- /**
- * <p>Constant that indicates the version 2 of the SPDY protocol</p>
- */
- public static final short V2 = 2;
-
- /**
- * <p>Constant that indicates the version 3 of the SPDY protocol</p>
- */
- public static final short V3 = 3;
-
- private SPDY()
- {
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SPDYException.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SPDYException.java
deleted file mode 100644
index 0df87c8f27..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SPDYException.java
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-/**
- * <p>An unrecoverable exception that signals to the application that
- * something wrong happened.</p>
- */
-public class SPDYException extends RuntimeException
-{
- public SPDYException()
- {
- }
-
- public SPDYException(String message)
- {
- super(message);
- }
-
- public SPDYException(String message, Throwable cause)
- {
- super(message, cause);
- }
-
- public SPDYException(Throwable cause)
- {
- super(cause);
- }
-
- public SPDYException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)
- {
- super(message, cause, enableSuppression, writableStackTrace);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Session.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Session.java
deleted file mode 100644
index 5841551f25..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Session.java
+++ /dev/null
@@ -1,261 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.net.InetSocketAddress;
-import java.util.EventListener;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Promise;
-
-/**
- * <p>A {@link Session} represents the client-side endpoint of a SPDY connection to a single origin server.</p>
- * <p>Once a {@link Session} has been obtained, it can be used to open SPDY streams:</p>
- * <pre>
- * Session session = ...;
- * SynInfo synInfo = new SynInfo(true);
- * session.push(synInfo, new Stream.FrameListener.Adapter()
- * {
- * public void onReply(Stream stream, ReplyInfo replyInfo)
- * {
- * // Stream reply received
- * }
- * });
- * </pre>
- * <p>A {@link Session} is the active part of the endpoint, and by calling its API applications can generate
- * events on the connection; conversely {@link SessionFrameListener} is the passive part of the endpoint, and
- * has callbacks that are invoked when events happen on the connection.</p>
- *
- * @see SessionFrameListener
- */
-public interface Session
-{
- /**
- * @return the SPDY protocol version used by this session
- */
- public short getVersion();
-
- /**
- * <p>Registers the given {@code listener} to be notified of session events.</p>
- *
- * @param listener the listener to register
- * @see #removeListener(Listener)
- */
- public void addListener(Listener listener);
-
- /**
- * <p>Deregisters the give {@code listener} from being notified of session events.</p>
- *
- * @param listener the listener to deregister
- * @see #addListener(Listener)
- */
- public void removeListener(Listener listener);
-
- /**
- * <p>Sends a SYN_FRAME to create a new {@link Stream SPDY stream}.</p>
- * <p>Callers may use the returned Stream for example, to send data frames.</p>
- *
- * @param synInfo the metadata to send on stream creation
- * @param listener the listener to invoke when events happen on the stream just created
- * @return the stream that will be created
- * @see #syn(SynInfo, StreamFrameListener, Promise)
- */
- public Stream syn(SynInfo synInfo, StreamFrameListener listener) throws ExecutionException, InterruptedException, TimeoutException;
-
- /**
- * <p>Sends asynchronously a SYN_FRAME to create a new {@link Stream SPDY stream}.</p>
- * <p>Callers may pass a non-null completion callback to be notified of when the
- * stream has been created and use the stream, for example, to send data frames.</p>
- *
- *
- * @param synInfo the metadata to send on stream creation
- * @param listener the listener to invoke when events happen on the stream just created
- * @param promise the completion callback that gets notified of stream creation
- * @see #syn(SynInfo, StreamFrameListener)
- */
- public void syn(SynInfo synInfo, StreamFrameListener listener, Promise<Stream> promise);
-
- /**
- * <p>Sends synchronously a RST_STREAM to abort a stream.</p>
- *
- * @param rstInfo the metadata to reset the stream
- * @see #rst(RstInfo, Callback)
- */
- public void rst(RstInfo rstInfo) throws InterruptedException, ExecutionException, TimeoutException;
-
- /**
- * <p>Sends asynchronously a RST_STREAM to abort a stream.</p>
- * <p>Callers may pass a non-null completion callback to be notified of when the
- * reset has been actually sent.</p>
- *
- * @param rstInfo the metadata to reset the stream
- * @param callback the completion callback that gets notified of reset's send
- * @see #rst(RstInfo)
- */
- public void rst(RstInfo rstInfo, Callback callback);
-
- /**
- * <p>Sends synchronously a SETTINGS to configure the SPDY connection.</p>
- *
- * @param settingsInfo the metadata to send
- * @see #settings(SettingsInfo, Callback)
- */
- public void settings(SettingsInfo settingsInfo) throws ExecutionException, InterruptedException, TimeoutException;
-
- /**
- * <p>Sends asynchronously a SETTINGS to configure the SPDY connection.</p>
- * <p>Callers may pass a non-null completion callback to be notified of when the
- * settings has been actually sent.</p>
- *
- *
- * @param settingsInfo the metadata to send
- * @param callback the completion callback that gets notified of settings' send
- * @see #settings(SettingsInfo)
- */
- public void settings(SettingsInfo settingsInfo, Callback callback);
-
- /**
- * <p>Sends synchronously a PING, normally to measure round-trip time.</p>
- *
- * @see #ping(PingInfo, Promise)
- * @param pingInfo
- */
- public PingResultInfo ping(PingInfo pingInfo) throws ExecutionException, InterruptedException, TimeoutException;
-
- /**
- * <p>Sends asynchronously a PING, normally to measure round-trip time.</p>
- * <p>Callers may pass a non-null completion callback to be notified of when the
- * ping has been actually sent.</p>
- *
- * @param pingInfo
- * @param promise the completion callback that gets notified of ping's send
- * @see #ping(PingInfo)
- */
- public void ping(PingInfo pingInfo, Promise<PingResultInfo> promise);
-
- /**
- * <p>Closes gracefully this session, sending a GO_AWAY frame and then closing the TCP connection.</p>
- *
- * @see #goAway(GoAwayInfo, Callback)
- * @param goAwayInfo
- */
- public void goAway(GoAwayInfo goAwayInfo) throws ExecutionException, InterruptedException, TimeoutException;
-
- /**
- * <p>Closes gracefully this session, sending a GO_AWAY frame and then closing the TCP connection.</p>
- * <p>Callers may pass a non-null completion callback to be notified of when the
- * go away has been actually sent.</p>
- *
- * @param goAwayInfo
- * @param callback the completion callback that gets notified of go away's send
- * @see #goAway(GoAwayInfo)
- */
- public void goAway(GoAwayInfo goAwayInfo, Callback callback);
-
- /**
- * @return a snapshot of the streams currently active in this session
- * @see #getStream(int)
- */
- public Set<Stream> getStreams();
-
- /**
- * @param streamId the id of the stream to retrieve
- * @return the stream with the given stream id
- * @see #getStreams()
- */
- public Stream getStream(int streamId);
-
- /**
- * @param key the attribute key
- * @return an arbitrary object associated with the given key to this session
- * @see #setAttribute(String, Object)
- */
- public Object getAttribute(String key);
-
- /**
- * @param key the attribute key
- * @param value an arbitrary object to associate with the given key to this session
- * @see #getAttribute(String)
- * @see #removeAttribute(String)
- */
- public void setAttribute(String key, Object value);
-
- /**
- * @param key the attribute key
- * @return the arbitrary object associated with the given key to this session
- * @see #setAttribute(String, Object)
- */
- public Object removeAttribute(String key);
-
- /**
- * @return the local address of the underlying endpoint
- */
- public InetSocketAddress getLocalAddress();
-
- /**
- * @return the remote address of the underlying endpoint
- */
- public InetSocketAddress getRemoteAddress();
-
- /**
- * <p>Super interface for listeners with callbacks that are invoked on specific session events.</p>
- */
- public interface Listener extends EventListener
- {
- }
-
- /**
- * <p>Specialized listener that is invoked upon creation and removal of streams.</p>
- */
- public interface StreamListener extends Listener
- {
- /**
- * <p>Callback invoked when a new SPDY stream is created.</p>
- *
- * @param stream the stream just created
- */
- public void onStreamCreated(Stream stream);
-
- /**
- * <p>Callback invoked when a SPDY stream is closed.</p>
- *
- * @param stream the stream just closed.
- */
- public void onStreamClosed(Stream stream);
-
- /**
- * <p>Empty implementation of {@link StreamListener}.</p>
- */
- public static class Adapter implements StreamListener
- {
- @Override
- public void onStreamCreated(Stream stream)
- {
- }
-
- @Override
- public void onStreamClosed(Stream stream)
- {
- }
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionFrameListener.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionFrameListener.java
deleted file mode 100644
index 0291d74be8..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionFrameListener.java
+++ /dev/null
@@ -1,163 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.EventListener;
-
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-/**
- * <p>A {@link SessionFrameListener} is the passive counterpart of a {@link Session} and receives events happening
- * on a SPDY session.</p>
- *
- * @see Session
- */
-public interface SessionFrameListener extends EventListener
-{
- /**
- * <p>Callback invoked when a request to create a stream has been received.</p>
- * <p>Application code should implement this method and reply to the stream creation, eventually
- * sending data:</p>
- * <pre>
- * public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- * {
- * // Do something with the metadata contained in synInfo
- *
- * if (stream.isHalfClosed()) // The other peer will not send data
- * {
- * stream.reply(new ReplyInfo(false));
- * stream.data(new StringDataInfo("foo", true));
- * return null; // Not interested in further stream events
- * }
- *
- * ...
- * }
- * </pre>
- * <p>Alternatively, if the stream creation requires reading data sent from the other peer:</p>
- * <pre>
- * public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- * {
- * // Do something with the metadata contained in synInfo
- *
- * if (!stream.isHalfClosed()) // The other peer will send data
- * {
- * stream.reply(new ReplyInfo(true));
- * return new Stream.FrameListener.Adapter() // Interested in stream events
- * {
- * public void onData(Stream stream, DataInfo dataInfo)
- * {
- * // Do something with the incoming data in dataInfo
- * }
- * };
- * }
- *
- * ...
- * }
- * </pre>
- *
- * @param stream the stream just created
- * @param synInfo the metadata sent on stream creation
- * @return a listener for stream events, or null if there is no interest in being notified of stream events
- */
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo);
-
- /**
- * <p>Callback invoked when a stream error happens.</p>
- *
- * @param session the session
- * @param rstInfo the metadata of the stream error
- */
- public void onRst(Session session, RstInfo rstInfo);
-
- /**
- * <p>Callback invoked when a request to configure the SPDY connection has been received.</p>
- *
- * @param session the session
- * @param settingsInfo the metadata sent to configure
- */
- public void onSettings(Session session, SettingsInfo settingsInfo);
-
- /**
- * <p>Callback invoked when a ping request has completed its round-trip.</p>
- *
- * @param session the session
- * @param pingResultInfo the metadata received
- */
- public void onPing(Session session, PingResultInfo pingResultInfo);
-
- /**
- * <p>Callback invoked when the other peer signals that it is closing the connection.</p>
- *
- * @param session the session
- * @param goAwayResultInfo the metadata sent
- */
- public void onGoAway(Session session, GoAwayResultInfo goAwayResultInfo);
-
- /**
- * <p>Callback invoked when an exception is thrown during the processing of an event on a
- * SPDY session.</p>
- * <p>Examples of such conditions are invalid frames received, corrupted headers compression state, etc.</p>
- *
- * @param session the session
- * @param x the exception that caused the event processing failure
- */
- public void onFailure(Session session, Throwable x);
-
-
- /**
- * <p>Empty implementation of {@link SessionFrameListener}</p>
- */
- public static class Adapter implements SessionFrameListener
- {
- private static final Logger logger = Log.getLogger(Adapter.class);
-
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- return null;
- }
-
- @Override
- public void onRst(Session session, RstInfo rstInfo)
- {
- }
-
- @Override
- public void onSettings(Session session, SettingsInfo settingsInfo)
- {
- }
-
- @Override
- public void onPing(Session session, PingResultInfo pingResultInfo)
- {
- }
-
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayResultInfo)
- {
- }
-
- @Override
- public void onFailure(Session session, Throwable x)
- {
- logger.info("", x);
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionStatus.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionStatus.java
deleted file mode 100644
index 09e2915dfb..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SessionStatus.java
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * <p>An enumeration of session statuses.</p>
- */
-public enum SessionStatus
-{
- /**
- * <p>The session status indicating no errors</p>
- */
- OK(0),
- /**
- * <p>The session status indicating a protocol error</p>
- */
- PROTOCOL_ERROR(1);
-
- /**
- * @param code the session status code
- * @return a {@link SessionStatus} from the given code,
- * or null if no status exists
- */
- public static SessionStatus from(int code)
- {
- return Codes.codes.get(code);
- }
-
- private final int code;
-
- private SessionStatus(int code)
- {
- this.code = code;
- Codes.codes.put(code, this);
- }
-
- /**
- * @return the code of this {@link SessionStatus}
- */
- public int getCode()
- {
- return code;
- }
-
- private static class Codes
- {
- private static final Map<Integer, SessionStatus> codes = new HashMap<>();
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Settings.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Settings.java
deleted file mode 100644
index 1b09d32fa6..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Settings.java
+++ /dev/null
@@ -1,228 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-public class Settings implements Iterable<Settings.Setting>
-{
- private final Map<ID, Settings.Setting> settings;
-
- public Settings()
- {
- settings = new HashMap<>();
- }
-
- public Settings(Settings original, boolean immutable)
- {
- Map<ID, Settings.Setting> copy = new HashMap<>(original.size());
- copy.putAll(original.settings);
- settings = immutable ? Collections.unmodifiableMap(copy) : copy;
- }
-
- public Setting get(ID id)
- {
- return settings.get(id);
- }
-
- public void put(Setting setting)
- {
- settings.put(setting.id(), setting);
- }
-
- public Setting remove(ID id)
- {
- return settings.remove(id);
- }
-
- public int size()
- {
- return settings.size();
- }
-
- public void clear()
- {
- settings.clear();
- }
-
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj)
- return true;
- if (obj == null || getClass() != obj.getClass())
- return false;
- Settings that = (Settings)obj;
- return settings.equals(that.settings);
- }
-
- @Override
- public int hashCode()
- {
- return settings.hashCode();
- }
-
- @Override
- public Iterator<Setting> iterator()
- {
- return settings.values().iterator();
- }
-
- @Override
- public String toString()
- {
- return settings.toString();
- }
-
- public static final class ID
- {
- public static final ID UPLOAD_BANDWIDTH = new ID(1);
- public static final ID DOWNLOAD_BANDWIDTH = new ID(2);
- public static final ID ROUND_TRIP_TIME = new ID(3);
- public static final ID MAX_CONCURRENT_STREAMS = new ID(4);
- public static final ID CURRENT_CONGESTION_WINDOW = new ID(5);
- public static final ID DOWNLOAD_RETRANSMISSION_RATE = new ID(6);
- public static final ID INITIAL_WINDOW_SIZE = new ID(7);
-
- public synchronized static ID from(int code)
- {
- ID id = Codes.codes.get(code);
- if (id == null)
- id = new ID(code);
- return id;
- }
-
- private final int code;
-
- private ID(int code)
- {
- this.code = code;
- Codes.codes.put(code, this);
- }
-
- public int code()
- {
- return code;
- }
-
- @Override
- public String toString()
- {
- return String.valueOf(code);
- }
-
- private static class Codes
- {
- private static final Map<Integer, ID> codes = new HashMap<>();
- }
- }
-
- public static enum Flag
- {
- NONE((byte)0),
- PERSIST((byte)1),
- PERSISTED((byte)2);
-
- public static Flag from(byte code)
- {
- return Codes.codes.get(code);
- }
-
- private final byte code;
-
- private Flag(byte code)
- {
- this.code = code;
- Codes.codes.put(code, this);
- }
-
- public byte code()
- {
- return code;
- }
-
- private static class Codes
- {
- private static final Map<Byte, Flag> codes = new HashMap<>();
- }
- }
-
- public static class Setting
- {
- private final ID id;
- private final Flag flag;
- private final int value;
-
- public Setting(ID id, int value)
- {
- this(id, Flag.NONE, value);
- }
-
- public Setting(ID id, Flag flag, int value)
- {
- this.id = id;
- this.flag = flag;
- this.value = value;
- }
-
- public ID id()
- {
- return id;
- }
-
- public Flag flag()
- {
- return flag;
- }
-
- public int value()
- {
- return value;
- }
-
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj)
- return true;
- if (obj == null || getClass() != obj.getClass())
- return false;
- Setting that = (Setting)obj;
- return value == that.value && flag == that.flag && id == that.id;
- }
-
- @Override
- public int hashCode()
- {
- int result = id.hashCode();
- result = 31 * result + flag.hashCode();
- result = 31 * result + value;
- return result;
- }
-
- @Override
- public String toString()
- {
- return String.format("[id=%s,flags=%s:value=%d]", id(), flag(), value());
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SettingsInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SettingsInfo.java
deleted file mode 100644
index c607e1f940..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SettingsInfo.java
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.concurrent.TimeUnit;
-
-public class SettingsInfo extends Info
-{
- public static final byte CLEAR_PERSISTED = 1;
-
- private final Settings settings;
- private final boolean clearPersisted;
-
- public SettingsInfo(Settings settings)
- {
- this(0, TimeUnit.SECONDS, settings, false);
- }
-
- public SettingsInfo(long timeout, TimeUnit unit, Settings settings, boolean clearPersisted)
- {
- super(timeout, unit);
- this.settings = settings;
- this.clearPersisted = clearPersisted;
- }
-
- public SettingsInfo(Settings settings, boolean clearPersisted)
- {
- this(0, TimeUnit.SECONDS, settings, clearPersisted);
- }
-
- public boolean isClearPersisted()
- {
- return clearPersisted;
- }
-
- public byte getFlags()
- {
- return isClearPersisted() ? CLEAR_PERSISTED : 0;
- }
-
- public Settings getSettings()
- {
- return settings;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Stream.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Stream.java
deleted file mode 100644
index a75768bafd..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/Stream.java
+++ /dev/null
@@ -1,237 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.nio.channels.WritePendingException;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Promise;
-
-/**
- * <p>A {@link Stream} represents a bidirectional exchange of data on top of a {@link Session}.</p> <p>Differently from
- * socket streams, where the input and output streams are permanently associated with the socket (and hence with the
- * connection that the socket represents), there can be multiple SPDY streams for a SPDY session.</p> <p>SPDY streams
- * may terminate without this implying that the SPDY session is terminated.</p> <p>If SPDY is used to transport the HTTP
- * protocol, then a SPDY stream maps to a HTTP request/response cycle, and after the request/response cycle is
- * completed, the stream is closed, and other streams may be opened. Differently from HTTP, though, multiple SPDY
- * streams may be opened concurrently on the same SPDY session.</p> <p>Like {@link Session}, {@link Stream} is the
- * active part and by calling its API applications can generate events on the stream; conversely, {@link
- * StreamFrameListener} is the passive part, and its callbacks are invoked when events happen on the stream.</p> <p>A
- * {@link Stream} can send multiple data frames one after the other but implementations use a flow control mechanism
- * that only sends the data frames if the other end has signalled that it can accept the frame.</p> <p>Data frames
- * should be sent sequentially only when the previous frame has been completely sent. The reason for this requirement is
- * to avoid potentially confusing code such as:</p>
- * <pre>
- * // WRONG CODE, DO NOT USE IT
- * final Stream stream = ...;
- * stream.data(StringDataInfo("chunk1", false), 5, TimeUnit.SECONDS, new Handler&lt;Void&gt;() { ... });
- * stream.data(StringDataInfo("chunk2", true), 1, TimeUnit.SECONDS, new Handler&lt;Void&gt;() { ... });
- * </pre>
- * <p>where the second call to {@link #data(DataInfo, Callback)} has a timeout smaller than the previous call.</p>
- * <p>The behavior of such style of invocations is unspecified (it may even throw an exception - similar to {@link
- * WritePendingException}).</p> <p>The correct sending of data frames is the following:</p>
- * <pre>
- * final Stream stream = ...;
- * ...
- * // Blocking version
- * stream.data(new StringDataInfo("chunk1", false)).get(1, TimeUnit.SECONDS);
- * stream.data(new StringDataInfo("chunk2", true)).get(1, TimeUnit.SECONDS);
- *
- * // Asynchronous version
- * stream.data(new StringDataInfo("chunk1", false), 1, TimeUnit.SECONDS, new Handler.Adapter&lt;Void&gt;()
- * {
- * public void completed(Void context)
- * {
- * stream.data(new StringDataInfo("chunk2", true));
- * }
- * });
- * </pre>
- *
- * @see StreamFrameListener
- */
-public interface Stream
-{
- /**
- * @return the id of this stream
- */
- public int getId();
-
- /**
- * @return the priority of this stream
- */
- public byte getPriority();
-
- /**
- * @return the session this stream is associated to
- */
- public Session getSession();
-
- /**
- * <p>Initiate a unidirectional spdy pushstream associated to this stream asynchronously<p> <p>Callers may use the
- * returned future to get the pushstream once it got created</p>
- *
- * @param pushInfo the metadata to send on stream creation
- * @return a future containing the stream once it got established
- * @see #push(PushInfo, Promise)
- */
- public Stream push(PushInfo pushInfo) throws InterruptedException, ExecutionException, TimeoutException;
-
- /**
- * <p>Initiate a unidirectional spdy pushstream associated to this stream asynchronously<p> <p>Callers may pass a
- * non-null completion promise to be notified of when the pushstream has been established.</p>
- *
- * @param pushInfo the metadata to send on stream creation
- * @param promise the completion promise that gets notified once the pushstream is established
- * @see #push(PushInfo)
- */
- public void push(PushInfo pushInfo, Promise<Stream> promise);
-
- /**
- * <p>Sends asynchronously a SYN_REPLY frame in response to a SYN_STREAM frame.</p> <p>Callers may use the returned
- * future to wait for the reply to be actually sent.</p>
- *
- * @param replyInfo the metadata to send
- * @see #reply(ReplyInfo, Callback)
- * @see SessionFrameListener#onSyn(Stream, SynInfo)
- */
- public void reply(ReplyInfo replyInfo) throws InterruptedException, ExecutionException, TimeoutException;
-
- /**
- * <p>Sends asynchronously a SYN_REPLY frame in response to a SYN_STREAM frame.</p> <p>Callers may pass a non-null
- * completion callback to be notified of when the reply has been actually sent.</p>
- *
- * @param replyInfo the metadata to send
- * @param callback the completion callback that gets notified of reply sent
- * @see #reply(ReplyInfo)
- */
- public void reply(ReplyInfo replyInfo, Callback callback);
-
- /**
- * <p>Sends asynchronously a DATA frame on this stream.</p> <p>DATA frames should always be sent after a SYN_REPLY
- * frame.</p> <p>Callers may use the returned future to wait for the data to be actually sent.</p>
- *
- * @param dataInfo the metadata to send
- * @see #data(DataInfo, Callback)
- * @see #reply(ReplyInfo)
- */
- public void data(DataInfo dataInfo) throws InterruptedException, ExecutionException, TimeoutException;
-
- /**
- * <p>Sends asynchronously a DATA frame on this stream.</p> <p>DATA frames should always be sent after a SYN_REPLY
- * frame.</p> <p>Callers may pass a non-null completion callback to be notified of when the data has been actually
- * sent.</p>
- *
- * @param dataInfo the metadata to send
- * @param callback the completion callback that gets notified of data sent
- * @see #data(DataInfo)
- */
- public void data(DataInfo dataInfo, Callback callback);
-
- /**
- * <p>Sends asynchronously a HEADER frame on this stream.</p> <p>HEADERS frames should always be sent after a
- * SYN_REPLY frame.</p> <p>Callers may use the returned future to wait for the headers to be actually sent.</p>
- *
- * @param headersInfo the metadata to send
- * @see #headers(HeadersInfo, Callback)
- * @see #reply(ReplyInfo)
- */
- public void headers(HeadersInfo headersInfo) throws InterruptedException, ExecutionException, TimeoutException;
-
- /**
- * <p>Sends asynchronously a HEADER frame on this stream.</p> <p>HEADERS frames should always be sent after a
- * SYN_REPLY frame.</p> <p>Callers may pass a non-null completion callback to be notified of when the headers have
- * been actually sent.</p>
- *
- * @param headersInfo the metadata to send
- * @param callback the completion callback that gets notified of headers sent
- * @see #headers(HeadersInfo)
- */
- public void headers(HeadersInfo headersInfo, Callback callback);
-
- /**
- * @return whether this stream is unidirectional or not
- */
- public boolean isUnidirectional();
-
- /**
- * @return whether this stream has been reset
- */
- public boolean isReset();
-
- /**
- * @return whether this stream has been closed by both parties
- * @see #isHalfClosed()
- */
- public boolean isClosed();
-
- /**
- * @return whether this stream has been closed by one party only
- * @see #isClosed()
- */
- public boolean isHalfClosed();
-
- /**
- * @param key the attribute key
- * @return an arbitrary object associated with the given key to this stream or null if no object can be found for
- * the given key.
- * @see #setAttribute(String, Object)
- */
- public Object getAttribute(String key);
-
- /**
- * @param key the attribute key
- * @param value an arbitrary object to associate with the given key to this stream
- * @see #getAttribute(String)
- * @see #removeAttribute(String)
- */
- public void setAttribute(String key, Object value);
-
- /**
- * @param key the attribute key
- * @return the arbitrary object associated with the given key to this stream
- * @see #setAttribute(String, Object)
- */
- public Object removeAttribute(String key);
-
- /**
- * @return the associated parent stream or null if this is not an associated stream
- */
- public Stream getAssociatedStream();
-
- /**
- * @return associated child streams or an empty set if no associated streams exist
- */
- public Set<Stream> getPushedStreams();
-
- /**
- * Get the idle timeout set for this particular stream
- * @return the idle timeout
- */
- public long getIdleTimeout();
-
- /**
- * Set an idle timeout for this stream
- * @param timeout
- */
- public void setIdleTimeout(long timeout);
-
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StreamFrameListener.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StreamFrameListener.java
deleted file mode 100644
index 08e41bce99..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StreamFrameListener.java
+++ /dev/null
@@ -1,110 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.EventListener;
-
-/**
- * <p>A {@link StreamFrameListener} is the passive counterpart of a {@link Stream} and receives
- * events happening on a SPDY stream.</p>
- *
- * @see Stream
- */
-public interface StreamFrameListener extends EventListener
-{
- /**
- * <p>Callback invoked when a reply to a stream creation has been received.</p>
- * <p>Application code may implement this method to send more data to the other end:</p>
- * <pre>
- * public void onReply(Stream stream, ReplyInfo replyInfo)
- * {
- * stream.data(new StringDataInfo("content"), true);
- * }
- * </pre>
- * @param stream the stream
- * @param replyInfo the reply metadata
- */
- public void onReply(Stream stream, ReplyInfo replyInfo);
-
- /**
- * <p>Callback invoked when headers are received on a stream.</p>
- *
- * @param stream the stream
- * @param headersInfo the headers metadata
- */
- public void onHeaders(Stream stream, HeadersInfo headersInfo);
-
- /**
- * <p>Callback invoked when a push syn has been received on a stream.</p>
- *
- * @param stream the push stream just created
- * @param pushInfo the push metadata
- * @return a listener for stream events or null if there is no interest in being notified of stream events
- */
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo);
-
- /**
- * <p>Callback invoked when data bytes are received on a stream.</p>
- * <p>Implementers should be read or consume the content of the
- * {@link DataInfo} before this method returns.</p>
- *
- * @param stream the stream
- * @param dataInfo the data metadata
- */
- public void onData(Stream stream, DataInfo dataInfo);
-
- /**
- * <p>Callback invoked on errors.</p>
- * @param stream the stream
- * @param x the failure
- */
- public void onFailure(Stream stream, Throwable x);
-
- /**
- * <p>Empty implementation of {@link StreamFrameListener}</p>
- */
- public static class Adapter implements StreamFrameListener
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- }
-
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- }
-
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- return null;
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- }
-
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StreamStatus.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StreamStatus.java
deleted file mode 100644
index c18ab1fc3b..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StreamStatus.java
+++ /dev/null
@@ -1,128 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * <p>An enumeration of stream statuses.</p>
- */
-public enum StreamStatus
-{
- /**
- * <p>The stream status indicating a protocol error</p>
- */
- PROTOCOL_ERROR(1, 1),
- /**
- * <p>The stream status indicating that the stream is not valid</p>
- */
- INVALID_STREAM(2, 2),
- /**
- * <p>The stream status indicating that the stream has been refused</p>
- */
- REFUSED_STREAM(3, 3),
- /**
- * <p>The stream status indicating that the implementation does not support the SPDY version of the stream</p>
- */
- UNSUPPORTED_VERSION(4, 4),
- /**
- * <p>The stream status indicating that the stream is no longer needed</p>
- */
- CANCEL_STREAM(5, 5),
- /**
- * <p>The stream status indicating an implementation error</p>
- */
- INTERNAL_ERROR(6, 6),
- /**
- * <p>The stream status indicating a flow control error</p>
- */
- FLOW_CONTROL_ERROR(7, 7),
- /**
- * <p>The stream status indicating a stream opened more than once</p>
- */
- STREAM_IN_USE(-1, 8),
- /**
- * <p>The stream status indicating data on a stream already closed</p>
- */
- STREAM_ALREADY_CLOSED(-1, 9),
- /**
- * <p>The stream status indicating credentials not valid</p>
- */
- INVALID_CREDENTIALS(-1, 10),
- /**
- * <p>The stream status indicating that the implementation could not support a frame too large</p>
- */
- FRAME_TOO_LARGE(-1, 11);
-
- /**
- * @param version the SPDY protocol version
- * @param code the stream status code
- * @return a {@link StreamStatus} from the given version and code,
- * or null if no such status exists
- */
- public static StreamStatus from(short version, int code)
- {
- switch (version)
- {
- case SPDY.V2:
- return Codes.v2Codes.get(code);
- case SPDY.V3:
- return Codes.v3Codes.get(code);
- default:
- throw new IllegalStateException();
- }
- }
-
- private final int v2Code;
- private final int v3Code;
-
- private StreamStatus(int v2Code, int v3Code)
- {
- this.v2Code = v2Code;
- if (v2Code >= 0)
- Codes.v2Codes.put(v2Code, this);
- this.v3Code = v3Code;
- if (v3Code >= 0)
- Codes.v3Codes.put(v3Code, this);
- }
-
- /**
- * @param version the SPDY protocol version
- * @return the stream status code
- */
- public int getCode(short version)
- {
- switch (version)
- {
- case SPDY.V2:
- return v2Code;
- case SPDY.V3:
- return v3Code;
- default:
- throw new IllegalStateException();
- }
- }
-
- private static class Codes
- {
- private static final Map<Integer, StreamStatus> v2Codes = new HashMap<>();
- private static final Map<Integer, StreamStatus> v3Codes = new HashMap<>();
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StringDataInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StringDataInfo.java
deleted file mode 100644
index 793c32a265..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StringDataInfo.java
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.nio.charset.StandardCharsets;
-import java.util.concurrent.TimeUnit;
-
-/**
- * <p>Specialized {@link DataInfo} for {@link String} content.</p>
- */
-public class StringDataInfo extends BytesDataInfo
-{
- public StringDataInfo(String string, boolean close)
- {
- super(string.getBytes(StandardCharsets.UTF_8), close);
- }
-
- public StringDataInfo(long timeout, TimeUnit unit, String string, boolean close)
- {
- super(timeout, unit, string.getBytes(StandardCharsets.UTF_8), close);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SynInfo.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SynInfo.java
deleted file mode 100644
index 26424c3c60..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/SynInfo.java
+++ /dev/null
@@ -1,128 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.util.Fields;
-
-/**
- * <p>A container for SYN_STREAM frames metadata and data.</p>
- */
-public class SynInfo extends Info
-{
- /**
- * <p>Flag that indicates that this {@link SynInfo} is the last frame in the stream.</p>
- *
- * @see #isClose()
- * @see #getFlags()
- */
- public static final byte FLAG_CLOSE = 1;
-
- private final boolean close;
- private final byte priority;
- private final Fields headers;
-
- /**
- * <p>Creates a {@link SynInfo} instance with the given headers and the given close flag,
- * not unidirectional, without associated stream, and with default priority.</p>
- *
- * @param headers the {@link Fields}
- * @param close the value of the close flag
- */
- public SynInfo(Fields headers, boolean close)
- {
- this(0, TimeUnit.SECONDS, headers, close, (byte)0);
- // either builder or setters for timeout
- }
-
- /**
- * <p>
- * Creates a {@link SynInfo} instance with the given headers, the given close flag and with the given priority.
- * </p>
- * @param headers
- * the {@link Fields}
- * @param close
- * the value of the close flag
- * @param priority
- */
- public SynInfo(Fields headers, boolean close, byte priority)
- {
- this(0, TimeUnit.SECONDS, headers, close, priority);
- }
-
- /**
- * <p>
- * Creates a {@link SynInfo} instance with the given headers, the given close flag and with the given priority.
- * </p>
- * @param timeout the timeout value
- * @param unit the TimeUnit of the timeout
- * @param headers
- * the {@link Fields}
- * @param close
- * the value of the close flag
- * @param priority
- */
- public SynInfo(long timeout, TimeUnit unit, Fields headers, boolean close, byte priority)
- {
- super(timeout, unit);
- this.close = close;
- this.priority = priority;
- this.headers = headers;
- }
-
- /**
- * @return the value of the close flag
- */
- public boolean isClose()
- {
- return close;
- }
-
- /**
- * @return the priority
- */
- public byte getPriority()
- {
- return priority;
- }
-
- /**
- * @return the {@link Fields}
- */
- public Fields getHeaders()
- {
- return headers;
- }
-
- /**
- * @return the close flag as integer
- * @see #FLAG_CLOSE
- */
- public byte getFlags()
- {
- return isClose() ? FLAG_CLOSE : 0;
- }
-
- @Override
- public String toString()
- {
- return String.format("SYN close=%b headers=%s", close, headers);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/server/ServerSessionFrameListener.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/server/ServerSessionFrameListener.java
deleted file mode 100644
index 69824eaf31..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/server/ServerSessionFrameListener.java
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api.server;
-
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-
-/**
- * <p>Specific, server-side, {@link SessionFrameListener}.</p>
- * <p>In addition to {@link SessionFrameListener}, this listener adds method
- * {@link #onConnect(Session)} that is called when a client first connects to the
- * server and may be used by a server-side application to send a SETTINGS frame
- * to configure the connection before the client can open any stream.</p>
- */
-public interface ServerSessionFrameListener extends SessionFrameListener
-{
- /**
- * <p>Callback invoked when a client opens a connection.</p>
- *
- * @param session the session
- */
- public void onConnect(Session session);
-
- /**
- * <p>Empty implementation of {@link ServerSessionFrameListener}</p>
- */
- public static class Adapter extends SessionFrameListener.Adapter implements ServerSessionFrameListener
- {
- @Override
- public void onConnect(Session session)
- {
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/ControlFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/ControlFrame.java
deleted file mode 100644
index 0ff4b6c9b6..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/ControlFrame.java
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-public abstract class ControlFrame
-{
- public static final int HEADER_LENGTH = 8;
-
- private final short version;
- private final ControlFrameType type;
- private final byte flags;
-
- public ControlFrame(short version, ControlFrameType type, byte flags)
- {
- this.version = version;
- this.type = type;
- this.flags = flags;
- }
-
- public short getVersion()
- {
- return version;
- }
-
- public ControlFrameType getType()
- {
- return type;
- }
-
- public byte getFlags()
- {
- return flags;
- }
-
- @Override
- public String toString()
- {
- return String.format("%s frame v%s", getType(), getVersion());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/ControlFrameType.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/ControlFrameType.java
deleted file mode 100644
index 7ca6ec83db..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/ControlFrameType.java
+++ /dev/null
@@ -1,59 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public enum ControlFrameType
-{
- SYN_STREAM((short)1),
- SYN_REPLY((short)2),
- RST_STREAM((short)3),
- SETTINGS((short)4),
- NOOP((short)5),
- PING((short)6),
- GO_AWAY((short)7),
- HEADERS((short)8),
- WINDOW_UPDATE((short)9),
- CREDENTIAL((short)10);
-
- public static ControlFrameType from(short code)
- {
- return Codes.codes.get(code);
- }
-
- private final short code;
-
- private ControlFrameType(short code)
- {
- this.code = code;
- Codes.codes.put(code, this);
- }
-
- public short getCode()
- {
- return code;
- }
-
- private static class Codes
- {
- private static final Map<Short, ControlFrameType> codes = new HashMap<>();
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/CredentialFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/CredentialFrame.java
deleted file mode 100644
index 9788bc2d43..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/CredentialFrame.java
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.security.cert.Certificate;
-
-public class CredentialFrame extends ControlFrame
-{
- private final short slot;
- private final byte[] proof;
- private final Certificate[] certificateChain;
-
- public CredentialFrame(short version, short slot, byte[] proof, Certificate[] certificateChain)
- {
- super(version, ControlFrameType.CREDENTIAL, (byte)0);
- this.slot = slot;
- this.proof = proof;
- this.certificateChain = certificateChain;
- }
-
- public short getSlot()
- {
- return slot;
- }
-
- public byte[] getProof()
- {
- return proof;
- }
-
- public Certificate[] getCertificateChain()
- {
- return certificateChain;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/DataFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/DataFrame.java
deleted file mode 100644
index d3689cd404..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/DataFrame.java
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import org.eclipse.jetty.spdy.api.DataInfo;
-
-public class DataFrame
-{
- public static final int HEADER_LENGTH = 8;
-
- private final int streamId;
- private final byte flags;
- private final int length;
-
- public DataFrame(int streamId, byte flags, int length)
- {
- this.streamId = streamId;
- this.flags = flags;
- this.length = length;
- }
-
- public int getStreamId()
- {
- return streamId;
- }
-
- public byte getFlags()
- {
- return flags;
- }
-
- public int getLength()
- {
- return length;
- }
-
- public boolean isClose()
- {
- return (flags & DataInfo.FLAG_CLOSE) == DataInfo.FLAG_CLOSE;
- }
-
- @Override
- public String toString()
- {
- return String.format("DATA frame stream=%d length=%d close=%b", getStreamId(), getLength(), isClose());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/GoAwayFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/GoAwayFrame.java
deleted file mode 100644
index 0471f75fca..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/GoAwayFrame.java
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import org.eclipse.jetty.spdy.api.SessionStatus;
-
-public class GoAwayFrame extends ControlFrame
-{
- private final int lastStreamId;
- private final int statusCode;
-
- public GoAwayFrame(short version, int lastStreamId, int statusCode)
- {
- super(version, ControlFrameType.GO_AWAY, (byte)0);
- this.lastStreamId = lastStreamId;
- this.statusCode = statusCode;
- }
-
- public int getLastStreamId()
- {
- return lastStreamId;
- }
-
- public int getStatusCode()
- {
- return statusCode;
- }
-
- @Override
- public String toString()
- {
- SessionStatus sessionStatus = SessionStatus.from(getStatusCode());
- return String.format("%s last_stream=%d status=%s", super.toString(), getLastStreamId(), sessionStatus == null ? getStatusCode() : sessionStatus);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/HeadersFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/HeadersFrame.java
deleted file mode 100644
index c1f9380168..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/HeadersFrame.java
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.util.Fields;
-
-public class HeadersFrame extends ControlFrame
-{
- private final int streamId;
- private final Fields headers;
-
- public HeadersFrame(short version, byte flags, int streamId, Fields headers)
- {
- super(version, ControlFrameType.HEADERS, flags);
- this.streamId = streamId;
- this.headers = headers;
- }
-
- public int getStreamId()
- {
- return streamId;
- }
-
- public Fields getHeaders()
- {
- return headers;
- }
-
- public boolean isClose()
- {
- return (getFlags() & HeadersInfo.FLAG_CLOSE) == HeadersInfo.FLAG_CLOSE;
- }
-
- public boolean isResetCompression()
- {
- return (getFlags() & HeadersInfo.FLAG_RESET_COMPRESSION) == HeadersInfo.FLAG_RESET_COMPRESSION;
- }
-
- @Override
- public String toString()
- {
- return String.format("%s stream=%d close=%b reset_compression=%b", super.toString(), getStreamId(), isClose(), isResetCompression());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/NoOpFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/NoOpFrame.java
deleted file mode 100644
index 13881ba815..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/NoOpFrame.java
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import org.eclipse.jetty.spdy.api.SPDY;
-
-public class NoOpFrame extends ControlFrame
-{
- public NoOpFrame()
- {
- super(SPDY.V2, ControlFrameType.NOOP, (byte)0);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/PingFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/PingFrame.java
deleted file mode 100644
index 0032301316..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/PingFrame.java
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-public class PingFrame extends ControlFrame
-{
- private final int pingId;
-
- public PingFrame(short version, int pingId)
- {
- super(version, ControlFrameType.PING, (byte)0);
- this.pingId = pingId;
- }
-
- public int getPingId()
- {
- return pingId;
- }
-
- @Override
- public String toString()
- {
- return String.format("%s ping=%d", super.toString(), getPingId());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/RstStreamFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/RstStreamFrame.java
deleted file mode 100644
index 3b6b9839d2..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/RstStreamFrame.java
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import org.eclipse.jetty.spdy.api.StreamStatus;
-
-public class RstStreamFrame extends ControlFrame
-{
- private final int streamId;
- private final int statusCode;
-
- public RstStreamFrame(short version, int streamId, int statusCode)
- {
- super(version, ControlFrameType.RST_STREAM, (byte)0);
- this.streamId = streamId;
- this.statusCode = statusCode;
- }
-
- public int getStreamId()
- {
- return streamId;
- }
-
- public int getStatusCode()
- {
- return statusCode;
- }
-
- @Override
- public String toString()
- {
- StreamStatus streamStatus = StreamStatus.from(getVersion(), getStatusCode());
- return String.format("%s stream=%d status=%s", super.toString(), getStreamId(), streamStatus == null ? getStatusCode() : streamStatus);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SettingsFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SettingsFrame.java
deleted file mode 100644
index 240c684519..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SettingsFrame.java
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import org.eclipse.jetty.spdy.api.Settings;
-import org.eclipse.jetty.spdy.api.SettingsInfo;
-
-public class SettingsFrame extends ControlFrame
-{
- private final Settings settings;
-
- public SettingsFrame(short version, byte flags, Settings settings)
- {
- super(version, ControlFrameType.SETTINGS, flags);
- this.settings = settings;
- }
-
- public boolean isClearPersisted()
- {
- return (getFlags() & SettingsInfo.CLEAR_PERSISTED) == SettingsInfo.CLEAR_PERSISTED;
- }
-
- public Settings getSettings()
- {
- return settings;
- }
-
- @Override
- public String toString()
- {
- return String.format("%s clear_persisted=%b settings=%s", super.toString(), isClearPersisted(), getSettings());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SynReplyFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SynReplyFrame.java
deleted file mode 100644
index 73cfb9c3b6..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SynReplyFrame.java
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.util.Fields;
-
-public class SynReplyFrame extends ControlFrame
-{
- private final int streamId;
- private final Fields headers;
-
- public SynReplyFrame(short version, byte flags, int streamId, Fields headers)
- {
- super(version, ControlFrameType.SYN_REPLY, flags);
- this.streamId = streamId;
- this.headers = headers;
- }
-
- public int getStreamId()
- {
- return streamId;
- }
-
- public Fields getHeaders()
- {
- return headers;
- }
-
- public boolean isClose()
- {
- return (getFlags() & ReplyInfo.FLAG_CLOSE) == ReplyInfo.FLAG_CLOSE;
- }
-
- @Override
- public String toString()
- {
- return String.format("%s stream=%d close=%b", super.toString(), getStreamId(), isClose());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SynStreamFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SynStreamFrame.java
deleted file mode 100644
index 98b65f3196..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/SynStreamFrame.java
+++ /dev/null
@@ -1,83 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import org.eclipse.jetty.spdy.PushSynInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.util.Fields;
-
-public class SynStreamFrame extends ControlFrame
-{
- private final int streamId;
- private final int associatedStreamId;
- private final byte priority;
- private final short slot;
- private final Fields headers;
-
- public SynStreamFrame(short version, byte flags, int streamId, int associatedStreamId, byte priority, short slot, Fields headers)
- {
- super(version, ControlFrameType.SYN_STREAM, flags);
- this.streamId = streamId;
- this.associatedStreamId = associatedStreamId;
- this.priority = priority;
- this.slot = slot;
- this.headers = headers;
- }
-
- public int getStreamId()
- {
- return streamId;
- }
-
- public int getAssociatedStreamId()
- {
- return associatedStreamId;
- }
-
- public byte getPriority()
- {
- return priority;
- }
-
- public short getSlot()
- {
- return slot;
- }
-
- public Fields getHeaders()
- {
- return headers;
- }
-
- public boolean isClose()
- {
- return (getFlags() & SynInfo.FLAG_CLOSE) == SynInfo.FLAG_CLOSE;
- }
-
- public boolean isUnidirectional()
- {
- return (getFlags() & PushSynInfo.FLAG_UNIDIRECTIONAL) == PushSynInfo.FLAG_UNIDIRECTIONAL;
- }
-
- @Override
- public String toString()
- {
- return String.format("%s stream=%d close=%b", super.toString(), getStreamId(), isClose());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/WindowUpdateFrame.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/WindowUpdateFrame.java
deleted file mode 100644
index f07b5589fb..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/frames/WindowUpdateFrame.java
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-public class WindowUpdateFrame extends ControlFrame
-{
- private final int streamId;
- private final int windowDelta;
-
- public WindowUpdateFrame(short version, int streamId, int windowDelta)
- {
- super(version, ControlFrameType.WINDOW_UPDATE, (byte)0);
- this.streamId = streamId;
- this.windowDelta = windowDelta;
- }
-
- public int getStreamId()
- {
- return streamId;
- }
-
- public int getWindowDelta()
- {
- return windowDelta;
- }
-
- @Override
- public String toString()
- {
- return String.format("%s stream=%d delta=%d", super.toString(), getStreamId(), getWindowDelta());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/ControlFrameGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/ControlFrameGenerator.java
deleted file mode 100644
index 57381bc9a4..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/ControlFrameGenerator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-
-public abstract class ControlFrameGenerator
-{
- private final ByteBufferPool bufferPool;
-
- protected ControlFrameGenerator(ByteBufferPool bufferPool)
- {
- this.bufferPool = bufferPool;
- }
-
- protected ByteBufferPool getByteBufferPool()
- {
- return bufferPool;
- }
-
- public abstract ByteBuffer generate(ControlFrame frame);
-
- protected void generateControlFrameHeader(ControlFrame frame, int frameLength, ByteBuffer buffer)
- {
- buffer.putShort((short)(0x8000 + frame.getVersion()));
- buffer.putShort(frame.getType().getCode());
- int flagsAndLength = frame.getFlags();
- flagsAndLength <<= 24;
- flagsAndLength += frameLength;
- buffer.putInt(flagsAndLength);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/CredentialGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/CredentialGenerator.java
deleted file mode 100644
index 2ed6e20d45..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/CredentialGenerator.java
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.SessionException;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.CredentialFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class CredentialGenerator extends ControlFrameGenerator
-{
- public CredentialGenerator(ByteBufferPool bufferPool)
- {
- super(bufferPool);
- }
-
- @Override
- public ByteBuffer generate(ControlFrame frame)
- {
- CredentialFrame credential = (CredentialFrame)frame;
-
- byte[] proof = credential.getProof();
-
- List<byte[]> certificates = serializeCertificates(credential.getCertificateChain());
- int certificatesLength = 0;
- for (byte[] certificate : certificates)
- certificatesLength += certificate.length;
-
- int frameBodyLength = 2 + 4 + proof.length + certificates.size() * 4 + certificatesLength;
-
- int totalLength = ControlFrame.HEADER_LENGTH + frameBodyLength;
- ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- generateControlFrameHeader(credential, frameBodyLength, buffer);
-
- buffer.putShort(credential.getSlot());
- buffer.putInt(proof.length);
- buffer.put(proof);
- for (byte[] certificate : certificates)
- {
- buffer.putInt(certificate.length);
- buffer.put(certificate);
- }
-
- buffer.flip();
- return buffer;
- }
-
- private List<byte[]> serializeCertificates(Certificate[] certificates)
- {
- try
- {
- List<byte[]> result = new ArrayList<>(certificates.length);
- for (Certificate certificate : certificates)
- result.add(certificate.getEncoded());
- return result;
- }
- catch (CertificateEncodingException x)
- {
- throw new SessionException(SessionStatus.PROTOCOL_ERROR, x);
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/DataFrameGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/DataFrameGenerator.java
deleted file mode 100644
index 6a3304ffeb..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/DataFrameGenerator.java
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.frames.DataFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class DataFrameGenerator
-{
- private final ByteBufferPool bufferPool;
-
- public DataFrameGenerator(ByteBufferPool bufferPool)
- {
- this.bufferPool = bufferPool;
- }
-
- public ByteBuffer generate(int streamId, int length, DataInfo dataInfo)
- {
- ByteBuffer buffer = bufferPool.acquire(DataFrame.HEADER_LENGTH + length, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- buffer.limit(length + DataFrame.HEADER_LENGTH);
- buffer.position(DataFrame.HEADER_LENGTH);
- // Guaranteed to always be >= 0
- int read = dataInfo.readInto(buffer);
-
- buffer.putInt(0, streamId & 0x7F_FF_FF_FF);
- buffer.putInt(4, read & 0x00_FF_FF_FF);
-
- byte flags = dataInfo.getFlags();
- if (dataInfo.available() > 0)
- flags &= ~DataInfo.FLAG_CLOSE;
- buffer.put(4, flags);
-
- buffer.flip();
- return buffer;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/Generator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/Generator.java
deleted file mode 100644
index 0bc53829cd..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/Generator.java
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-import java.util.EnumMap;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.ControlFrameType;
-
-public class Generator
-{
- final static boolean useDirectBuffers=false;
- private final EnumMap<ControlFrameType, ControlFrameGenerator> generators = new EnumMap<>(ControlFrameType.class);
- private final DataFrameGenerator dataFrameGenerator;
-
- public Generator(ByteBufferPool bufferPool, CompressionFactory.Compressor compressor)
- {
- HeadersBlockGenerator headersBlockGenerator = new HeadersBlockGenerator(compressor);
- generators.put(ControlFrameType.SYN_STREAM, new SynStreamGenerator(bufferPool, headersBlockGenerator));
- generators.put(ControlFrameType.SYN_REPLY, new SynReplyGenerator(bufferPool, headersBlockGenerator));
- generators.put(ControlFrameType.RST_STREAM, new RstStreamGenerator(bufferPool));
- generators.put(ControlFrameType.SETTINGS, new SettingsGenerator(bufferPool));
- generators.put(ControlFrameType.NOOP, new NoOpGenerator(bufferPool));
- generators.put(ControlFrameType.PING, new PingGenerator(bufferPool));
- generators.put(ControlFrameType.GO_AWAY, new GoAwayGenerator(bufferPool));
- generators.put(ControlFrameType.HEADERS, new HeadersGenerator(bufferPool, headersBlockGenerator));
- generators.put(ControlFrameType.WINDOW_UPDATE, new WindowUpdateGenerator(bufferPool));
- generators.put(ControlFrameType.CREDENTIAL, new CredentialGenerator(bufferPool));
-
- dataFrameGenerator = new DataFrameGenerator(bufferPool);
- }
-
- public ByteBuffer control(ControlFrame frame)
- {
- ControlFrameGenerator generator = generators.get(frame.getType());
- return generator.generate(frame);
- }
-
- public ByteBuffer data(int streamId, int length, DataInfo dataInfo)
- {
- return dataFrameGenerator.generate(streamId, length, dataInfo);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/GoAwayGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/GoAwayGenerator.java
deleted file mode 100644
index 524862a327..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/GoAwayGenerator.java
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.GoAwayFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class GoAwayGenerator extends ControlFrameGenerator
-{
- public GoAwayGenerator(ByteBufferPool bufferPool)
- {
- super(bufferPool);
- }
-
- @Override
- public ByteBuffer generate(ControlFrame frame)
- {
- GoAwayFrame goAway = (GoAwayFrame)frame;
-
- int frameBodyLength = 8;
- int totalLength = ControlFrame.HEADER_LENGTH + frameBodyLength;
- ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- generateControlFrameHeader(goAway, frameBodyLength, buffer);
-
- buffer.putInt(goAway.getLastStreamId() & 0x7F_FF_FF_FF);
- writeStatusCode(goAway, buffer);
-
- buffer.flip();
- return buffer;
- }
-
- private void writeStatusCode(GoAwayFrame goAway, ByteBuffer buffer)
- {
- switch (goAway.getVersion())
- {
- case SPDY.V2:
- break;
- case SPDY.V3:
- buffer.putInt(goAway.getStatusCode());
- break;
- default:
- throw new IllegalStateException();
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/HeadersBlockGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/HeadersBlockGenerator.java
deleted file mode 100644
index 9921f324ea..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/HeadersBlockGenerator.java
+++ /dev/null
@@ -1,150 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.io.ByteArrayOutputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-import org.eclipse.jetty.spdy.CompressionDictionary;
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.util.Fields;
-
-public class HeadersBlockGenerator
-{
- private final CompressionFactory.Compressor compressor;
- private boolean needsDictionary = true;
-
- public HeadersBlockGenerator(CompressionFactory.Compressor compressor)
- {
- this.compressor = compressor;
- }
-
- public ByteBuffer generate(short version, Fields headers)
- {
- // TODO: ByteArrayOutputStream is quite inefficient, but grows on demand; optimize using ByteBuffer ?
- final Charset iso1 = StandardCharsets.ISO_8859_1;
- ByteArrayOutputStream buffer = new ByteArrayOutputStream(headers.getSize() * 64);
- writeCount(version, buffer, headers.getSize());
- for (Fields.Field header : headers)
- {
- String name = header.getName().toLowerCase(Locale.ENGLISH);
- byte[] nameBytes = name.getBytes(iso1);
- writeNameLength(version, buffer, nameBytes.length);
- buffer.write(nameBytes, 0, nameBytes.length);
-
- // Most common path first
- String value = header.getValue();
- byte[] valueBytes = value.getBytes(iso1);
- if (header.hasMultipleValues())
- {
- List<String> values = header.getValues();
- for (int i = 1; i < values.size(); ++i)
- {
- byte[] moreValueBytes = values.get(i).getBytes(iso1);
- byte[] newValueBytes = Arrays.copyOf(valueBytes,valueBytes.length + 1 + moreValueBytes.length);
- newValueBytes[valueBytes.length] = 0;
- System.arraycopy(moreValueBytes, 0, newValueBytes, valueBytes.length + 1, moreValueBytes.length);
- valueBytes = newValueBytes;
- }
- }
-
- writeValueLength(version, buffer, valueBytes.length);
- buffer.write(valueBytes, 0, valueBytes.length);
- }
-
- return compress(version, buffer.toByteArray());
- }
-
- private ByteBuffer compress(short version, byte[] bytes)
- {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream(bytes.length);
-
- // The headers compression context is per-session, so we need to synchronize
- synchronized (compressor)
- {
- if (needsDictionary)
- {
- compressor.setDictionary(CompressionDictionary.get(version));
- needsDictionary = false;
- }
-
- compressor.setInput(bytes);
-
- // Compressed bytes may be bigger than input bytes, so we need to loop and accumulate them
- // Beware that the minimum amount of bytes generated by the compressor is few bytes, so we
- // need to use an output buffer that is big enough to exit the compress loop
- buffer.reset();
- int compressed;
- byte[] output = new byte[Math.max(256, bytes.length)];
- while (true)
- {
- // SPDY uses the SYNC_FLUSH mode
- compressed = compressor.compress(output);
- buffer.write(output, 0, compressed);
- if (compressed < output.length)
- break;
- }
- }
-
- return ByteBuffer.wrap(buffer.toByteArray());
- }
-
- private void writeCount(short version, ByteArrayOutputStream buffer, int value)
- {
- switch (version)
- {
- case SPDY.V2:
- {
- buffer.write((value & 0xFF_00) >>> 8);
- buffer.write(value & 0x00_FF);
- break;
- }
- case SPDY.V3:
- {
- buffer.write((value & 0xFF_00_00_00) >>> 24);
- buffer.write((value & 0x00_FF_00_00) >>> 16);
- buffer.write((value & 0x00_00_FF_00) >>> 8);
- buffer.write(value & 0x00_00_00_FF);
- break;
- }
- default:
- {
- // Here the version is trusted to be correct; if it's not
- // then it's a bug rather than an application error
- throw new IllegalStateException();
- }
- }
- }
-
- private void writeNameLength(short version, ByteArrayOutputStream buffer, int length)
- {
- writeCount(version, buffer, length);
- }
-
- private void writeValueLength(short version, ByteArrayOutputStream buffer, int length)
- {
- writeCount(version, buffer, length);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/HeadersGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/HeadersGenerator.java
deleted file mode 100644
index afb9adb206..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/HeadersGenerator.java
+++ /dev/null
@@ -1,76 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.SessionException;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.HeadersFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class HeadersGenerator extends ControlFrameGenerator
-{
- private final HeadersBlockGenerator headersBlockGenerator;
-
- public HeadersGenerator(ByteBufferPool bufferPool, HeadersBlockGenerator headersBlockGenerator)
- {
- super(bufferPool);
- this.headersBlockGenerator = headersBlockGenerator;
- }
-
- @Override
- public ByteBuffer generate(ControlFrame frame)
- {
- HeadersFrame headers = (HeadersFrame)frame;
- short version = headers.getVersion();
-
- ByteBuffer headersBuffer = headersBlockGenerator.generate(version, headers.getHeaders());
-
- int frameBodyLength = 4;
- if (frame.getVersion() == SPDY.V2)
- frameBodyLength += 2;
-
- int frameLength = frameBodyLength + headersBuffer.remaining();
- if (frameLength > 0xFF_FF_FF)
- {
- // Too many headers, but unfortunately we have already modified the compression
- // context, so we have no other choice than tear down the connection.
- throw new SessionException(SessionStatus.PROTOCOL_ERROR, "Too many headers");
- }
-
- int totalLength = ControlFrame.HEADER_LENGTH + frameLength;
-
- ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- generateControlFrameHeader(headers, frameLength, buffer);
-
- buffer.putInt(headers.getStreamId() & 0x7F_FF_FF_FF);
- if (frame.getVersion() == SPDY.V2)
- buffer.putShort((short)0);
-
- buffer.put(headersBuffer);
-
- buffer.flip();
- return buffer;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/NoOpGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/NoOpGenerator.java
deleted file mode 100644
index cbf029c55e..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/NoOpGenerator.java
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.NoOpFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class NoOpGenerator extends ControlFrameGenerator
-{
- public NoOpGenerator(ByteBufferPool bufferPool)
- {
- super(bufferPool);
- }
-
- @Override
- public ByteBuffer generate(ControlFrame frame)
- {
- NoOpFrame noOp = (NoOpFrame)frame;
-
- int frameBodyLength = 0;
- int totalLength = ControlFrame.HEADER_LENGTH + frameBodyLength;
- ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- generateControlFrameHeader(noOp, frameBodyLength, buffer);
-
- buffer.flip();
- return buffer;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/PingGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/PingGenerator.java
deleted file mode 100644
index c263a20f08..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/PingGenerator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.PingFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class PingGenerator extends ControlFrameGenerator
-{
- public PingGenerator(ByteBufferPool bufferPool)
- {
- super(bufferPool);
- }
-
- @Override
- public ByteBuffer generate(ControlFrame frame)
- {
- PingFrame ping = (PingFrame)frame;
-
- int frameBodyLength = 4;
- int totalLength = ControlFrame.HEADER_LENGTH + frameBodyLength;
- ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- generateControlFrameHeader(ping, frameBodyLength, buffer);
-
- buffer.putInt(ping.getPingId());
-
- buffer.flip();
- return buffer;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/RstStreamGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/RstStreamGenerator.java
deleted file mode 100644
index d26ac8ee91..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/RstStreamGenerator.java
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.RstStreamFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class RstStreamGenerator extends ControlFrameGenerator
-{
- public RstStreamGenerator(ByteBufferPool bufferPool)
- {
- super(bufferPool);
- }
-
- @Override
- public ByteBuffer generate(ControlFrame frame)
- {
- RstStreamFrame rstStream = (RstStreamFrame)frame;
-
- int frameBodyLength = 8;
- int totalLength = ControlFrame.HEADER_LENGTH + frameBodyLength;
- ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- generateControlFrameHeader(rstStream, frameBodyLength, buffer);
-
- buffer.putInt(rstStream.getStreamId() & 0x7F_FF_FF_FF);
- buffer.putInt(rstStream.getStatusCode());
-
- buffer.flip();
- return buffer;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SettingsGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SettingsGenerator.java
deleted file mode 100644
index 4c00ddee1d..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SettingsGenerator.java
+++ /dev/null
@@ -1,91 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Settings;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.SettingsFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class SettingsGenerator extends ControlFrameGenerator
-{
- public SettingsGenerator(ByteBufferPool bufferPool)
- {
- super(bufferPool);
- }
-
- @Override
- public ByteBuffer generate(ControlFrame frame)
- {
- SettingsFrame settingsFrame = (SettingsFrame)frame;
-
- Settings settings = settingsFrame.getSettings();
- int size = settings.size();
- int frameBodyLength = 4 + 8 * size;
- int totalLength = ControlFrame.HEADER_LENGTH + frameBodyLength;
- ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- generateControlFrameHeader(settingsFrame, frameBodyLength, buffer);
-
- buffer.putInt(size);
-
- for (Settings.Setting setting : settings)
- {
- int id = setting.id().code();
- byte flags = setting.flag().code();
- int idAndFlags = convertIdAndFlags(frame.getVersion(), id, flags);
- buffer.putInt(idAndFlags);
- buffer.putInt(setting.value());
- }
-
- buffer.flip();
- return buffer;
- }
-
- private int convertIdAndFlags(short version, int id, byte flags)
- {
- switch (version)
- {
- case SPDY.V2:
- {
- // In v2 the format is 24 bits of ID + 8 bits of flag
- int idAndFlags = (id << 8) + (flags & 0xFF);
- // A bug in the Chromium implementation forces v2 to have
- // the 3 ID bytes little endian, so we swap first and third
- int result = idAndFlags & 0x00_FF_00_FF;
- result += (idAndFlags & 0xFF_00_00_00) >>> 16;
- result += (idAndFlags & 0x00_00_FF_00) << 16;
- return result;
- }
- case SPDY.V3:
- {
- // In v3 the format is 8 bits of flags + 24 bits of ID
- return (flags << 24) + (id & 0xFF_FF_FF);
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SynReplyGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SynReplyGenerator.java
deleted file mode 100644
index d9aaa79ca2..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SynReplyGenerator.java
+++ /dev/null
@@ -1,104 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.SessionException;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.SynReplyFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class SynReplyGenerator extends ControlFrameGenerator
-{
- private final HeadersBlockGenerator headersBlockGenerator;
-
- public SynReplyGenerator(ByteBufferPool bufferPool, HeadersBlockGenerator headersBlockGenerator)
- {
- super(bufferPool);
- this.headersBlockGenerator = headersBlockGenerator;
- }
-
- @Override
- public ByteBuffer generate(ControlFrame frame)
- {
- SynReplyFrame synReply = (SynReplyFrame)frame;
- short version = synReply.getVersion();
-
- ByteBuffer headersBuffer = headersBlockGenerator.generate(version, synReply.getHeaders());
-
- int frameBodyLength = getFrameDataLength(version);
-
- int frameLength = frameBodyLength + headersBuffer.remaining();
- if (frameLength > 0xFF_FF_FF)
- {
- // Too many headers, but unfortunately we have already modified the compression
- // context, so we have no other choice than tear down the connection.
- throw new SessionException(SessionStatus.PROTOCOL_ERROR, "Too many headers");
- }
-
- int totalLength = ControlFrame.HEADER_LENGTH + frameLength;
-
- ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- generateControlFrameHeader(synReply, frameLength, buffer);
-
- buffer.putInt(synReply.getStreamId() & 0x7F_FF_FF_FF);
- writeAdditional(version, buffer);
-
- buffer.put(headersBuffer);
-
- buffer.flip();
- return buffer;
- }
-
- private int getFrameDataLength(short version)
- {
- switch (version)
- {
- case SPDY.V2:
- return 6;
- case SPDY.V3:
- return 4;
- default:
- // Here the version is trusted to be correct; if it's not
- // then it's a bug rather than an application error
- throw new IllegalStateException();
- }
- }
-
- private void writeAdditional(short version, ByteBuffer buffer)
- {
- switch (version)
- {
- case SPDY.V2:
- buffer.putShort((short)0);
- break;
- case SPDY.V3:
- break;
- default:
- // Here the version is trusted to be correct; if it's not
- // then it's a bug rather than an application error
- throw new IllegalStateException();
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SynStreamGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SynStreamGenerator.java
deleted file mode 100644
index 7a4e8ee618..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/SynStreamGenerator.java
+++ /dev/null
@@ -1,94 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.SessionException;
-import org.eclipse.jetty.spdy.StreamException;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.SynStreamFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class SynStreamGenerator extends ControlFrameGenerator
-{
- private final HeadersBlockGenerator headersBlockGenerator;
-
- public SynStreamGenerator(ByteBufferPool bufferPool, HeadersBlockGenerator headersBlockGenerator)
- {
- super(bufferPool);
- this.headersBlockGenerator = headersBlockGenerator;
- }
-
- @Override
- public ByteBuffer generate(ControlFrame frame)
- {
- SynStreamFrame synStream = (SynStreamFrame)frame;
- short version = synStream.getVersion();
-
- ByteBuffer headersBuffer = headersBlockGenerator.generate(version, synStream.getHeaders());
-
- int frameBodyLength = 10;
-
- int frameLength = frameBodyLength + headersBuffer.remaining();
- if (frameLength > 0xFF_FF_FF)
- {
- // Too many headers, but unfortunately we have already modified the compression
- // context, so we have no other choice than tear down the connection.
- throw new SessionException(SessionStatus.PROTOCOL_ERROR, "Too many headers");
- }
-
- int totalLength = ControlFrame.HEADER_LENGTH + frameLength;
-
- ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- generateControlFrameHeader(synStream, frameLength, buffer);
-
- int streamId = synStream.getStreamId();
- buffer.putInt(streamId & 0x7F_FF_FF_FF);
- buffer.putInt(synStream.getAssociatedStreamId() & 0x7F_FF_FF_FF);
- writePriority(streamId, version, synStream.getPriority(), buffer);
- buffer.put((byte)synStream.getSlot());
-
- buffer.put(headersBuffer);
-
- buffer.flip();
- return buffer;
- }
-
- private void writePriority(int streamId, short version, byte priority, ByteBuffer buffer)
- {
- switch (version)
- {
- case SPDY.V2:
- priority <<= 6;
- break;
- case SPDY.V3:
- priority <<= 5;
- break;
- default:
- throw new StreamException(streamId, StreamStatus.UNSUPPORTED_VERSION);
- }
- buffer.put(priority);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/WindowUpdateGenerator.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/WindowUpdateGenerator.java
deleted file mode 100644
index 5ce1699721..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/generator/WindowUpdateGenerator.java
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
-import org.eclipse.jetty.util.BufferUtil;
-
-public class WindowUpdateGenerator extends ControlFrameGenerator
-{
- public WindowUpdateGenerator(ByteBufferPool bufferPool)
- {
- super(bufferPool);
- }
-
- @Override
- public ByteBuffer generate(ControlFrame frame)
- {
- WindowUpdateFrame windowUpdate = (WindowUpdateFrame)frame;
-
- int frameBodyLength = 8;
- int totalLength = ControlFrame.HEADER_LENGTH + frameBodyLength;
- ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
- BufferUtil.clearToFill(buffer);
- generateControlFrameHeader(windowUpdate, frameBodyLength, buffer);
-
- buffer.putInt(windowUpdate.getStreamId() & 0x7F_FF_FF_FF);
- buffer.putInt(windowUpdate.getWindowDelta() & 0x7F_FF_FF_FF);
-
- buffer.flip();
- return buffer;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/ControlFrameBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/ControlFrameBodyParser.java
deleted file mode 100644
index 9dccfcd692..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/ControlFrameBodyParser.java
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-public abstract class ControlFrameBodyParser
-{
- public abstract boolean parse(ByteBuffer buffer);
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/ControlFrameParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/ControlFrameParser.java
deleted file mode 100644
index cfaf14af26..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/ControlFrameParser.java
+++ /dev/null
@@ -1,213 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-import java.util.EnumMap;
-
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.ControlFrameType;
-
-public abstract class ControlFrameParser
-{
- private final EnumMap<ControlFrameType, ControlFrameBodyParser> parsers = new EnumMap<>(ControlFrameType.class);
- private final ControlFrameBodyParser unknownParser = new UnknownControlFrameBodyParser(this);
- private State state = State.VERSION;
- private int cursor;
- private short version;
- private short type;
- private byte flags;
- private int length;
- private ControlFrameBodyParser bodyParser;
- private int bytesToSkip = 0;
-
- public ControlFrameParser(CompressionFactory.Decompressor decompressor)
- {
- parsers.put(ControlFrameType.SYN_STREAM, new SynStreamBodyParser(decompressor, this));
- parsers.put(ControlFrameType.SYN_REPLY, new SynReplyBodyParser(decompressor, this));
- parsers.put(ControlFrameType.RST_STREAM, new RstStreamBodyParser(this));
- parsers.put(ControlFrameType.SETTINGS, new SettingsBodyParser(this));
- parsers.put(ControlFrameType.NOOP, new NoOpBodyParser(this));
- parsers.put(ControlFrameType.PING, new PingBodyParser(this));
- parsers.put(ControlFrameType.GO_AWAY, new GoAwayBodyParser(this));
- parsers.put(ControlFrameType.HEADERS, new HeadersBodyParser(decompressor, this));
- parsers.put(ControlFrameType.WINDOW_UPDATE, new WindowUpdateBodyParser(this));
- parsers.put(ControlFrameType.CREDENTIAL, new CredentialBodyParser(this));
- }
-
- public short getVersion()
- {
- return version;
- }
-
- public byte getFlags()
- {
- return flags;
- }
-
- public int getLength()
- {
- return length;
- }
-
- public void skip(int bytesToSkip)
- {
- state = State.SKIP;
- this.bytesToSkip = bytesToSkip;
- }
-
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case VERSION:
- {
- if (buffer.remaining() >= 2)
- {
- version = (short)(buffer.getShort() & 0x7F_FF);
- state = State.TYPE;
- }
- else
- {
- state = State.VERSION_BYTES;
- cursor = 2;
- }
- break;
- }
- case VERSION_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- version += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- version &= 0x7F_FF;
- state = State.TYPE;
- }
- break;
- }
- case TYPE:
- {
- if (buffer.remaining() >= 2)
- {
- type = buffer.getShort();
- state = State.FLAGS;
- }
- else
- {
- state = State.TYPE_BYTES;
- cursor = 2;
- }
- break;
- }
- case TYPE_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- type += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- state = State.FLAGS;
- break;
- }
- case FLAGS:
- {
- flags = buffer.get();
- cursor = 3;
- state = State.LENGTH;
- break;
- }
- case LENGTH:
- {
- byte currByte = buffer.get();
- --cursor;
- length += (currByte & 0xFF) << 8 * cursor;
- if (cursor > 0)
- break;
-
- ControlFrameType controlFrameType = ControlFrameType.from(type);
-
- // SPEC v3, 2.2.1: unrecognized control frames must be ignored
- if (controlFrameType == null)
- bodyParser = unknownParser;
- else
- bodyParser = parsers.get(controlFrameType);
-
- state = State.BODY;
-
- // We have to let it fall through the next switch:
- // the NOOP frame has no body and we cannot break
- // because the buffer may be consumed and we will
- // never enter the BODY case.
- }
- case BODY:
- {
- if (bodyParser.parse(buffer))
- {
- reset();
- return true;
- }
- break;
- }
- case SKIP:
- {
- int remaining = buffer.remaining();
- if (remaining >= bytesToSkip)
- {
- buffer.position(buffer.position() + bytesToSkip);
- reset();
- return true;
- }
- else
- {
- buffer.position(buffer.limit());
- bytesToSkip = bytesToSkip - remaining;
- return false;
- }
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- void reset()
- {
- state = State.VERSION;
- cursor = 0;
- version = 0;
- type = 0;
- flags = 0;
- length = 0;
- bodyParser = null;
- bytesToSkip = 0;
- }
-
- protected abstract void onControlFrame(ControlFrame frame);
-
- private enum State
- {
- VERSION, VERSION_BYTES, TYPE, TYPE_BYTES, FLAGS, LENGTH, BODY, SKIP
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/CredentialBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/CredentialBodyParser.java
deleted file mode 100644
index f511aed935..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/CredentialBodyParser.java
+++ /dev/null
@@ -1,274 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.io.ByteArrayInputStream;
-import java.nio.ByteBuffer;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.jetty.spdy.SessionException;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.frames.ControlFrameType;
-import org.eclipse.jetty.spdy.frames.CredentialFrame;
-
-public class CredentialBodyParser extends ControlFrameBodyParser
-{
- private final List<Certificate> certificates = new ArrayList<>();
- private final ControlFrameParser controlFrameParser;
- private State state = State.SLOT;
- private int totalLength;
- private int cursor;
- private short slot;
- private int proofLength;
- private byte[] proof;
- private int certificateLength;
- private byte[] certificate;
-
- public CredentialBodyParser(ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case SLOT:
- {
- if (buffer.remaining() >= 2)
- {
- slot = buffer.getShort();
- checkSlotValid();
- state = State.PROOF_LENGTH;
- }
- else
- {
- state = State.SLOT_BYTES;
- cursor = 2;
- }
- break;
- }
- case SLOT_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- slot += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- checkSlotValid();
- state = State.PROOF_LENGTH;
- }
- break;
- }
- case PROOF_LENGTH:
- {
- if (buffer.remaining() >= 4)
- {
- proofLength = buffer.getInt() & 0x7F_FF_FF_FF;
- state = State.PROOF;
- }
- else
- {
- state = State.PROOF_LENGTH_BYTES;
- cursor = 4;
- }
- break;
- }
- case PROOF_LENGTH_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- proofLength += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- proofLength &= 0x7F_FF_FF_FF;
- state = State.PROOF;
- }
- break;
- }
- case PROOF:
- {
- totalLength = controlFrameParser.getLength() - 2 - 4 - proofLength;
- proof = new byte[proofLength];
- if (buffer.remaining() >= proofLength)
- {
- buffer.get(proof);
- state = State.CERTIFICATE_LENGTH;
- if (totalLength == 0)
- {
- onCredential();
- return true;
- }
- }
- else
- {
- state = State.PROOF_BYTES;
- cursor = proofLength;
- }
- break;
- }
- case PROOF_BYTES:
- {
- proof[proofLength - cursor] = buffer.get();
- --cursor;
- if (cursor == 0)
- {
- state = State.CERTIFICATE_LENGTH;
- if (totalLength == 0)
- {
- onCredential();
- return true;
- }
- }
- break;
- }
- case CERTIFICATE_LENGTH:
- {
- if (buffer.remaining() >= 4)
- {
- certificateLength = buffer.getInt() & 0x7F_FF_FF_FF;
- state = State.CERTIFICATE;
- }
- else
- {
- state = State.CERTIFICATE_LENGTH_BYTES;
- cursor = 4;
- }
- break;
- }
- case CERTIFICATE_LENGTH_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- certificateLength += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- certificateLength &= 0x7F_FF_FF_FF;
- state = State.CERTIFICATE;
- }
- break;
- }
- case CERTIFICATE:
- {
- totalLength -= 4 + certificateLength;
- certificate = new byte[certificateLength];
- if (buffer.remaining() >= certificateLength)
- {
- buffer.get(certificate);
- if (onCertificate())
- return true;
- }
- else
- {
- state = State.CERTIFICATE_BYTES;
- cursor = certificateLength;
- }
- break;
- }
- case CERTIFICATE_BYTES:
- {
- certificate[certificateLength - cursor] = buffer.get();
- --cursor;
- if (cursor == 0)
- {
- if (onCertificate())
- return true;
- }
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- private void checkSlotValid()
- {
- if (slot <= 0)
- throw new SessionException(SessionStatus.PROTOCOL_ERROR,
- "Invalid slot " + slot + " for " + ControlFrameType.CREDENTIAL + " frame");
- }
-
- private boolean onCertificate()
- {
- certificates.add(deserializeCertificate(certificate));
- if (totalLength == 0)
- {
- onCredential();
- return true;
- }
- else
- {
- certificateLength = 0;
- state = State.CERTIFICATE_LENGTH;
- }
- return false;
- }
-
- private Certificate deserializeCertificate(byte[] bytes)
- {
- try
- {
- CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
- return certificateFactory.generateCertificate(new ByteArrayInputStream(bytes));
- }
- catch (CertificateException x)
- {
- throw new SessionException(SessionStatus.PROTOCOL_ERROR, x);
- }
- }
-
- private void onCredential()
- {
- CredentialFrame frame = new CredentialFrame(controlFrameParser.getVersion(), slot,
- Arrays.copyOf(proof, proof.length), certificates.toArray(new Certificate[certificates.size()]));
- controlFrameParser.onControlFrame(frame);
- reset();
- }
-
- private void reset()
- {
- state = State.SLOT;
- totalLength = 0;
- cursor = 0;
- slot = 0;
- proofLength = 0;
- proof = null;
- certificateLength = 0;
- certificate = null;
- certificates.clear();
- }
-
- public enum State
- {
- SLOT, SLOT_BYTES, PROOF_LENGTH, PROOF_LENGTH_BYTES, PROOF, PROOF_BYTES,
- CERTIFICATE_LENGTH, CERTIFICATE_LENGTH_BYTES, CERTIFICATE, CERTIFICATE_BYTES
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/DataFrameParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/DataFrameParser.java
deleted file mode 100644
index 4bc025c2df..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/DataFrameParser.java
+++ /dev/null
@@ -1,155 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.frames.DataFrame;
-
-public abstract class DataFrameParser
-{
- private State state = State.STREAM_ID;
- private int cursor;
- private int streamId;
- private byte flags;
- private int length;
-
- /**
- * <p>Parses the given {@link ByteBuffer} for a data frame.</p>
- *
- * @param buffer the {@link ByteBuffer} to parse
- * @return true if the data frame has been fully parsed, false otherwise
- */
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case STREAM_ID:
- {
- if (buffer.remaining() >= 4)
- {
- streamId = buffer.getInt() & 0x7F_FF_FF_FF;
- state = State.FLAGS;
- }
- else
- {
- state = State.STREAM_ID_BYTES;
- cursor = 4;
- }
- break;
- }
- case STREAM_ID_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- streamId += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- state = State.FLAGS;
- break;
- }
- case FLAGS:
- {
- flags = buffer.get();
- cursor = 3;
- state = State.LENGTH;
- break;
- }
- case LENGTH:
- {
- byte currByte = buffer.get();
- --cursor;
- length += (currByte & 0xFF) << 8 * cursor;
- if (cursor > 0)
- break;
- state = State.DATA;
- // Fall down if length == 0: we can't loop because the buffer
- // may be empty but we need to invoke the application anyway
- if (length > 0)
- break;
- }
- case DATA:
- {
- // Length can only be at most 3 bytes, which is 16_777_215 i.e. 16 MiB.
- // However, compliant clients should implement flow control, so it's
- // unlikely that we will get that 16 MiB chunk.
- // However, TCP may further split the flow control window, so we may
- // only have part of the data at this point.
-
- int size = Math.min(length, buffer.remaining());
- int limit = buffer.limit();
- buffer.limit(buffer.position() + size);
- ByteBuffer bytes = buffer.slice();
- buffer.limit(limit);
- buffer.position(buffer.position() + size);
- length -= size;
- if (length == 0)
- {
- onDataFrame(bytes);
- return true;
- }
- else
- {
- // We got only part of the frame data bytes,
- // so we generate a synthetic data frame
- onDataFragment(bytes);
- }
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- private void onDataFrame(ByteBuffer bytes)
- {
- DataFrame frame = new DataFrame(streamId, flags, bytes.remaining());
- onDataFrame(frame, bytes);
- reset();
- }
-
- private void onDataFragment(ByteBuffer bytes)
- {
- DataFrame frame = new DataFrame(streamId, (byte)(flags & ~DataInfo.FLAG_CLOSE), bytes.remaining());
- onDataFrame(frame, bytes);
- // Do not reset, we're expecting more data
- }
-
- protected abstract void onDataFrame(DataFrame frame, ByteBuffer data);
-
- private void reset()
- {
- state = State.STREAM_ID;
- cursor = 0;
- streamId = 0;
- flags = 0;
- length = 0;
- }
-
- private enum State
- {
- STREAM_ID, STREAM_ID_BYTES, FLAGS, LENGTH, DATA
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/GoAwayBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/GoAwayBodyParser.java
deleted file mode 100644
index 8ad18fb03d..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/GoAwayBodyParser.java
+++ /dev/null
@@ -1,159 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.frames.GoAwayFrame;
-
-public class GoAwayBodyParser extends ControlFrameBodyParser
-{
- private final ControlFrameParser controlFrameParser;
- private State state = State.LAST_GOOD_STREAM_ID;
- private int cursor;
- private int lastStreamId;
- private int statusCode;
-
- public GoAwayBodyParser(ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case LAST_GOOD_STREAM_ID:
- {
- if (buffer.remaining() >= 4)
- {
- lastStreamId = buffer.getInt() & 0x7F_FF_FF_FF;
- switch (controlFrameParser.getVersion())
- {
- case SPDY.V2:
- {
- onGoAway();
- return true;
- }
- case SPDY.V3:
- {
- state = State.STATUS_CODE;
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- else
- {
- state = State.LAST_GOOD_STREAM_ID_BYTES;
- cursor = 4;
- }
- break;
- }
- case LAST_GOOD_STREAM_ID_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- lastStreamId += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- lastStreamId &= 0x7F_FF_FF_FF;
- switch (controlFrameParser.getVersion())
- {
- case SPDY.V2:
- {
- onGoAway();
- return true;
- }
- case SPDY.V3:
- {
- state = State.STATUS_CODE;
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- break;
- }
- case STATUS_CODE:
- {
- if (buffer.remaining() >= 4)
- {
- statusCode = buffer.getInt();
- onGoAway();
- return true;
- }
- else
- {
- state = State.STATUS_CODE_BYTES;
- cursor = 4;
- }
- break;
- }
- case STATUS_CODE_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- statusCode += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- onGoAway();
- return true;
- }
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- private void onGoAway()
- {
- GoAwayFrame frame = new GoAwayFrame(controlFrameParser.getVersion(), lastStreamId, statusCode);
- controlFrameParser.onControlFrame(frame);
- reset();
- }
-
- private void reset()
- {
- state = State.LAST_GOOD_STREAM_ID;
- cursor = 0;
- lastStreamId = 0;
- statusCode = 0;
- }
-
- private enum State
- {
- LAST_GOOD_STREAM_ID, LAST_GOOD_STREAM_ID_BYTES, STATUS_CODE, STATUS_CODE_BYTES
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/HeadersBlockParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/HeadersBlockParser.java
deleted file mode 100644
index 3c3d67f667..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/HeadersBlockParser.java
+++ /dev/null
@@ -1,230 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.zip.ZipException;
-
-import org.eclipse.jetty.spdy.CompressionDictionary;
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.SessionException;
-import org.eclipse.jetty.spdy.StreamException;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-
-public abstract class HeadersBlockParser
-{
- private final CompressionFactory.Decompressor decompressor;
- private byte[] data;
- private boolean needsDictionary = true;
-
- protected HeadersBlockParser(CompressionFactory.Decompressor decompressor)
- {
- this.decompressor = decompressor;
- }
-
- public boolean parse(int streamId, short version, int length, ByteBuffer buffer)
- {
- // Need to be sure that all the compressed data has arrived
- // Because SPDY uses SYNC_FLUSH mode, and the Java API
- // does not expose when decompression is finished with this mode
- // (but only when using NO_FLUSH), then we need to
- // accumulate the compressed bytes until we have all of them
-
- boolean accumulated = accumulate(length, buffer);
- if (!accumulated)
- return false;
-
- byte[] compressedHeaders = data;
- data = null;
- ByteBuffer decompressedHeaders = decompress(version, compressedHeaders);
-
- Charset iso1 = StandardCharsets.ISO_8859_1;
- // We know the decoded bytes contain the full headers,
- // so optimize instead of looping byte by byte
- int count = readCount(version, decompressedHeaders);
- for (int i = 0; i < count; ++i)
- {
- int nameLength = readNameLength(version, decompressedHeaders);
- if (nameLength == 0)
- throw new StreamException(streamId, StreamStatus.PROTOCOL_ERROR, "Invalid header name length");
- byte[] nameBytes = new byte[nameLength];
- decompressedHeaders.get(nameBytes);
- String name = new String(nameBytes, iso1);
-
- int valueLength = readValueLength(version, decompressedHeaders);
- if (valueLength == 0)
- throw new StreamException(streamId, StreamStatus.PROTOCOL_ERROR, "Invalid header value length");
- byte[] valueBytes = new byte[valueLength];
- decompressedHeaders.get(valueBytes);
- String value = new String(valueBytes, iso1);
- // Multi valued headers are separate by NUL
- String[] values = value.split("\u0000");
- // Check if there are multiple NULs (section 2.6.9)
- for (String v : values)
- if (v.length() == 0)
- throw new StreamException(streamId, StreamStatus.PROTOCOL_ERROR, "Invalid multi valued header");
-
- onHeader(name, values);
- }
-
- return true;
- }
-
- private boolean accumulate(int length, ByteBuffer buffer)
- {
- int remaining = buffer.remaining();
- if (data == null)
- {
- if (remaining < length)
- {
- data = new byte[remaining];
- buffer.get(data);
- return false;
- }
- else
- {
- data = new byte[length];
- buffer.get(data);
- return true;
- }
- }
- else
- {
- int accumulated = data.length;
- int needed = length - accumulated;
- if (remaining < needed)
- {
- byte[] local = Arrays.copyOf(data,accumulated + remaining);
- buffer.get(local, accumulated, remaining);
- data = local;
- return false;
- }
- else
- {
- byte[] local = Arrays.copyOf(data,length);
- buffer.get(local, accumulated, needed);
- data = local;
- return true;
- }
- }
- }
-
- private int readCount(int version, ByteBuffer buffer)
- {
- switch (version)
- {
- case SPDY.V2:
- return buffer.getShort();
- case SPDY.V3:
- return buffer.getInt();
- default:
- throw new IllegalStateException();
- }
- }
-
- private int readNameLength(int version, ByteBuffer buffer)
- {
- return readCount(version, buffer);
- }
-
- private int readValueLength(int version, ByteBuffer buffer)
- {
- return readCount(version, buffer);
- }
-
- protected abstract void onHeader(String name, String[] values);
-
- private ByteBuffer decompress(short version, byte[] compressed)
- {
- // Differently from compression, decompression always happens
- // non-concurrently because we read and parse with a single
- // thread, and therefore there is no need for synchronization.
-
- try
- {
- byte[] decompressed = null;
- byte[] buffer = new byte[compressed.length * 2];
- decompressor.setInput(compressed);
-
- while (true)
- {
- int count = decompressor.decompress(buffer);
- if (count == 0)
- {
- if (decompressed != null)
- {
- return ByteBuffer.wrap(decompressed);
- }
- else if (needsDictionary)
- {
- decompressor.setDictionary(CompressionDictionary.get(version));
- needsDictionary = false;
- }
- else
- {
- throw new IllegalStateException();
- }
- }
- else
- {
- if (count < buffer.length)
- {
- if (decompressed == null)
- {
- // Only one pass was needed to decompress
- return ByteBuffer.wrap(buffer, 0, count);
- }
- else
- {
- // Last pass needed to decompress, merge decompressed bytes
- byte[] result = Arrays.copyOf(decompressed,decompressed.length+count);
- System.arraycopy(buffer, 0, result, decompressed.length, count);
- return ByteBuffer.wrap(result);
- }
- }
- else
- {
- if (decompressed == null)
- {
- decompressed = buffer;
- buffer = new byte[buffer.length];
- }
- else
- {
- byte[] result = Arrays.copyOf(decompressed,decompressed.length+buffer.length);
- System.arraycopy(buffer, 0, result, decompressed.length, buffer.length);
- decompressed = result;
- }
- }
- }
- }
- }
- catch (ZipException x)
- {
- // We had a compression problem, and since the compression context
- // is per-connection, we need to tear down the connection
- throw new SessionException(SessionStatus.PROTOCOL_ERROR, x);
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/HeadersBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/HeadersBodyParser.java
deleted file mode 100644
index 47dfe2cea5..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/HeadersBodyParser.java
+++ /dev/null
@@ -1,173 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.frames.ControlFrameType;
-import org.eclipse.jetty.spdy.frames.HeadersFrame;
-import org.eclipse.jetty.util.Fields;
-
-public class HeadersBodyParser extends ControlFrameBodyParser
-{
- private final Fields headers = new Fields();
- private final ControlFrameParser controlFrameParser;
- private final HeadersBlockParser headersBlockParser;
- private State state = State.STREAM_ID;
- private int cursor;
- private int streamId;
-
- public HeadersBodyParser(CompressionFactory.Decompressor decompressor, ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- this.headersBlockParser = new HeadersHeadersBlockParser(decompressor);
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case STREAM_ID:
- {
- if (buffer.remaining() >= 4)
- {
- streamId = buffer.getInt() & 0x7F_FF_FF_FF;
- state = State.ADDITIONAL;
- }
- else
- {
- state = State.STREAM_ID_BYTES;
- cursor = 4;
- }
- break;
- }
- case STREAM_ID_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- streamId += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- streamId &= 0x7F_FF_FF_FF;
- state = State.ADDITIONAL;
- }
- break;
- }
- case ADDITIONAL:
- {
- switch (controlFrameParser.getVersion())
- {
- case SPDY.V2:
- {
- if (buffer.remaining() >= 2)
- {
- buffer.getShort();
- state = State.HEADERS;
- }
- else
- {
- state = State.ADDITIONAL_BYTES;
- cursor = 2;
- }
- break;
- }
- case SPDY.V3:
- {
- state = State.HEADERS;
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- break;
- }
- case ADDITIONAL_BYTES:
- {
- assert controlFrameParser.getVersion() == SPDY.V2;
- buffer.get();
- --cursor;
- if (cursor == 0)
- state = State.HEADERS;
- break;
- }
- case HEADERS:
- {
- short version = controlFrameParser.getVersion();
- int length = controlFrameParser.getLength() - 4;
- if (version == SPDY.V2)
- length -= 2;
- if (headersBlockParser.parse(streamId, version, length, buffer))
- {
- byte flags = controlFrameParser.getFlags();
- if (flags != 0 && flags != HeadersInfo.FLAG_CLOSE && flags != HeadersInfo.FLAG_RESET_COMPRESSION)
- throw new IllegalArgumentException("Invalid flag " + flags + " for frame " + ControlFrameType.HEADERS);
-
- HeadersFrame frame = new HeadersFrame(version, flags, streamId, new Fields(headers, true));
- controlFrameParser.onControlFrame(frame);
-
- reset();
- return true;
- }
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- private void reset()
- {
- headers.clear();
- state = State.STREAM_ID;
- cursor = 0;
- streamId = 0;
- }
-
- private enum State
- {
- STREAM_ID, STREAM_ID_BYTES, ADDITIONAL, ADDITIONAL_BYTES, HEADERS
- }
-
- private class HeadersHeadersBlockParser extends HeadersBlockParser
- {
- public HeadersHeadersBlockParser(CompressionFactory.Decompressor decompressor)
- {
- super(decompressor);
- }
-
- @Override
- protected void onHeader(String name, String[] values)
- {
- for (String value : values)
- headers.add(name, value);
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/NoOpBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/NoOpBodyParser.java
deleted file mode 100644
index 636ddc3fc2..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/NoOpBodyParser.java
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.frames.NoOpFrame;
-
-public class NoOpBodyParser extends ControlFrameBodyParser
-{
- private final ControlFrameParser controlFrameParser;
-
- public NoOpBodyParser(ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- NoOpFrame frame = new NoOpFrame();
- controlFrameParser.onControlFrame(frame);
- return true;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/Parser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/Parser.java
deleted file mode 100644
index 378f25689d..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/Parser.java
+++ /dev/null
@@ -1,240 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-import java.util.EventListener;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.SessionException;
-import org.eclipse.jetty.spdy.StreamException;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.DataFrame;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class Parser
-{
- private static final Logger logger = Log.getLogger(Parser.class);
- private final List<Listener> listeners = new CopyOnWriteArrayList<>();
- private final ControlFrameParser controlFrameParser;
- private final DataFrameParser dataFrameParser;
- private State state = State.CONTROL_BIT;
-
- public Parser(CompressionFactory.Decompressor decompressor)
- {
- // It is important to allocate one decompression context per
- // SPDY session for the control frames (to decompress the headers)
- controlFrameParser = new ControlFrameParser(decompressor)
- {
- @Override
- protected void onControlFrame(ControlFrame frame)
- {
- logger.debug("Parsed {}", frame);
- notifyControlFrame(frame);
- }
- };
- dataFrameParser = new DataFrameParser()
- {
- @Override
- protected void onDataFrame(DataFrame frame, ByteBuffer data)
- {
- logger.debug("Parsed {}, {} data bytes", frame, data.remaining());
- notifyDataFrame(frame, data);
- }
- };
- }
-
- public void addListener(Listener listener)
- {
- listeners.add(listener);
- }
-
- public void removeListener(Listener listener)
- {
- listeners.remove(listener);
- }
-
- protected void notifyControlFrame(ControlFrame frame)
- {
- for (Listener listener : listeners)
- {
- try
- {
- listener.onControlFrame(frame);
- }
- catch (Exception x)
- {
- logger.info("Exception while notifying listener " + listener, x);
- }
- }
- }
-
- protected void notifyDataFrame(DataFrame frame, ByteBuffer data)
- {
- for (Listener listener : listeners)
- {
- try
- {
- listener.onDataFrame(frame, data);
- }
- catch (Exception x)
- {
- logger.info("Exception while notifying listener " + listener, x);
- }
- }
- }
-
- protected void notifyStreamException(StreamException x)
- {
- for (Listener listener : listeners)
- {
- try
- {
- listener.onStreamException(x);
- }
- catch (Exception xx)
- {
- logger.debug("Could not notify listener " + listener, xx);
- }
- }
- }
-
- protected void notifySessionException(SessionException x)
- {
- logger.debug("SPDY session exception", x);
- for (Listener listener : listeners)
- {
- try
- {
- listener.onSessionException(x);
- }
- catch (Exception xx)
- {
- logger.debug("Could not notify listener " + listener, xx);
- }
- }
- }
-
- public void parse(ByteBuffer buffer)
- {
- logger.debug("Parsing {} bytes", buffer.remaining());
- try
- {
- while (buffer.hasRemaining())
- {
- try
- {
- switch (state)
- {
- case CONTROL_BIT:
- {
- // We must only peek the first byte and not advance the buffer
- // because the 7 least significant bits may be relevant in data frames
- int currByte = buffer.get(buffer.position());
- boolean isControlFrame = (currByte & 0x80) == 0x80;
- state = isControlFrame ? State.CONTROL_FRAME : State.DATA_FRAME;
- break;
- }
- case CONTROL_FRAME:
- {
- if (controlFrameParser.parse(buffer))
- reset();
- break;
- }
- case DATA_FRAME:
- {
- if (dataFrameParser.parse(buffer))
- reset();
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- catch (StreamException x)
- {
- notifyStreamException(x);
- }
- }
- }
- catch (SessionException x)
- {
- notifySessionException(x);
- }
- catch (Throwable x)
- {
- notifySessionException(new SessionException(SessionStatus.PROTOCOL_ERROR, x));
- }
- finally
- {
- // Be sure to consume after exceptions
- buffer.position(buffer.limit());
- }
- }
-
- private void reset()
- {
- state = State.CONTROL_BIT;
- }
-
- public interface Listener extends EventListener
- {
- public void onControlFrame(ControlFrame frame);
-
- public void onDataFrame(DataFrame frame, ByteBuffer data);
-
- public void onStreamException(StreamException x);
-
- public void onSessionException(SessionException x);
-
- public static class Adapter implements Listener
- {
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- }
-
- @Override
- public void onDataFrame(DataFrame frame, ByteBuffer data)
- {
- }
-
- @Override
- public void onStreamException(StreamException x)
- {
- }
-
- @Override
- public void onSessionException(SessionException x)
- {
- }
- }
- }
-
- private enum State
- {
- CONTROL_BIT, CONTROL_FRAME, DATA_FRAME
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/PingBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/PingBodyParser.java
deleted file mode 100644
index ad4a596f24..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/PingBodyParser.java
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.frames.PingFrame;
-
-public class PingBodyParser extends ControlFrameBodyParser
-{
- private final ControlFrameParser controlFrameParser;
- private State state = State.PING_ID;
- private int cursor;
- private int pingId;
-
- public PingBodyParser(ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case PING_ID:
- {
- if (buffer.remaining() >= 4)
- {
- pingId = buffer.getInt() & 0x7F_FF_FF_FF;
- onPing();
- return true;
- }
- else
- {
- state = State.PING_ID_BYTES;
- cursor = 4;
- }
- break;
- }
- case PING_ID_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- pingId += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- onPing();
- return true;
- }
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- private void onPing()
- {
- PingFrame frame = new PingFrame(controlFrameParser.getVersion(), pingId);
- controlFrameParser.onControlFrame(frame);
- reset();
- }
-
- private void reset()
- {
- state = State.PING_ID;
- cursor = 0;
- pingId = 0;
- }
-
- private enum State
- {
- PING_ID, PING_ID_BYTES
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/RstStreamBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/RstStreamBodyParser.java
deleted file mode 100644
index 175fea3ea9..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/RstStreamBodyParser.java
+++ /dev/null
@@ -1,127 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.frames.RstStreamFrame;
-
-public class RstStreamBodyParser extends ControlFrameBodyParser
-{
- private final ControlFrameParser controlFrameParser;
- private State state = State.STREAM_ID;
- private int cursor;
- private int streamId;
- private int statusCode;
-
- public RstStreamBodyParser(ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case STREAM_ID:
- {
- if (buffer.remaining() >= 4)
- {
- streamId = buffer.getInt() & 0x7F_FF_FF_FF;
- state = State.STATUS_CODE;
- }
- else
- {
- state = State.STREAM_ID_BYTES;
- cursor = 4;
- }
- break;
- }
- case STREAM_ID_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- streamId += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- streamId &= 0x7F_FF_FF_FF;
- state = State.STATUS_CODE;
- }
- break;
- }
- case STATUS_CODE:
- {
- if (buffer.remaining() >= 4)
- {
- statusCode = buffer.getInt();
- onRstStream();
- return true;
- }
- else
- {
- state = State.STATUS_CODE_BYTES;
- cursor = 4;
- }
- break;
- }
- case STATUS_CODE_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- statusCode += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- onRstStream();
- return true;
- }
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- private void onRstStream()
- {
- // TODO: check that statusCode is not 0
- RstStreamFrame frame = new RstStreamFrame(controlFrameParser.getVersion(), streamId, statusCode);
- controlFrameParser.onControlFrame(frame);
- reset();
- }
-
- private void reset()
- {
- state = State.STREAM_ID;
- cursor = 0;
- streamId = 0;
- statusCode = 0;
- }
-
- private enum State
- {
- STREAM_ID, STREAM_ID_BYTES, STATUS_CODE, STATUS_CODE_BYTES
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SettingsBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SettingsBodyParser.java
deleted file mode 100644
index bb9623a702..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SettingsBodyParser.java
+++ /dev/null
@@ -1,200 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Settings;
-import org.eclipse.jetty.spdy.frames.SettingsFrame;
-
-public class SettingsBodyParser extends ControlFrameBodyParser
-{
- private final Settings settings = new Settings();
- private final ControlFrameParser controlFrameParser;
- private State state = State.COUNT;
- private int cursor;
- private int count;
- private int idAndFlags;
- private int value;
-
- public SettingsBodyParser(ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case COUNT:
- {
- if (buffer.remaining() >= 4)
- {
- count = buffer.getInt();
- state = State.ID_FLAGS;
- }
- else
- {
- state = State.COUNT_BYTES;
- cursor = 4;
- }
- break;
- }
- case COUNT_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- count += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- state = State.ID_FLAGS;
- break;
- }
- case ID_FLAGS:
- {
- if (buffer.remaining() >= 4)
- {
- idAndFlags = convertIdAndFlags(controlFrameParser.getVersion(), buffer.getInt());
- state = State.VALUE;
- }
- else
- {
- state = State.ID_FLAGS_BYTES;
- cursor = 4;
- }
- break;
- }
- case ID_FLAGS_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- value += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- idAndFlags = convertIdAndFlags(controlFrameParser.getVersion(), value);
- state = State.VALUE;
- }
- break;
- }
- case VALUE:
- {
- if (buffer.remaining() >= 4)
- {
- value = buffer.getInt();
- if (onPair())
- return true;
- }
- else
- {
- state = State.VALUE_BYTES;
- cursor = 4;
- value = 0;
- }
- break;
- }
- case VALUE_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- value += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- if (onPair())
- return true;
- }
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- private int convertIdAndFlags(short version, int idAndFlags)
- {
- switch (version)
- {
- case SPDY.V2:
- {
- // A bug in the Chromium implementation forces v2 to have
- // 3 ID bytes little endian + 1 byte of flags
- // Here we normalize this to conform with v3, which is
- // 1 bytes of flag + 3 ID bytes big endian
- int result = (idAndFlags & 0x00_00_00_FF) << 24;
- result += (idAndFlags & 0x00_00_FF_00) << 8;
- result += (idAndFlags & 0x00_FF_00_00) >>> 8;
- result += (idAndFlags & 0xFF_00_00_00) >>> 24;
- return result;
- }
- case SPDY.V3:
- {
- return idAndFlags;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
-
- private boolean onPair()
- {
- int id = idAndFlags & 0x00_FF_FF_FF;
- byte flags = (byte)((idAndFlags & 0xFF_00_00_00) >>> 24);
- settings.put(new Settings.Setting(Settings.ID.from(id), Settings.Flag.from(flags), value));
- state = State.ID_FLAGS;
- idAndFlags = 0;
- value = 0;
- --count;
- if (count == 0)
- {
- onSettings();
- return true;
- }
- return false;
- }
-
- private void onSettings()
- {
- SettingsFrame frame = new SettingsFrame(controlFrameParser.getVersion(), controlFrameParser.getFlags(), new Settings(settings, true));
- controlFrameParser.onControlFrame(frame);
- reset();
- }
-
- private void reset()
- {
- settings.clear();
- state = State.COUNT;
- cursor = 0;
- count = 0;
- idAndFlags = 0;
- value = 0;
- }
-
- private enum State
- {
- COUNT, COUNT_BYTES, ID_FLAGS, ID_FLAGS_BYTES, VALUE, VALUE_BYTES
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SynReplyBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SynReplyBodyParser.java
deleted file mode 100644
index 8b35f3019a..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SynReplyBodyParser.java
+++ /dev/null
@@ -1,184 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.frames.ControlFrameType;
-import org.eclipse.jetty.spdy.frames.SynReplyFrame;
-import org.eclipse.jetty.util.Fields;
-
-public class SynReplyBodyParser extends ControlFrameBodyParser
-{
- private final Fields headers = new Fields();
- private final ControlFrameParser controlFrameParser;
- private final HeadersBlockParser headersBlockParser;
- private State state = State.STREAM_ID;
- private int cursor;
- private int streamId;
-
- public SynReplyBodyParser(CompressionFactory.Decompressor decompressor, ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- this.headersBlockParser = new SynReplyHeadersBlockParser(decompressor);
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case STREAM_ID:
- {
- if (buffer.remaining() >= 4)
- {
- streamId = buffer.getInt() & 0x7F_FF_FF_FF;
- state = State.ADDITIONAL;
- }
- else
- {
- state = State.STREAM_ID_BYTES;
- cursor = 4;
- }
- break;
- }
- case STREAM_ID_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- streamId += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- streamId &= 0x7F_FF_FF_FF;
- state = State.ADDITIONAL;
- }
- break;
- }
- case ADDITIONAL:
- {
- switch (controlFrameParser.getVersion())
- {
- case SPDY.V2:
- {
- if (buffer.remaining() >= 2)
- {
- buffer.getShort();
- state = State.HEADERS;
- }
- else
- {
- state = State.ADDITIONAL_BYTES;
- cursor = 2;
- }
- break;
- }
- case SPDY.V3:
- {
- state = State.HEADERS;
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- break;
- }
- case ADDITIONAL_BYTES:
- {
- assert controlFrameParser.getVersion() == SPDY.V2;
- buffer.get();
- --cursor;
- if (cursor == 0)
- state = State.HEADERS;
- break;
- }
- case HEADERS:
- {
- short version = controlFrameParser.getVersion();
- int length = controlFrameParser.getLength() - getSynReplyDataLength(version);
- if (headersBlockParser.parse(streamId, version, length, buffer))
- {
- byte flags = controlFrameParser.getFlags();
- if (flags != 0 && flags != ReplyInfo.FLAG_CLOSE)
- throw new IllegalArgumentException("Invalid flag " + flags + " for frame " + ControlFrameType.SYN_REPLY);
-
- SynReplyFrame frame = new SynReplyFrame(version, flags, streamId, new Fields(headers, true));
- controlFrameParser.onControlFrame(frame);
-
- reset();
- return true;
- }
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- private int getSynReplyDataLength(short version)
- {
- switch (version)
- {
- case 2:
- return 6;
- case 3:
- return 4;
- default:
- throw new IllegalStateException();
- }
- }
-
- private void reset()
- {
- headers.clear();
- state = State.STREAM_ID;
- cursor = 0;
- streamId = 0;
- }
-
- private enum State
- {
- STREAM_ID, STREAM_ID_BYTES, ADDITIONAL, ADDITIONAL_BYTES, HEADERS
- }
-
- private class SynReplyHeadersBlockParser extends HeadersBlockParser
- {
- public SynReplyHeadersBlockParser(CompressionFactory.Decompressor decompressor)
- {
- super(decompressor);
- }
-
- @Override
- protected void onHeader(String name, String[] values)
- {
- for (String value : values)
- headers.add(name, value);
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SynStreamBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SynStreamBodyParser.java
deleted file mode 100644
index 6b28214ded..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/SynStreamBodyParser.java
+++ /dev/null
@@ -1,236 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.PushSynInfo;
-import org.eclipse.jetty.spdy.StreamException;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.frames.ControlFrameType;
-import org.eclipse.jetty.spdy.frames.SynStreamFrame;
-import org.eclipse.jetty.util.Fields;
-
-public class SynStreamBodyParser extends ControlFrameBodyParser
-{
- private final Fields headers = new Fields();
- private final ControlFrameParser controlFrameParser;
- private final HeadersBlockParser headersBlockParser;
- private State state = State.STREAM_ID;
- private int cursor;
- private int streamId;
- private int associatedStreamId;
- private byte priority;
- private short slot;
-
- public SynStreamBodyParser(CompressionFactory.Decompressor decompressor, ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- this.headersBlockParser = new SynStreamHeadersBlockParser(decompressor);
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case STREAM_ID:
- {
- if (buffer.remaining() >= 4)
- {
- streamId = buffer.getInt() & 0x7F_FF_FF_FF;
- state = State.ASSOCIATED_STREAM_ID;
- }
- else
- {
- state = State.STREAM_ID_BYTES;
- cursor = 4;
- }
- break;
- }
- case STREAM_ID_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- streamId += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- streamId &= 0x7F_FF_FF_FF;
- state = State.ASSOCIATED_STREAM_ID;
- }
- break;
- }
- case ASSOCIATED_STREAM_ID:
- {
- // Now we know the streamId, we can do the version check
- // and if it is wrong, issue a RST_STREAM
- try
- {
- checkVersion(controlFrameParser.getVersion(), streamId);
- }
- catch (StreamException e)
- {
- // We've already read 4 bytes of the streamId which are part of controlFrameParser.getLength
- // so we need to substract those from the bytesToSkip.
- int bytesToSkip = controlFrameParser.getLength() - 4;
- int remaining = buffer.remaining();
- if (remaining >= bytesToSkip)
- {
- buffer.position(buffer.position() + bytesToSkip);
- controlFrameParser.reset();
- reset();
- }
- else
- {
- int bytesToSkipInNextBuffer = bytesToSkip - remaining;
- buffer.position(buffer.limit());
- controlFrameParser.skip(bytesToSkipInNextBuffer);
- reset();
- }
- throw e;
- }
- if (buffer.remaining() >= 4)
- {
- associatedStreamId = buffer.getInt() & 0x7F_FF_FF_FF;
- state = State.PRIORITY;
- }
- else
- {
- state = State.ASSOCIATED_STREAM_ID_BYTES;
- cursor = 4;
- }
- break;
- }
- case ASSOCIATED_STREAM_ID_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- associatedStreamId += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- associatedStreamId &= 0x7F_FF_FF_FF;
- state = State.PRIORITY;
- }
- break;
- }
- case PRIORITY:
- {
- byte currByte = buffer.get();
- ++cursor;
- if (cursor == 1)
- {
- priority = readPriority(controlFrameParser.getVersion(), currByte);
- }
- else
- {
- slot = (short)(currByte & 0xFF);
- cursor = 0;
- state = State.HEADERS;
- }
- break;
- }
- case HEADERS:
- {
- short version = controlFrameParser.getVersion();
- int length = controlFrameParser.getLength() - 10;
- if (headersBlockParser.parse(streamId, version, length, buffer))
- {
- byte flags = controlFrameParser.getFlags();
- if (flags > (SynInfo.FLAG_CLOSE | PushSynInfo.FLAG_UNIDIRECTIONAL))
- throw new IllegalArgumentException("Invalid flag " + flags + " for frame " +
- ControlFrameType.SYN_STREAM);
-
- SynStreamFrame frame = new SynStreamFrame(version, flags, streamId, associatedStreamId,
- priority, slot, new Fields(headers, false));
- controlFrameParser.onControlFrame(frame);
-
- reset();
- return true;
- }
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- private void checkVersion(short version, int streamId)
- {
- if (version != SPDY.V2 && version != SPDY.V3)
- throw new StreamException(streamId, StreamStatus.UNSUPPORTED_VERSION);
- }
-
- private byte readPriority(short version, byte currByte)
- {
- // Right shift retains the sign bit when operated on a byte,
- // so we use an int to perform the shifts
- switch (version)
- {
- case SPDY.V2:
- int p2 = currByte & 0b1100_0000;
- p2 >>>= 6;
- return (byte)p2;
- case SPDY.V3:
- int p3 = currByte & 0b1110_0000;
- p3 >>>= 5;
- return (byte)p3;
- default:
- throw new IllegalStateException();
- }
- }
-
- private void reset()
- {
- headers.clear();
- state = State.STREAM_ID;
- cursor = 0;
- streamId = 0;
- associatedStreamId = 0;
- priority = 0;
- }
-
- private enum State
- {
- STREAM_ID, STREAM_ID_BYTES, ASSOCIATED_STREAM_ID, ASSOCIATED_STREAM_ID_BYTES, PRIORITY, HEADERS
- }
-
- private class SynStreamHeadersBlockParser extends HeadersBlockParser
- {
- public SynStreamHeadersBlockParser(CompressionFactory.Decompressor decompressor)
- {
- super(decompressor);
- }
-
- @Override
- protected void onHeader(String name, String[] values)
- {
- for (String value : values)
- headers.add(name, value);
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/UnknownControlFrameBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/UnknownControlFrameBodyParser.java
deleted file mode 100644
index 2f7a008e2f..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/UnknownControlFrameBodyParser.java
+++ /dev/null
@@ -1,72 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-public class UnknownControlFrameBodyParser extends ControlFrameBodyParser
-{
- private final ControlFrameParser controlFrameParser;
- private State state = State.BODY;
- private int remaining;
-
- public UnknownControlFrameBodyParser(ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- switch (state)
- {
- case BODY:
- {
- remaining = controlFrameParser.getLength();
- state = State.CONSUME;
- // Fall down
- }
- case CONSUME:
- {
- int consume = Math.min(remaining, buffer.remaining());
- buffer.position(buffer.position() + consume);
- remaining -= consume;
- if (remaining > 0)
- return false;
- reset();
- return true;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
-
- private void reset()
- {
- state = State.BODY;
- remaining = 0;
- }
-
- private enum State
- {
- BODY, CONSUME
- }
-}
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/WindowUpdateBodyParser.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/WindowUpdateBodyParser.java
deleted file mode 100644
index f55ecd4d9d..0000000000
--- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/parser/WindowUpdateBodyParser.java
+++ /dev/null
@@ -1,127 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
-
-public class WindowUpdateBodyParser extends ControlFrameBodyParser
-{
- private final ControlFrameParser controlFrameParser;
- private State state = State.STREAM_ID;
- private int cursor;
- private int streamId;
- private int windowDelta;
-
- public WindowUpdateBodyParser(ControlFrameParser controlFrameParser)
- {
- this.controlFrameParser = controlFrameParser;
- }
-
- @Override
- public boolean parse(ByteBuffer buffer)
- {
- while (buffer.hasRemaining())
- {
- switch (state)
- {
- case STREAM_ID:
- {
- if (buffer.remaining() >= 4)
- {
- streamId = buffer.getInt() & 0x7F_FF_FF_FF;
- state = State.WINDOW_DELTA;
- }
- else
- {
- state = State.STREAM_ID_BYTES;
- cursor = 4;
- }
- break;
- }
- case STREAM_ID_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- streamId += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- streamId &= 0x7F_FF_FF_FF;
- state = State.WINDOW_DELTA;
- }
- break;
- }
- case WINDOW_DELTA:
- {
- if (buffer.remaining() >= 4)
- {
- windowDelta = buffer.getInt() & 0x7F_FF_FF_FF;
- onWindowUpdate();
- return true;
- }
- else
- {
- state = State.WINDOW_DELTA_BYTES;
- cursor = 4;
- }
- break;
- }
- case WINDOW_DELTA_BYTES:
- {
- byte currByte = buffer.get();
- --cursor;
- windowDelta += (currByte & 0xFF) << 8 * cursor;
- if (cursor == 0)
- {
- windowDelta &= 0x7F_FF_FF_FF;
- onWindowUpdate();
- return true;
- }
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
- return false;
- }
-
- private void onWindowUpdate()
- {
- WindowUpdateFrame frame = new WindowUpdateFrame(controlFrameParser.getVersion(), streamId, windowDelta);
- controlFrameParser.onControlFrame(frame);
- reset();
- }
-
- private void reset()
- {
- state = State.STREAM_ID;
- cursor = 0;
- streamId = 0;
- windowDelta = 0;
- }
-
- private enum State
- {
- STREAM_ID, STREAM_ID_BYTES, WINDOW_DELTA, WINDOW_DELTA_BYTES;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java
deleted file mode 100644
index 969d72e790..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.io.ByteArrayEndPoint;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.SPDYException;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.toolchain.test.AdvancedRunner;
-import org.eclipse.jetty.toolchain.test.annotation.Slow;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.thread.Scheduler;
-import org.eclipse.jetty.util.thread.TimerScheduler;
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AdvancedRunner.class)
-//TODO: Uncomment comment lines and reimplement tests to fit new design
-@Ignore("Doesn't work with new Flusher class, needs to be rewritten")
-public class AsyncTimeoutTest
-{
- EndPoint endPoint = new ByteArrayEndPoint();
-
- @Slow
- @Test
- public void testAsyncTimeoutInControlFrames() throws Exception
- {
- final long timeout = 1000;
- final TimeUnit unit = TimeUnit.MILLISECONDS;
-
- ByteBufferPool bufferPool = new MappedByteBufferPool();
- Executor threadPool = Executors.newCachedThreadPool();
- Scheduler scheduler = new TimerScheduler();
- scheduler.start(); // TODO need to use jetty lifecycles better here
- Generator generator = new Generator(bufferPool, new StandardCompressionFactory.StandardCompressor());
- Session session = new StandardSession(SPDY.V2, bufferPool, scheduler, new TestController(),
- endPoint, null, 1, null, generator, new FlowControlStrategy.None())
- {
-// @Override
- public void flush()
- {
- try
- {
- unit.sleep(2 * timeout);
-// super.flush();
- }
- catch (InterruptedException x)
- {
- throw new SPDYException(x);
- }
- }
- };
-
- final CountDownLatch failedLatch = new CountDownLatch(1);
- session.syn(new SynInfo(timeout, unit, new Fields(), true, (byte)0), null, new Promise.Adapter<Stream>()
- {
- @Override
- public void failed(Throwable x)
- {
- failedLatch.countDown();
- }
- });
-
- Assert.assertTrue(failedLatch.await(2 * timeout, unit));
- }
-
- @Slow
- @Test
- public void testAsyncTimeoutInDataFrames() throws Exception
- {
- final long timeout = 1000;
- final TimeUnit unit = TimeUnit.MILLISECONDS;
-
- ByteBufferPool bufferPool = new MappedByteBufferPool();
- Executor threadPool = Executors.newCachedThreadPool();
- Scheduler scheduler = new TimerScheduler();
- scheduler.start();
- Generator generator = new Generator(bufferPool, new StandardCompressionFactory.StandardCompressor());
- Session session = new StandardSession(SPDY.V2, bufferPool, scheduler, new TestController(),
- endPoint, null, 1, null, generator, new FlowControlStrategy.None())
- {
-// @Override
- protected void write(ByteBuffer buffer, Callback callback)
- {
- try
- {
- // Wait if we're writing the data frame (control frame's first byte is 0x80)
- if (buffer.get(0) == 0)
- unit.sleep(2 * timeout);
-// super.write(buffer, callback);
- }
- catch (InterruptedException x)
- {
- throw new SPDYException(x);
- }
- }
- };
-
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
- final CountDownLatch failedLatch = new CountDownLatch(1);
- stream.data(new StringDataInfo(timeout, unit, "data", true), new Callback.Adapter()
- {
- @Override
- public void failed(Throwable x)
- {
- failedLatch.countDown();
- }
- });
-
- Assert.assertTrue(failedLatch.await(2 * timeout, unit));
- }
-
- private static class TestController implements Controller
- {
- @Override
- public void write(Callback callback, ByteBuffer... buffers)
- {
- callback.succeeded();
- }
-
- @Override
- public void close(boolean onlyOutput)
- {
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java
deleted file mode 100644
index 80bd21c0b7..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java
+++ /dev/null
@@ -1,681 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.nio.ByteBuffer;
-import java.nio.channels.ClosedChannelException;
-import java.util.HashSet;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Settings;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.frames.DataFrame;
-import org.eclipse.jetty.spdy.frames.SettingsFrame;
-import org.eclipse.jetty.spdy.frames.SynReplyFrame;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.FuturePromise;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
-import org.eclipse.jetty.util.thread.Scheduler;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.mockito.stubbing.Answer;
-
-import static org.hamcrest.Matchers.greaterThan;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public class StandardSessionTest
-{
- private static final Logger LOG = Log.getLogger(StandardSessionTest.class);
- private static final short VERSION = SPDY.V2;
-
- @Mock
- private Controller controller;
-
- @Mock
- private EndPoint endPoint;
-
- private ExecutorService threadPool;
- private StandardSession session;
- private Scheduler scheduler;
- private Fields headers;
- private final ByteBufferPool bufferPool = new MappedByteBufferPool();
- private final Generator generator = new Generator(bufferPool, new StandardCompressionFactory.StandardCompressor());
-
- @Before
- public void setUp() throws Exception
- {
- threadPool = Executors.newCachedThreadPool();
- scheduler = new ScheduledExecutorScheduler();
- scheduler.start();
- session = new StandardSession(VERSION, bufferPool, scheduler, controller, endPoint, null, 1, null,
- generator, new FlowControlStrategy.None());
- when(endPoint.getIdleTimeout()).thenReturn(30000L);
- headers = new Fields();
- }
-
- @After
- public void after() throws Exception
- {
- scheduler.stop();
- threadPool.shutdownNow();
- }
-
- @SuppressWarnings("unchecked")
- private void setControllerWriteExpectation(final boolean fail)
- {
- doAnswer(new Answer()
- {
- public Object answer(InvocationOnMock invocation)
- {
- Object[] args = invocation.getArguments();
- Callback callback = (Callback)args[0];
- if (fail)
- callback.failed(new ClosedChannelException());
- else
- callback.succeeded();
- return null;
- }
- }).when(controller).write(any(Callback.class), any(ByteBuffer.class));
- }
-
- @Test
- public void testStreamIsRemovedFromSessionWhenReset() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = createStream();
- assertThatStreamIsInSession(stream);
- assertThat("stream is not reset", stream.isReset(), is(false));
- session.rst(new RstInfo(stream.getId(), StreamStatus.STREAM_ALREADY_CLOSED));
- assertThatStreamIsNotInSession(stream);
- assertThatStreamIsReset(stream);
- }
-
- @Test
- public void testStreamIsAddedAndRemovedFromSession() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = createStream();
- assertThatStreamIsInSession(stream);
- stream.updateCloseState(true, true);
- session.onControlFrame(new SynReplyFrame(VERSION, SynInfo.FLAG_CLOSE, stream.getId(), null));
- assertThatStreamIsClosed(stream);
- assertThatStreamIsNotInSession(stream);
- }
-
- @Test
- public void testStreamIsRemovedWhenHeadersWithCloseFlagAreSent() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = createStream();
- assertThatStreamIsInSession(stream);
- stream.updateCloseState(true, false);
- stream.headers(new HeadersInfo(headers, true));
- assertThatStreamIsClosed(stream);
- assertThatStreamIsNotInSession(stream);
- }
-
- @Test
- public void testStreamIsUnidirectional() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = createStream();
- assertThat("stream is not unidirectional", stream.isUnidirectional(), not(true));
- Stream pushStream = createPushStream(stream);
- assertThat("pushStream is unidirectional", pushStream.isUnidirectional(), is(true));
- }
-
- @Test
- public void testPushStreamCreation() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- Stream stream = createStream();
- IStream pushStream = createPushStream(stream);
- assertThat("Push stream must be associated to the first stream created", pushStream.getAssociatedStream().getId(), is(stream.getId()));
- assertThat("streamIds need to be monotonic", pushStream.getId(), greaterThan(stream.getId()));
- }
-
- @Test
- public void testPushStreamIsNotClosedWhenAssociatedStreamIsClosed() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = createStream();
- Stream pushStream = createPushStream(stream);
- assertThatStreamIsNotHalfClosed(stream);
- assertThatStreamIsNotClosed(stream);
- assertThatPushStreamIsHalfClosed(pushStream);
- assertThatPushStreamIsNotClosed(pushStream);
-
- stream.updateCloseState(true, true);
- assertThatStreamIsHalfClosed(stream);
- assertThatStreamIsNotClosed(stream);
- assertThatPushStreamIsHalfClosed(pushStream);
- assertThatPushStreamIsNotClosed(pushStream);
-
- session.onControlFrame(new SynReplyFrame(VERSION, SynInfo.FLAG_CLOSE, stream.getId(), null));
- assertThatStreamIsClosed(stream);
- assertThatPushStreamIsNotClosed(pushStream);
- }
-
- @Test
- public void testCreatePushStreamOnClosedStream() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = createStream();
- stream.updateCloseState(true, true);
- assertThatStreamIsHalfClosed(stream);
- stream.updateCloseState(true, false);
- assertThatStreamIsClosed(stream);
- createPushStreamAndMakeSureItFails(stream);
- }
-
- private void createPushStreamAndMakeSureItFails(IStream stream) throws InterruptedException
- {
- final CountDownLatch failedLatch = new CountDownLatch(1);
- PushInfo pushInfo = new PushInfo(5, TimeUnit.SECONDS, headers, false);
- stream.push(pushInfo, new Promise.Adapter<Stream>()
- {
- @Override
- public void failed(Throwable x)
- {
- failedLatch.countDown();
- }
- });
- assertThat("pushStream creation failed", failedLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testPushStreamIsAddedAndRemovedFromParentAndSessionWhenClosed() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = createStream();
- IStream pushStream = createPushStream(stream);
- assertThatPushStreamIsHalfClosed(pushStream);
- assertThatPushStreamIsInSession(pushStream);
- assertThatStreamIsAssociatedWithPushStream(stream, pushStream);
- session.data(pushStream, new StringDataInfo("close", true), 5, TimeUnit.SECONDS, new Callback.Adapter());
- assertThatPushStreamIsClosed(pushStream);
- assertThatPushStreamIsNotInSession(pushStream);
- assertThatStreamIsNotAssociatedWithPushStream(stream, pushStream);
- }
-
- @Test
- public void testPushStreamIsRemovedWhenReset() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = createStream();
- IStream pushStream = (IStream)stream.push(new PushInfo(new Fields(), false));
- assertThatPushStreamIsInSession(pushStream);
- session.rst(new RstInfo(pushStream.getId(), StreamStatus.INVALID_STREAM));
- assertThatPushStreamIsNotInSession(pushStream);
- assertThatStreamIsNotAssociatedWithPushStream(stream, pushStream);
- assertThatStreamIsReset(pushStream);
- }
-
- @Test
- public void testPushStreamWithSynInfoClosedTrue() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = createStream();
- PushInfo pushInfo = new PushInfo(5, TimeUnit.SECONDS, headers, true);
- IStream pushStream = (IStream)stream.push(pushInfo);
- assertThatPushStreamIsHalfClosed(pushStream);
- assertThatPushStreamIsClosed(pushStream);
- assertThatStreamIsNotAssociatedWithPushStream(stream, pushStream);
- assertThatStreamIsNotInSession(pushStream);
- }
-
- @Test
- public void testPushStreamSendHeadersWithCloseFlagIsRemovedFromSessionAndDisassociateFromParent() throws InterruptedException, ExecutionException,
- TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = createStream();
- PushInfo pushInfo = new PushInfo(5, TimeUnit.SECONDS, headers, false);
- IStream pushStream = (IStream)stream.push(pushInfo);
- assertThatStreamIsAssociatedWithPushStream(stream, pushStream);
- assertThatPushStreamIsInSession(pushStream);
- pushStream.headers(new HeadersInfo(headers, true));
- assertThatPushStreamIsNotInSession(pushStream);
- assertThatPushStreamIsHalfClosed(pushStream);
- assertThatPushStreamIsClosed(pushStream);
- assertThatStreamIsNotAssociatedWithPushStream(stream, pushStream);
- }
-
- @Test
- public void testCreatedAndClosedListenersAreCalledForNewStream() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- final CountDownLatch createdListenerCalledLatch = new CountDownLatch(1);
- final CountDownLatch closedListenerCalledLatch = new CountDownLatch(1);
- session.addListener(new TestStreamListener(createdListenerCalledLatch, closedListenerCalledLatch));
- IStream stream = createStream();
- session.onControlFrame(new SynReplyFrame(VERSION, (byte)0, stream.getId(), new Fields()));
- session.onDataFrame(new DataFrame(stream.getId(), SynInfo.FLAG_CLOSE, 128), ByteBuffer.allocate(128));
- stream.data(new StringDataInfo("close", true));
- assertThat("onStreamCreated listener has been called", createdListenerCalledLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThatOnStreamClosedListenerHasBeenCalled(closedListenerCalledLatch);
- }
-
- @Test
- public void testListenerIsCalledForResetStream() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- final CountDownLatch closedListenerCalledLatch = new CountDownLatch(1);
- session.addListener(new TestStreamListener(null, closedListenerCalledLatch));
- IStream stream = createStream();
- session.rst(new RstInfo(stream.getId(), StreamStatus.CANCEL_STREAM));
- assertThatOnStreamClosedListenerHasBeenCalled(closedListenerCalledLatch);
- }
-
- @Test
- public void testCreatedAndClosedListenersAreCalledForNewPushStream() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- final CountDownLatch createdListenerCalledLatch = new CountDownLatch(2);
- final CountDownLatch closedListenerCalledLatch = new CountDownLatch(1);
- session.addListener(new TestStreamListener(createdListenerCalledLatch, closedListenerCalledLatch));
- IStream stream = createStream();
- IStream pushStream = createPushStream(stream);
- session.data(pushStream, new StringDataInfo("close", true), 5, TimeUnit.SECONDS, new Callback.Adapter());
- assertThat("onStreamCreated listener has been called twice. Once for the stream and once for the pushStream",
- createdListenerCalledLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThatOnStreamClosedListenerHasBeenCalled(closedListenerCalledLatch);
- }
-
- @Test
- public void testListenerIsCalledForResetPushStream() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- final CountDownLatch closedListenerCalledLatch = new CountDownLatch(1);
- session.addListener(new TestStreamListener(null, closedListenerCalledLatch));
- IStream stream = createStream();
- IStream pushStream = createPushStream(stream);
- session.rst(new RstInfo(pushStream.getId(), StreamStatus.CANCEL_STREAM));
- assertThatOnStreamClosedListenerHasBeenCalled(closedListenerCalledLatch);
- }
-
- private class TestStreamListener extends Session.StreamListener.Adapter
- {
- private CountDownLatch createdListenerCalledLatch;
- private CountDownLatch closedListenerCalledLatch;
-
- public TestStreamListener(CountDownLatch createdListenerCalledLatch, CountDownLatch closedListenerCalledLatch)
- {
- this.createdListenerCalledLatch = createdListenerCalledLatch;
- this.closedListenerCalledLatch = closedListenerCalledLatch;
- }
-
- @Override
- public void onStreamCreated(Stream stream)
- {
- if (createdListenerCalledLatch != null)
- createdListenerCalledLatch.countDown();
- super.onStreamCreated(stream);
- }
-
- @Override
- public void onStreamClosed(Stream stream)
- {
- if (closedListenerCalledLatch != null)
- closedListenerCalledLatch.countDown();
- super.onStreamClosed(stream);
- }
- }
-
- @Test
- @Ignore("In V3 we need to rst the stream if we receive data on a remotely half closed stream.")
- public void receiveDataOnRemotelyHalfClosedStreamResetsStreamInV3() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- IStream stream = (IStream)session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter());
- stream.updateCloseState(true, false);
- assertThat("stream is half closed from remote side", stream.isHalfClosed(), is(true));
- stream.process(new ByteBufferDataInfo(ByteBuffer.allocate(256), true));
- }
-
- @Test
- public void testReceiveDataOnRemotelyClosedStreamIsIgnored() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- final CountDownLatch onDataCalledLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- onDataCalledLatch.countDown();
- super.onData(stream, dataInfo);
- }
- });
- session.onControlFrame(new SynReplyFrame(VERSION, SynInfo.FLAG_CLOSE, stream.getId(), headers));
- session.onDataFrame(new DataFrame(stream.getId(), (byte)0, 0), ByteBuffer.allocate(128));
- assertThat("onData is never called", onDataCalledLatch.await(1, TimeUnit.SECONDS), not(true));
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testControllerWriteFails() throws Exception
- {
- final AtomicInteger writes = new AtomicInteger();
- final AtomicBoolean fail = new AtomicBoolean();
- Controller controller = new Controller()
- {
- @Override
- public void write(Callback callback, ByteBuffer... buffers)
- {
- writes.incrementAndGet();
- if (fail.get())
- callback.failed(new ClosedChannelException());
- else
- callback.succeeded();
- }
-
- @Override
- public void close(boolean onlyOutput)
- {
-
- }
- };
- ISession session = new StandardSession(VERSION, bufferPool, scheduler, controller, endPoint, null, 1, null, generator, null);
- IStream stream = new StandardStream(1, (byte)0, session, null, scheduler, null);
- stream.updateWindowSize(8192);
-
- // Send a reply to comply with the API usage
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
-
- // Make the controller fail
- fail.set(true);
- final CountDownLatch failedCalledLatch = new CountDownLatch(1);
- Callback.Adapter callback = new Callback.Adapter()
- {
- @Override
- public void failed(Throwable x)
- {
- failedCalledLatch.countDown();
- }
- };
- // Data frame should fail on controller.write()
- stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "data", false), callback);
-
- Assert.assertEquals(2, writes.get());
- Assert.assertTrue(failedCalledLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testControlFramesAreStillSentForResetStreams() throws InterruptedException, ExecutionException, TimeoutException
- {
- setControllerWriteExpectation(false);
-
- // This is necessary to keep the compression context of Headers valid
- IStream stream = createStream();
- session.rst(new RstInfo(stream.getId(), StreamStatus.INVALID_STREAM));
- stream.headers(new HeadersInfo(headers, true));
-
- verify(controller, times(3)).write(any(Callback.class), any(ByteBuffer.class));
- }
-
- @Test
- public void testMaxConcurrentStreams() throws InterruptedException
- {
- final CountDownLatch failedBecauseMaxConcurrentStreamsExceeded = new CountDownLatch(1);
-
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.MAX_CONCURRENT_STREAMS, 0));
- SettingsFrame settingsFrame = new SettingsFrame(VERSION, (byte)0, settings);
- session.onControlFrame(settingsFrame);
-
- PushSynInfo pushSynInfo = new PushSynInfo(1, new PushInfo(new Fields(), false));
- session.syn(pushSynInfo, null, new Promise.Adapter<Stream>()
- {
- @Override
- public void failed(Throwable x)
- {
- failedBecauseMaxConcurrentStreamsExceeded.countDown();
- }
- });
-
- assertThat("Opening push stream failed because maxConcurrentStream is exceeded",
- failedBecauseMaxConcurrentStreamsExceeded.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testHeaderFramesAreSentInTheOrderTheyAreCreated() throws ExecutionException,
- TimeoutException, InterruptedException
- {
- testHeaderFramesAreSentInOrder((byte)0, (byte)0, (byte)0);
- }
-
- @Test
- public void testHeaderFramesAreSentInTheOrderTheyAreCreatedWithPrioritization() throws ExecutionException,
- TimeoutException, InterruptedException
- {
- testHeaderFramesAreSentInOrder((byte)0, (byte)1, (byte)2);
- }
-
- private void testHeaderFramesAreSentInOrder(final byte priority0, final byte priority1, final byte priority2) throws InterruptedException, ExecutionException
- {
- final StandardSession testLocalSession = new StandardSession(VERSION, bufferPool, scheduler,
- new ControllerMock(), endPoint, null, 1, null, generator, new FlowControlStrategy.None());
- HashSet<Future> tasks = new HashSet<>();
-
- int numberOfTasksToRun = 128;
- for (int i = 0; i < numberOfTasksToRun; i++)
- {
- tasks.add(threadPool.submit(new Runnable()
- {
-
- @Override
- public void run()
- {
- synStream(priority0);
- synStream(priority1);
- synStream(priority2);
- }
-
- private void synStream(byte priority)
- {
- SynInfo synInfo = new SynInfo(headers, false, priority);
- testLocalSession.syn(synInfo, new StreamFrameListener.Adapter(), new FuturePromise<Stream>());
- }
- }));
- }
-
- for (Future task : tasks)
- {
- task.get();
- }
-
- threadPool.shutdown();
- threadPool.awaitTermination(60, TimeUnit.SECONDS);
- }
-
- private class ControllerMock implements Controller
- {
- long lastStreamId = 0;
-
- @Override
- public void write(Callback callback, ByteBuffer... buffers)
- {
- StandardSession.FrameBytes frameBytes = (StandardSession.FrameBytes)callback;
-
- int streamId = frameBytes.getStream().getId();
- if (LOG.isDebugEnabled())
- LOG.debug("last: {}, current: {}", lastStreamId, streamId);
- if (lastStreamId < streamId)
- lastStreamId = streamId;
- else
- throw new IllegalStateException("Last streamId: " + lastStreamId + " is not smaller than current StreamId: " +
- streamId);
- frameBytes.succeeded();
- }
-
- @Override
- public void close(boolean onlyOutput)
- {
- }
- }
-
- private IStream createStream() throws InterruptedException, ExecutionException, TimeoutException
- {
- SynInfo synInfo = new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0);
- return (IStream)session.syn(synInfo, new StreamFrameListener.Adapter());
- }
-
- private IStream createPushStream(Stream stream) throws InterruptedException, ExecutionException, TimeoutException
- {
- PushInfo pushInfo = new PushInfo(5, TimeUnit.SECONDS, headers, false);
- return (IStream)stream.push(pushInfo);
- }
-
- private void assertThatStreamIsClosed(IStream stream)
- {
- assertThat("stream is closed", stream.isClosed(), is(true));
- }
-
- private void assertThatStreamIsReset(IStream stream)
- {
- assertThat("stream is reset", stream.isReset(), is(true));
- }
-
- private void assertThatStreamIsNotInSession(IStream stream)
- {
- assertThat("stream is not in session", session.getStreams().contains(stream), not(true));
- }
-
- private void assertThatStreamIsInSession(IStream stream)
- {
- assertThat("stream is in session", session.getStreams().contains(stream), is(true));
- }
-
- private void assertThatStreamIsNotClosed(IStream stream)
- {
- assertThat("stream is not closed", stream.isClosed(), not(true));
- }
-
- private void assertThatStreamIsNotHalfClosed(IStream stream)
- {
- assertThat("stream is not halfClosed", stream.isHalfClosed(), not(true));
- }
-
- private void assertThatPushStreamIsNotClosed(Stream pushStream)
- {
- assertThat("pushStream is not closed", pushStream.isClosed(), not(true));
- }
-
- private void assertThatStreamIsHalfClosed(IStream stream)
- {
- assertThat("stream is halfClosed", stream.isHalfClosed(), is(true));
- }
-
- private void assertThatStreamIsNotAssociatedWithPushStream(IStream stream, IStream pushStream)
- {
- assertThat("pushStream is removed from parent", stream.getPushedStreams().contains(pushStream), not(true));
- }
-
- private void assertThatPushStreamIsNotInSession(Stream pushStream)
- {
- assertThat("pushStream is not in session", session.getStreams().contains(pushStream), not(true));
- }
-
- private void assertThatPushStreamIsInSession(Stream pushStream)
- {
- assertThat("pushStream is in session", session.getStreams().contains(pushStream), is(true));
- }
-
- private void assertThatStreamIsAssociatedWithPushStream(IStream stream, Stream pushStream)
- {
- assertThat("stream is associated with pushStream", stream.getPushedStreams().contains(pushStream), is(true));
- }
-
- private void assertThatPushStreamIsClosed(Stream pushStream)
- {
- assertThat("pushStream is closed", pushStream.isClosed(), is(true));
- }
-
- private void assertThatPushStreamIsHalfClosed(Stream pushStream)
- {
- assertThat("pushStream is half closed ", pushStream.isHalfClosed(), is(true));
- }
-
- private void assertThatOnStreamClosedListenerHasBeenCalled(final CountDownLatch closedListenerCalledLatch) throws InterruptedException
- {
- assertThat("onStreamClosed listener has been called", closedListenerCalledLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardStreamTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardStreamTest.java
deleted file mode 100644
index ee79f8138e..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardStreamTest.java
+++ /dev/null
@@ -1,258 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy;
-
-import java.nio.channels.ClosedChannelException;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.SynStreamFrame;
-import org.eclipse.jetty.toolchain.test.annotation.Slow;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public class StandardStreamTest
-{
- private final ScheduledExecutorScheduler scheduler = new ScheduledExecutorScheduler();
- @Mock
- private ISession session;
- @Mock
- private SynStreamFrame synStreamFrame;
-
- @Before
- public void setUp() throws Exception
- {
- scheduler.start();
- }
-
- @After
- public void tearDown() throws Exception
- {
- scheduler.stop();
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testSyn()
- {
- Stream stream = new StandardStream(synStreamFrame.getStreamId(), synStreamFrame.getPriority(), session, null, null, null);
- Set<Stream> streams = new HashSet<>();
- streams.add(stream);
- when(synStreamFrame.isClose()).thenReturn(false);
- PushInfo pushInfo = new PushInfo(new Fields(), false);
- when(session.getStreams()).thenReturn(streams);
- stream.push(pushInfo, new Promise.Adapter<Stream>());
- verify(session).syn(argThat(new PushSynInfoMatcher(stream.getId(), pushInfo)),
- any(StreamFrameListener.class), any(Promise.class));
- }
-
- private class PushSynInfoMatcher extends ArgumentMatcher<PushSynInfo>
- {
- private int associatedStreamId;
- private PushInfo pushInfo;
-
- public PushSynInfoMatcher(int associatedStreamId, PushInfo pushInfo)
- {
- this.associatedStreamId = associatedStreamId;
- this.pushInfo = pushInfo;
- }
-
- @Override
- public boolean matches(Object argument)
- {
- PushSynInfo pushSynInfo = (PushSynInfo)argument;
- return pushSynInfo.getAssociatedStreamId() == associatedStreamId && pushSynInfo.isClose() == pushInfo.isClose();
- }
- }
-
- @Test
- public void testSynOnClosedStream()
- {
- IStream stream = new StandardStream(synStreamFrame.getStreamId(), synStreamFrame.getPriority(), session,
- null, null , null);
- stream.updateCloseState(true, true);
- stream.updateCloseState(true, false);
- assertThat("stream expected to be closed", stream.isClosed(), is(true));
- final CountDownLatch failedLatch = new CountDownLatch(1);
- stream.push(new PushInfo(1, TimeUnit.SECONDS, new Fields(), false), new Promise.Adapter<Stream>()
- {
- @Override
- public void failed(Throwable x)
- {
- failedLatch.countDown();
- }
- });
- assertThat("PushStream creation failed", failedLatch.getCount(), equalTo(0L));
- }
-
- @SuppressWarnings("unchecked")
- @Test(expected = IllegalStateException.class)
- public void testSendDataOnHalfClosedStream() throws InterruptedException, ExecutionException, TimeoutException
- {
- SynStreamFrame synStreamFrame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, null);
- IStream stream = new StandardStream(synStreamFrame.getStreamId(), synStreamFrame.getPriority(), session,
- null, scheduler, null);
- stream.updateWindowSize(8192);
- stream.updateCloseState(synStreamFrame.isClose(), true);
- assertThat("stream is half closed", stream.isHalfClosed(), is(true));
- stream.data(new StringDataInfo("data on half closed stream", true));
- verify(session, never()).data(any(IStream.class), any(DataInfo.class), anyInt(), any(TimeUnit.class), any(Callback.class));
- }
-
- @Test
- @Slow
- public void testIdleTimeout() throws Exception
- {
- IStream stream = new StandardStream(1, (byte)0, session, null, scheduler, null);
- long idleTimeout = 500;
- stream.setIdleTimeout(idleTimeout);
-
- final AtomicInteger failureCount = new AtomicInteger();
- final CountDownLatch failureLatch = new CountDownLatch(1);
- stream.setStreamFrameListener(new StreamFrameListener.Adapter()
- {
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- assertThat("exception is a TimeoutException", x, is(instanceOf(TimeoutException.class)));
- failureCount.incrementAndGet();
- failureLatch.countDown();
- }
- });
- stream.process(new StringDataInfo("string", false));
-
- // Wait more than (2 * idleTimeout) to be sure to trigger a failureCount > 1
- Thread.sleep(3 * idleTimeout);
-
- assertThat("onFailure has been called", failureLatch.await(5, TimeUnit.SECONDS), is(true));
- Assert.assertEquals(1, failureCount.get());
- }
-
- @Test
- @Slow
- public void testIdleTimeoutIsInterruptedWhenReceiving() throws Exception
- {
- final CountDownLatch failureLatch = new CountDownLatch(1);
- IStream stream = new StandardStream(1, (byte)0, session, null, scheduler, null);
- long idleTimeout = 1000;
- stream.setIdleTimeout(idleTimeout);
- stream.setStreamFrameListener(new StreamFrameListener.Adapter()
- {
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- assertThat("exception is a TimeoutException", x, is(instanceOf(TimeoutException.class)));
- failureLatch.countDown();
- }
- });
- stream.process(new SynStreamFrame(SPDY.V3, (byte)0, 1, 0, (byte)0, (short)0, null));
- stream.process(new StringDataInfo("string", false));
- Thread.sleep(idleTimeout / 2);
- stream.process(new StringDataInfo("string", false));
- Thread.sleep(idleTimeout / 2);
- stream.process(new StringDataInfo("string", false));
- Thread.sleep(idleTimeout / 2);
- stream.process(new StringDataInfo("string", true));
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- Thread.sleep(idleTimeout);
- assertThat("onFailure has not been called", failureLatch.await(idleTimeout, TimeUnit.MILLISECONDS), is(false));
- }
-
- @Test
- @Slow
- public void testReplyFailureClosesStream() throws Exception
- {
- ISession session = new StandardSession(SPDY.V3, null, null, null, null, null, 1, null, null, null)
- {
- @Override
- public void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback callback)
- {
- callback.failed(new ClosedChannelException());
- }
- };
- IStream stream = new StandardStream(1, (byte)0, session, null, scheduler, null);
- final AtomicInteger failureCount = new AtomicInteger();
- stream.setStreamFrameListener(new StreamFrameListener.Adapter()
- {
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- failureCount.incrementAndGet();
- }
- });
- long idleTimeout = 500;
- stream.setIdleTimeout(idleTimeout);
-
- stream.process(new SynStreamFrame(SPDY.V3, (byte)0, 1, 0, (byte)0, (short)0, null));
-
- final CountDownLatch failureLatch = new CountDownLatch(1);
- stream.reply(new ReplyInfo(false), new Callback.Adapter()
- {
- @Override
- public void failed(Throwable x)
- {
- failureLatch.countDown();
- }
- });
-
- Assert.assertTrue(failureLatch.await(5, TimeUnit.SECONDS));
-
- // Make sure that the idle timeout never fires, since the failure above should have closed the stream
- Thread.sleep(3 * idleTimeout);
-
- Assert.assertEquals(0, failureCount.get());
- Assert.assertTrue(stream.isClosed());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/api/ClientUsageTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/api/ClientUsageTest.java
deleted file mode 100644
index bd1ea53757..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/api/ClientUsageTest.java
+++ /dev/null
@@ -1,260 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import java.nio.charset.StandardCharsets;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.eclipse.jetty.spdy.StandardSession;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.junit.Ignore;
-import org.junit.Test;
-
-@Ignore
-public class ClientUsageTest
-{
- @Test
- public void testClientRequestResponseNoBody() throws Exception
- {
- Session session = new StandardSession(SPDY.V2, null, null, null, null, null, 1, null, null, null);
-
- session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- // Do something with the response
- replyInfo.getHeaders().get("host");
-
- // Then issue another similar request
- try
- {
- stream.getSession().syn(new SynInfo(new Fields(), true), this);
- }
- catch (ExecutionException | InterruptedException | TimeoutException e)
- {
- throw new IllegalStateException(e);
- }
- }
- });
- }
-
- @Test
- public void testClientReceivesPush1() throws InterruptedException, ExecutionException, TimeoutException
- {
- Session session = new StandardSession(SPDY.V2, null, null, null, null, null, 1, null, null, null);
-
- session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
- {
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- }
- };
- };
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- // Do something with the response
- replyInfo.getHeaders().get("host");
-
- // Then issue another similar request
- try
- {
- stream.getSession().syn(new SynInfo(new Fields(), true), this);
- }
- catch (ExecutionException | InterruptedException | TimeoutException e)
- {
- throw new IllegalStateException(e);
- }
- }
- });
- }
-
- @Test
- public void testClientReceivesPush2() throws InterruptedException, ExecutionException, TimeoutException
- {
- Session session = new StandardSession(SPDY.V2, null, null, null, null, null, 1, new SessionFrameListener.Adapter()
- {
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- }
- };
- }
- }, null, null);
-
- session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- // Do something with the response
- replyInfo.getHeaders().get("host");
-
- // Then issue another similar request
- try
- {
- stream.getSession().syn(new SynInfo(new Fields(), true), this);
- }
- catch (ExecutionException | InterruptedException | TimeoutException e)
- {
- throw new IllegalStateException(e);
- }
- }
- });
- }
-
- @Test
- public void testClientRequestWithBodyResponseNoBody() throws Exception
- {
- Session session = new StandardSession(SPDY.V2, null, null, null, null, null, 1, null, null, null);
-
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- // Do something with the response
- replyInfo.getHeaders().get("host");
-
- // Then issue another similar request
- try
- {
- stream.getSession().syn(new SynInfo(new Fields(), true), this);
- }
- catch (ExecutionException | InterruptedException | TimeoutException e)
- {
- throw new IllegalStateException(e);
- }
- }
- });
- // Send-and-forget the data
- stream.data(new StringDataInfo("data", true));
- }
-
- @Test
- public void testAsyncClientRequestWithBodyResponseNoBody() throws Exception
- {
- Session session = new StandardSession(SPDY.V2, null, null, null, null, null, 1, null, null, null);
-
- final String context = "context";
- session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- // Do something with the response
- replyInfo.getHeaders().get("host");
-
- // Then issue another similar request
- try
- {
- stream.getSession().syn(new SynInfo(new Fields(), true), this);
- }
- catch (ExecutionException | InterruptedException | TimeoutException e)
- {
- throw new IllegalStateException(e);
- }
- }
- }, new Promise.Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream stream)
- {
- // Differently from JDK 7 AIO, there is no need to
- // have an explicit parameter for the context since
- // that is captured while the handler is created anyway,
- // and it is used only by the handler as parameter
-
- // The style below is fire-and-forget, since
- // we do not pass the handler nor we call get()
- // to wait for the data to be sent
- stream.data(new StringDataInfo(context, true), new Callback.Adapter());
- }
- }
- );
- }
-
- @Test
- public void testAsyncClientRequestWithBodyAndResponseWithBody() throws Exception
- {
- Session session = new StandardSession(SPDY.V2, null, null, null, null, null, 1, null, null, null);
-
- session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
- {
- // The good of passing the listener to push() is that applications can safely
- // accumulate info from the reply headers to be used in the data callback,
- // e.g. content-type, charset, etc.
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- // Do something with the response
- Fields headers = replyInfo.getHeaders();
- int contentLength = headers.get("content-length").getValueAsInt();
- stream.setAttribute("content-length", contentLength);
- if (!replyInfo.isClose())
- stream.setAttribute("builder", new StringBuilder());
-
- // May issue another similar request while waiting for data
- try
- {
- stream.getSession().syn(new SynInfo(new Fields(), true), this);
- }
- catch (ExecutionException | InterruptedException | TimeoutException e)
- {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- StringBuilder builder = (StringBuilder)stream.getAttribute("builder");
- builder.append(dataInfo.asString(StandardCharsets.UTF_8, true));
-
- }
- }, new Promise.Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream stream)
- {
- stream.data(new BytesDataInfo("wee".getBytes(StandardCharsets.UTF_8), false), new Callback.Adapter());
- stream.data(new StringDataInfo("foo", false), new Callback.Adapter());
- stream.data(new ByteBufferDataInfo(StandardCharsets.UTF_8.encode("bar"), true), new Callback.Adapter());
- }
- }
- );
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/api/ServerUsageTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/api/ServerUsageTest.java
deleted file mode 100644
index 88a94ac1d9..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/api/ServerUsageTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.api;
-
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-
-@Ignore
-public class ServerUsageTest
-{
- @Test
- public void testServerSynAndReplyWithData() throws Exception
- {
- ServerSessionFrameListener ssfl = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo streamInfo)
- {
- Fields synHeaders = streamInfo.getHeaders();
- // Do something with headers, for example extract them and
- // perform an http request via Jetty's LocalConnector
-
- // Get the http response, fill headers and data
- Fields replyHeaders = new Fields();
- replyHeaders.put(synHeaders.get("host"));
- // Sends a reply
- stream.reply(new ReplyInfo(replyHeaders, false), new Callback.Adapter());
-
- // Sends data
- StringDataInfo dataInfo = new StringDataInfo("foo", false);
- stream.data(dataInfo, new Callback.Adapter());
- // Stream is now closed
- return null;
- }
- };
- Assert.assertNotNull(ssfl);
- }
-
- @Test
- public void testServerInitiatesStreamAndPushesData() throws Exception
- {
- ServerSessionFrameListener ssfl = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onConnect(Session session)
- {
- // SPDY does not allow the server to initiate a stream without an existing stream
- // being opened by the client already.
- // Correct SPDY sequence will be:
- // C --- SYN_STREAM(id=1) --> S
- // C <-- SYN_REPLY(id=1) --- S
- // C <-- SYN_STREAM(id=2,uni,assId=1) --- S
- //
- // However, the API may allow to initiate the stream
-
- session.syn(new SynInfo(new Fields(), false), null, new Promise.Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream stream)
- {
- // The point here is that we have no idea if the client accepted our stream
- // So we return a stream, we may be able to send the headers frame, but later
- // the client sends a rst frame.
- // We have to atomically set some flag on the stream to signal it's closed
- // and any operation on it will throw
- stream.headers(new HeadersInfo(new Fields(), true), new Callback.Adapter());
- }
- });
- }
- };
- Assert.assertNotNull(ssfl);
- }
-
- @Test
- public void testServerPush() throws Exception
- {
- ServerSessionFrameListener ssfl = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo streamInfo)
- {
- // Need to send the reply first
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
-
- Session session = stream.getSession();
- // Since it's unidirectional, no need to pass the listener
- session.syn(new SynInfo(new Fields(), false, (byte)0), null, new Promise.Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream pushStream)
- {
- pushStream.data(new StringDataInfo("foo", false), new Callback.Adapter());
- }
- });
- return null;
- }
- };
- Assert.assertNotNull(ssfl);
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/CredentialGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/CredentialGenerateParseTest.java
deleted file mode 100644
index e1c10ec0ea..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/CredentialGenerateParseTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.security.KeyStore;
-import java.security.cert.Certificate;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.util.resource.Resource;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class CredentialGenerateParseTest
-{
- @Test
- public void testGenerateParse() throws Exception
- {
- short slot = 1;
- byte[] proof = new byte[]{0, 1, 2};
- Certificate[] temp = loadCertificates();
- Certificate[] certificates = new Certificate[temp.length * 2];
- System.arraycopy(temp, 0, certificates, 0, temp.length);
- System.arraycopy(temp, 0, certificates, temp.length, temp.length);
- CredentialFrame frame1 = new CredentialFrame(SPDY.V3, slot, proof, certificates);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- parser.parse(buffer);
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.CREDENTIAL, frame2.getType());
- CredentialFrame credential = (CredentialFrame)frame2;
- Assert.assertEquals(SPDY.V3, credential.getVersion());
- Assert.assertEquals(0, credential.getFlags());
- Assert.assertEquals(slot, credential.getSlot());
- Assert.assertArrayEquals(proof, credential.getProof());
- Assert.assertArrayEquals(certificates, credential.getCertificateChain());
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- short slot = 1;
- byte[] proof = new byte[]{0, 1, 2};
- Certificate[] certificates = loadCertificates();
- CredentialFrame frame1 = new CredentialFrame(SPDY.V3, slot, proof, certificates);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- while (buffer.hasRemaining())
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.CREDENTIAL, frame2.getType());
- CredentialFrame credential = (CredentialFrame)frame2;
- Assert.assertEquals(SPDY.V3, credential.getVersion());
- Assert.assertEquals(0, credential.getFlags());
- Assert.assertEquals(slot, credential.getSlot());
- Assert.assertArrayEquals(proof, credential.getProof());
- Assert.assertArrayEquals(certificates, credential.getCertificateChain());
- }
-
- private Certificate[] loadCertificates() throws Exception
- {
- KeyStore keyStore = KeyStore.getInstance("JKS");
- InputStream keyStoreStream = Resource.newResource("src/test/resources/keystore.jks").getInputStream();
- keyStore.load(keyStoreStream, "storepwd".toCharArray());
- return keyStore.getCertificateChain("mykey");
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/DataGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/DataGenerateParseTest.java
deleted file mode 100644
index a209fe895b..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/DataGenerateParseTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class DataGenerateParseTest
-{
- @Test
- public void testGenerateParse() throws Exception
- {
- testGenerateParse("test1");
- }
-
- @Test
- public void testGenerateParseZeroLength() throws Exception
- {
- testGenerateParse("");
- }
-
- private void testGenerateParse(String content) throws Exception
- {
- int length = content.length();
- DataInfo data = new StringDataInfo(content, true);
- int streamId = 13;
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.data(streamId, 2 * length, data);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- parser.parse(buffer);
- DataFrame frame2 = listener.getDataFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(streamId, frame2.getStreamId());
- Assert.assertEquals(DataInfo.FLAG_CLOSE, frame2.getFlags());
- Assert.assertEquals(length, frame2.getLength());
- Assert.assertEquals(length, listener.getData().remaining());
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- String content = "test2";
- int length = content.length();
- DataInfo data = new StringDataInfo(content, true);
- int streamId = 13;
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.data(streamId, 2 * length, data);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- while (buffer.hasRemaining())
- {
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
- if (buffer.remaining() < length)
- {
- DataFrame frame2 = listener.getDataFrame();
- Assert.assertNotNull(frame2);
- Assert.assertEquals(streamId, frame2.getStreamId());
- Assert.assertEquals(buffer.hasRemaining() ? 0 : DataInfo.FLAG_CLOSE, frame2.getFlags());
- Assert.assertEquals(1, frame2.getLength());
- Assert.assertEquals(1, listener.getData().remaining());
- }
- }
- }
-
- @Test
- public void testGenerateParseWithSyntheticFrames() throws Exception
- {
- String content = "0123456789ABCDEF";
- int length = content.length();
- DataInfo data = new StringDataInfo(content, true);
- int streamId = 13;
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.data(streamId, 2 * length, data);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
-
- // Split the buffer to simulate a split boundary in receiving the bytes
- int split = 3;
- ByteBuffer buffer1 = ByteBuffer.allocate(buffer.remaining() - split);
- buffer.limit(buffer.limit() - split);
- buffer1.put(buffer);
- buffer1.flip();
- ByteBuffer buffer2 = ByteBuffer.allocate(split);
- buffer.limit(buffer.limit() + split);
- buffer2.put(buffer);
- buffer2.flip();
-
- parser.parse(buffer1);
- DataFrame frame2 = listener.getDataFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(streamId, frame2.getStreamId());
- Assert.assertEquals(0, frame2.getFlags());
- Assert.assertEquals(length - split, frame2.getLength());
- Assert.assertEquals(length - split, listener.getData().remaining());
-
- parser.parse(buffer2);
- DataFrame frame3 = listener.getDataFrame();
-
- Assert.assertNotNull(frame3);
- Assert.assertEquals(streamId, frame3.getStreamId());
- Assert.assertEquals(DataInfo.FLAG_CLOSE, frame3.getFlags());
- Assert.assertEquals(split, frame3.getLength());
- Assert.assertEquals(split, listener.getData().remaining());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/GoAwayGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/GoAwayGenerateParseTest.java
deleted file mode 100644
index 11ce7ea7cc..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/GoAwayGenerateParseTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class GoAwayGenerateParseTest
-{
- @Test
- public void testGenerateParse() throws Exception
- {
- int lastStreamId = 13;
- int statusCode = 1;
- GoAwayFrame frame1 = new GoAwayFrame(SPDY.V3, lastStreamId, statusCode);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- parser.parse(buffer);
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.GO_AWAY, frame2.getType());
- GoAwayFrame goAway = (GoAwayFrame)frame2;
- Assert.assertEquals(SPDY.V3, goAway.getVersion());
- Assert.assertEquals(lastStreamId, goAway.getLastStreamId());
- Assert.assertEquals(0, goAway.getFlags());
- Assert.assertEquals(statusCode, goAway.getStatusCode());
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- int lastStreamId = 13;
- int statusCode = 1;
- GoAwayFrame frame1 = new GoAwayFrame(SPDY.V3, lastStreamId, statusCode);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- while (buffer.hasRemaining())
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.GO_AWAY, frame2.getType());
- GoAwayFrame goAway = (GoAwayFrame)frame2;
- Assert.assertEquals(SPDY.V3, goAway.getVersion());
- Assert.assertEquals(lastStreamId, goAway.getLastStreamId());
- Assert.assertEquals(0, goAway.getFlags());
- Assert.assertEquals(statusCode, goAway.getStatusCode());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/HeadersGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/HeadersGenerateParseTest.java
deleted file mode 100644
index 03c3cd4cfb..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/HeadersGenerateParseTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertThat;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Before;
-import org.junit.Test;
-
-public class HeadersGenerateParseTest
-{
-
- private Fields headers = new Fields();
- private int streamId = 13;
- private byte flags = HeadersInfo.FLAG_RESET_COMPRESSION;
- private final TestSPDYParserListener listener = new TestSPDYParserListener();
- private final Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- private ByteBuffer buffer;
-
- @Before
- public void setUp()
- {
- parser.addListener(listener);
- headers.put("a", "b");
- buffer = createHeadersFrameBuffer(headers);
- }
-
- private ByteBuffer createHeadersFrameBuffer(Fields headers)
- {
- HeadersFrame frame1 = new HeadersFrame(SPDY.V2, flags, streamId, headers);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
- assertThat("Buffer is not null", buffer, notNullValue());
- return buffer;
- }
-
- @Test
- public void testGenerateParse() throws Exception
- {
- parser.parse(buffer);
- assertExpectationsAreMet(headers);
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- while (buffer.hasRemaining())
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
-
- assertExpectationsAreMet(headers);
- }
-
- @Test
- public void testHeadersAreTranslatedToLowerCase()
- {
- Fields headers = new Fields();
- headers.put("Via","localhost");
- parser.parse(createHeadersFrameBuffer(headers));
- HeadersFrame parsedHeadersFrame = assertExpectationsAreMet(headers);
- Fields.Field viaHeader = parsedHeadersFrame.getHeaders().get("via");
- assertThat("Via Header name is lowercase", viaHeader.getName(), is("via"));
- }
-
- private HeadersFrame assertExpectationsAreMet(Fields headers)
- {
- ControlFrame parsedControlFrame = listener.getControlFrame();
- assertThat("listener received controlFrame", parsedControlFrame, notNullValue());
- assertThat("ControlFrame type is HEADERS", ControlFrameType.HEADERS, is(parsedControlFrame.getType()));
- HeadersFrame headersFrame = (HeadersFrame)parsedControlFrame;
- assertThat("Version matches", SPDY.V2, is(headersFrame.getVersion()));
- assertThat("StreamId matches", streamId, is(headersFrame.getStreamId()));
- assertThat("flags match", flags, is(headersFrame.getFlags()));
- assertThat("headers match", headers, is(headersFrame.getHeaders()));
- return headersFrame;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/NoOpGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/NoOpGenerateParseTest.java
deleted file mode 100644
index 7795337fbc..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/NoOpGenerateParseTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class NoOpGenerateParseTest
-{
- @Test
- public void testGenerateParse() throws Exception
- {
- NoOpFrame frame1 = new NoOpFrame();
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- parser.parse(buffer);
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.NOOP, frame2.getType());
- NoOpFrame noOp = (NoOpFrame)frame2;
- Assert.assertEquals(0, noOp.getFlags());
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- NoOpFrame frame1 = new NoOpFrame();
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- while (buffer.hasRemaining())
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.NOOP, frame2.getType());
- NoOpFrame noOp = (NoOpFrame)frame2;
- Assert.assertEquals(0, noOp.getFlags());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/PingGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/PingGenerateParseTest.java
deleted file mode 100644
index f34ed5759d..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/PingGenerateParseTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class PingGenerateParseTest
-{
- @Test
- public void testGenerateParse() throws Exception
- {
- int pingId = 13;
- PingFrame frame1 = new PingFrame(SPDY.V2, pingId);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- parser.parse(buffer);
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.PING, frame2.getType());
- PingFrame ping = (PingFrame)frame2;
- Assert.assertEquals(SPDY.V2, ping.getVersion());
- Assert.assertEquals(pingId, ping.getPingId());
- Assert.assertEquals(0, ping.getFlags());
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- int pingId = 13;
- PingFrame frame1 = new PingFrame(SPDY.V2, pingId);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- while (buffer.hasRemaining())
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.PING, frame2.getType());
- PingFrame ping = (PingFrame)frame2;
- Assert.assertEquals(SPDY.V2, ping.getVersion());
- Assert.assertEquals(pingId, ping.getPingId());
- Assert.assertEquals(0, ping.getFlags());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/RstStreamGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/RstStreamGenerateParseTest.java
deleted file mode 100644
index 8bc8710e55..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/RstStreamGenerateParseTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertThat;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class RstStreamGenerateParseTest
-{
- @Test
- public void testGenerateParse() throws Exception
- {
- int streamId = 13;
- int streamStatus = StreamStatus.UNSUPPORTED_VERSION.getCode(SPDY.V2);
- RstStreamFrame frame1 = new RstStreamFrame(SPDY.V2, streamId, streamStatus);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- assertThat("buffer is not null", buffer, not(nullValue()));
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- parser.parse(buffer);
- ControlFrame frame2 = listener.getControlFrame();
-
- assertThat("frame2 is not null", frame2, not(nullValue()));
- assertThat("frame2 is type RST_STREAM",ControlFrameType.RST_STREAM, equalTo(frame2.getType()));
- RstStreamFrame rstStream = (RstStreamFrame)frame2;
- assertThat("rstStream version is SPDY.V2",SPDY.V2, equalTo(rstStream.getVersion()));
- assertThat("rstStream id is equal to streamId",streamId, equalTo(rstStream.getStreamId()));
- assertThat("rstStream flags are 0",(byte)0, equalTo(rstStream.getFlags()));
- assertThat("stream status is equal to rstStream statuscode",streamStatus, is(rstStream.getStatusCode()));
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- int streamId = 13;
- int streamStatus = StreamStatus.UNSUPPORTED_VERSION.getCode(SPDY.V2);
- RstStreamFrame frame1 = new RstStreamFrame(SPDY.V2, streamId, streamStatus);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- while (buffer.hasRemaining())
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.RST_STREAM, frame2.getType());
- RstStreamFrame rstStream = (RstStreamFrame)frame2;
- Assert.assertEquals(SPDY.V2, rstStream.getVersion());
- Assert.assertEquals(streamId, rstStream.getStreamId());
- Assert.assertEquals(0, rstStream.getFlags());
- Assert.assertEquals(streamStatus, rstStream.getStatusCode());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SettingsGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SettingsGenerateParseTest.java
deleted file mode 100644
index adf9760220..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SettingsGenerateParseTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Settings;
-import org.eclipse.jetty.spdy.api.SettingsInfo;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SettingsGenerateParseTest
-{
- @Test
- public void testGenerateParse() throws Exception
- {
- byte flags = SettingsInfo.CLEAR_PERSISTED;
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.MAX_CONCURRENT_STREAMS, Settings.Flag.PERSIST, 100));
- settings.put(new Settings.Setting(Settings.ID.ROUND_TRIP_TIME, Settings.Flag.PERSISTED, 500));
- SettingsFrame frame1 = new SettingsFrame(SPDY.V2, flags, settings);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- parser.parse(buffer);
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.SETTINGS, frame2.getType());
- SettingsFrame settingsFrame = (SettingsFrame)frame2;
- Assert.assertEquals(SPDY.V2, settingsFrame.getVersion());
- Assert.assertEquals(flags, settingsFrame.getFlags());
- Assert.assertEquals(settings, settingsFrame.getSettings());
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- byte flags = SettingsInfo.CLEAR_PERSISTED;
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.DOWNLOAD_RETRANSMISSION_RATE, 100));
- settings.put(new Settings.Setting(Settings.ID.ROUND_TRIP_TIME, 500));
- SettingsFrame frame1 = new SettingsFrame(SPDY.V2, flags, settings);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- while (buffer.hasRemaining())
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.SETTINGS, frame2.getType());
- SettingsFrame settingsFrame = (SettingsFrame)frame2;
- Assert.assertEquals(SPDY.V2, settingsFrame.getVersion());
- Assert.assertEquals(flags, settingsFrame.getFlags());
- Assert.assertEquals(settings, settingsFrame.getSettings());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SynReplyGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SynReplyGenerateParseTest.java
deleted file mode 100644
index 61c5cc5ec1..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SynReplyGenerateParseTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SynReplyGenerateParseTest
-{
- @Test
- public void testGenerateParse() throws Exception
- {
- byte flags = ReplyInfo.FLAG_CLOSE;
- int streamId = 13;
- Fields headers = new Fields();
- headers.put("a", "b");
- SynReplyFrame frame1 = new SynReplyFrame(SPDY.V2, flags, streamId, headers);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- parser.parse(buffer);
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.SYN_REPLY, frame2.getType());
- SynReplyFrame synReply = (SynReplyFrame)frame2;
- Assert.assertEquals(SPDY.V2, synReply.getVersion());
- Assert.assertEquals(flags, synReply.getFlags());
- Assert.assertEquals(streamId, synReply.getStreamId());
- Assert.assertEquals(headers, synReply.getHeaders());
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- byte flags = ReplyInfo.FLAG_CLOSE;
- int streamId = 13;
- Fields headers = new Fields();
- headers.put("a", "b");
- SynReplyFrame frame1 = new SynReplyFrame(SPDY.V2, flags, streamId, headers);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- while (buffer.hasRemaining())
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.SYN_REPLY, frame2.getType());
- SynReplyFrame synReply = (SynReplyFrame)frame2;
- Assert.assertEquals(SPDY.V2, synReply.getVersion());
- Assert.assertEquals(flags, synReply.getFlags());
- Assert.assertEquals(streamId, synReply.getStreamId());
- Assert.assertEquals(headers, synReply.getHeaders());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SynStreamGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SynStreamGenerateParseTest.java
deleted file mode 100644
index 0eeb55cfd9..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/SynStreamGenerateParseTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SynStreamGenerateParseTest
-{
- @Test
- public void testGenerateParse() throws Exception
- {
- byte flags = SynInfo.FLAG_CLOSE;
- int streamId = 13;
- int associatedStreamId = 11;
- byte priority = 3;
- short slot = 5;
- Fields headers = new Fields();
- headers.put("a", "b");
- headers.put("c", "d");
- SynStreamFrame frame1 = new SynStreamFrame(SPDY.V2, flags, streamId, associatedStreamId, priority, slot, headers);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- parser.parse(buffer);
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.SYN_STREAM, frame2.getType());
- SynStreamFrame synStream = (SynStreamFrame)frame2;
- Assert.assertEquals(SPDY.V2, synStream.getVersion());
- Assert.assertEquals(streamId, synStream.getStreamId());
- Assert.assertEquals(associatedStreamId, synStream.getAssociatedStreamId());
- Assert.assertEquals(flags, synStream.getFlags());
- Assert.assertEquals(priority, synStream.getPriority());
- Assert.assertEquals(slot, synStream.getSlot());
- Assert.assertEquals(headers, synStream.getHeaders());
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- byte flags = SynInfo.FLAG_CLOSE;
- int streamId = 13;
- int associatedStreamId = 11;
- byte priority = 3;
- short slot = 5;
- Fields headers = new Fields();
- headers.put("a", "b");
- headers.put("c", "d");
- SynStreamFrame frame1 = new SynStreamFrame(SPDY.V2, flags, streamId, associatedStreamId, priority, slot, headers);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- while (buffer.hasRemaining())
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.SYN_STREAM, frame2.getType());
- SynStreamFrame synStream = (SynStreamFrame)frame2;
- Assert.assertEquals(SPDY.V2, synStream.getVersion());
- Assert.assertEquals(streamId, synStream.getStreamId());
- Assert.assertEquals(associatedStreamId, synStream.getAssociatedStreamId());
- Assert.assertEquals(flags, synStream.getFlags());
- Assert.assertEquals(priority, synStream.getPriority());
- Assert.assertEquals(slot, synStream.getSlot());
- Assert.assertEquals(headers, synStream.getHeaders());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/TestSPDYParserListener.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/TestSPDYParserListener.java
deleted file mode 100644
index 3d6d5b3ece..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/TestSPDYParserListener.java
+++ /dev/null
@@ -1,70 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.spdy.SessionException;
-import org.eclipse.jetty.spdy.StreamException;
-import org.eclipse.jetty.spdy.parser.Parser;
-
-public class TestSPDYParserListener implements Parser.Listener
-{
- private ControlFrame controlFrame;
- private DataFrame dataFrame;
- private ByteBuffer data;
-
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- this.controlFrame = frame;
- }
-
- @Override
- public void onDataFrame(DataFrame frame, ByteBuffer data)
- {
- this.dataFrame = frame;
- this.data = data;
- }
-
- @Override
- public void onStreamException(StreamException x)
- {
- }
-
- @Override
- public void onSessionException(SessionException x)
- {
- }
-
- public ControlFrame getControlFrame()
- {
- return controlFrame;
- }
-
- public DataFrame getDataFrame()
- {
- return dataFrame;
- }
-
- public ByteBuffer getData()
- {
- return data;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/WindowUpdateGenerateParseTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/WindowUpdateGenerateParseTest.java
deleted file mode 100644
index 24689350f6..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/frames/WindowUpdateGenerateParseTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.frames;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class WindowUpdateGenerateParseTest
-{
- @Test
- public void testGenerateParse() throws Exception
- {
- int streamId = 13;
- int windowDelta = 17;
- WindowUpdateFrame frame1 = new WindowUpdateFrame(SPDY.V2, streamId, windowDelta);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- parser.parse(buffer);
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.WINDOW_UPDATE, frame2.getType());
- WindowUpdateFrame windowUpdate = (WindowUpdateFrame)frame2;
- Assert.assertEquals(SPDY.V2, windowUpdate.getVersion());
- Assert.assertEquals(streamId, windowUpdate.getStreamId());
- Assert.assertEquals(0, windowUpdate.getFlags());
- Assert.assertEquals(windowDelta, windowUpdate.getWindowDelta());
- }
-
- @Test
- public void testGenerateParseOneByteAtATime() throws Exception
- {
- int streamId = 13;
- int windowDelta = 17;
- WindowUpdateFrame frame1 = new WindowUpdateFrame(SPDY.V2, streamId, windowDelta);
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- ByteBuffer buffer = generator.control(frame1);
-
- Assert.assertNotNull(buffer);
-
- TestSPDYParserListener listener = new TestSPDYParserListener();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(listener);
- while (buffer.hasRemaining())
- parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
- ControlFrame frame2 = listener.getControlFrame();
-
- Assert.assertNotNull(frame2);
- Assert.assertEquals(ControlFrameType.WINDOW_UPDATE, frame2.getType());
- WindowUpdateFrame windowUpdate = (WindowUpdateFrame)frame2;
- Assert.assertEquals(SPDY.V2, windowUpdate.getVersion());
- Assert.assertEquals(streamId, windowUpdate.getStreamId());
- Assert.assertEquals(0, windowUpdate.getFlags());
- Assert.assertEquals(windowDelta, windowUpdate.getWindowDelta());
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/generator/DataFrameGeneratorTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/generator/DataFrameGeneratorTest.java
deleted file mode 100644
index b0c972c770..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/generator/DataFrameGeneratorTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.generator;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.ThreadLocalRandom;
-
-import org.eclipse.jetty.io.ArrayByteBufferPool;
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.frames.DataFrame;
-import org.eclipse.jetty.util.BufferUtil;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class DataFrameGeneratorTest
-{
- private int increment = 1024;
- private int streamId = 1;
- private ArrayByteBufferPool bufferPool;
- private DataFrameGenerator dataFrameGenerator;
- private ByteBuffer headerBuffer = ByteBuffer.allocate(DataFrame.HEADER_LENGTH);
-
- @Before
- public void setUp()
- {
- bufferPool = new ArrayByteBufferPool(64, increment, 8192);
- dataFrameGenerator = new DataFrameGenerator(bufferPool);
- headerBuffer.putInt(0, streamId & 0x7F_FF_FF_FF);
-
- }
-
- @Test
- public void testGenerateSmallFrame()
- {
- int bufferSize = 256;
- generateFrame(bufferSize);
- }
-
- @Test
- public void testGenerateFrameWithBufferThatEqualsBucketSize()
- {
- int bufferSize = increment;
- generateFrame(bufferSize);
- }
-
- @Test
- public void testGenerateFrameWithBufferThatEqualsBucketSizeMinusHeaderLength()
- {
- int bufferSize = increment - DataFrame.HEADER_LENGTH;
- generateFrame(bufferSize);
- }
-
- private void generateFrame(int bufferSize)
- {
- ByteBuffer byteBuffer = createByteBuffer(bufferSize);
- ByteBufferDataInfo dataInfo = new ByteBufferDataInfo(byteBuffer, true);
- fillHeaderBuffer(bufferSize);
- ByteBuffer dataFrameBuffer = dataFrameGenerator.generate(streamId, bufferSize, dataInfo);
-
- assertThat("The content size in dataFrameBuffer matches the buffersize + header length",
- dataFrameBuffer.limit(),
- is(bufferSize + DataFrame.HEADER_LENGTH));
-
- byte[] headerBytes = new byte[DataFrame.HEADER_LENGTH];
- dataFrameBuffer.get(headerBytes, 0, DataFrame.HEADER_LENGTH);
-
- assertThat("Header bytes are prepended", headerBytes, is(headerBuffer.array()));
- }
-
- private ByteBuffer createByteBuffer(int bufferSize)
- {
- byte[] bytes = new byte[bufferSize];
- ThreadLocalRandom.current().nextBytes(bytes);
- ByteBuffer byteBuffer = bufferPool.acquire(bufferSize, false);
- BufferUtil.flipToFill(byteBuffer);
- byteBuffer.put(bytes);
- BufferUtil.flipToFlush(byteBuffer, 0);
- return byteBuffer;
- }
-
- private void fillHeaderBuffer(int bufferSize)
- {
- headerBuffer.putInt(4, bufferSize & 0x00_FF_FF_FF);
- headerBuffer.put(4, DataInfo.FLAG_CLOSE);
- }
-
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/BrokenFrameTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/BrokenFrameTest.java
deleted file mode 100644
index 5d1a51d1b5..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/BrokenFrameTest.java
+++ /dev/null
@@ -1,287 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.io.ByteArrayOutputStream;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.zip.ZipException;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.StreamException;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.SynStreamFrame;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Test;
-
-public class BrokenFrameTest
-{
-
- @Test
- public void testInvalidHeaderNameLength() throws Exception
- {
- Fields headers = new Fields();
- headers.add("broken", "header");
- SynStreamFrame frame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, headers);
- Generator generator = new Generator(new MappedByteBufferPool(), new NoCompressionCompressionFactory.NoCompressionCompressor());
-
- ByteBuffer bufferWithBrokenHeaderNameLength = generator.control(frame);
- // Break the header name length to provoke the Parser to throw a StreamException
- bufferWithBrokenHeaderNameLength.put(21, (byte)0);
-
- ByteBuffer bufferWithValidSynStreamFrame = generator.control(frame);
-
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- outputStream.write(BufferUtil.toArray(bufferWithBrokenHeaderNameLength));
- outputStream.write(BufferUtil.toArray(bufferWithValidSynStreamFrame));
-
- byte concatenatedFramesByteArray[] = outputStream.toByteArray();
- ByteBuffer concatenatedBuffer = BufferUtil.toBuffer(concatenatedFramesByteArray);
-
- final CountDownLatch latch = new CountDownLatch(2);
- Parser parser = new Parser(new NoCompressionCompressionFactory.NoCompressionDecompressor());
- parser.addListener(new Parser.Listener.Adapter()
- {
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- latch.countDown();
- }
-
- @Override
- public void onStreamException(StreamException x)
- {
- latch.countDown();
- }
- });
- parser.parse(concatenatedBuffer);
-
- assertThat(latch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testInvalidVersion() throws Exception
- {
- Fields headers = new Fields();
- headers.add("good", "header");
- headers.add("another","header");
- SynStreamFrame frame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, headers);
- Generator generator = new Generator(new MappedByteBufferPool(), new NoCompressionCompressionFactory.NoCompressionCompressor());
-
- ByteBuffer bufferWithBrokenVersion = generator.control(frame);
- // Break the header name length to provoke the Parser to throw a StreamException
- bufferWithBrokenVersion.put(1, (byte)4);
-
- ByteBuffer bufferWithValidSynStreamFrame = generator.control(frame);
-
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- outputStream.write(BufferUtil.toArray(bufferWithBrokenVersion));
- outputStream.write(BufferUtil.toArray(bufferWithValidSynStreamFrame));
-
- byte concatenatedFramesByteArray[] = outputStream.toByteArray();
- ByteBuffer concatenatedBuffer = BufferUtil.toBuffer(concatenatedFramesByteArray);
-
- final CountDownLatch latch = new CountDownLatch(2);
- Parser parser = new Parser(new NoCompressionCompressionFactory.NoCompressionDecompressor());
- parser.addListener(new Parser.Listener.Adapter()
- {
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- latch.countDown();
- }
-
- @Override
- public void onStreamException(StreamException x)
- {
- latch.countDown();
- }
- });
- parser.parse(concatenatedBuffer);
-
- assertThat(latch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testInvalidVersionWithSplitBuffer() throws Exception
- {
- Fields headers = new Fields();
- headers.add("good", "header");
- headers.add("another","header");
- SynStreamFrame frame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, headers);
- Generator generator = new Generator(new MappedByteBufferPool(), new NoCompressionCompressionFactory.NoCompressionCompressor());
-
- ByteBuffer bufferWithBrokenVersion = generator.control(frame);
- // Break the header name length to provoke the Parser to throw a StreamException
- bufferWithBrokenVersion.put(1, (byte)4);
-
- ByteBuffer bufferWithValidSynStreamFrame = generator.control(frame);
-
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- outputStream.write(BufferUtil.toArray(bufferWithBrokenVersion));
- outputStream.write(BufferUtil.toArray(bufferWithValidSynStreamFrame));
-
- byte concatenatedFramesByteArray[] = outputStream.toByteArray();
- ByteBuffer concatenatedBuffer1 = BufferUtil.toBuffer(Arrays.copyOfRange(concatenatedFramesByteArray,0,20));
- ByteBuffer concatenatedBuffer2 = BufferUtil.toBuffer(Arrays.copyOfRange(concatenatedFramesByteArray,20,
- concatenatedFramesByteArray.length));
-
- final CountDownLatch latch = new CountDownLatch(2);
- Parser parser = new Parser(new NoCompressionCompressionFactory.NoCompressionDecompressor());
- parser.addListener(new Parser.Listener.Adapter()
- {
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- latch.countDown();
- }
-
- @Override
- public void onStreamException(StreamException x)
- {
- latch.countDown();
- }
- });
- parser.parse(concatenatedBuffer1);
- parser.parse(concatenatedBuffer2);
-
- assertThat(latch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testInvalidVersionAndGoodFrameSplitInThreeBuffers() throws Exception
- {
- Fields headers = new Fields();
- headers.add("good", "header");
- headers.add("another","header");
- SynStreamFrame frame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, headers);
- Generator generator = new Generator(new MappedByteBufferPool(), new NoCompressionCompressionFactory.NoCompressionCompressor());
-
- ByteBuffer bufferWithBrokenVersion = generator.control(frame);
- // Break the header name length to provoke the Parser to throw a StreamException
- bufferWithBrokenVersion.put(1, (byte)4);
-
- ByteBuffer bufferWithValidSynStreamFrame = generator.control(frame);
-
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- outputStream.write(BufferUtil.toArray(bufferWithBrokenVersion));
- outputStream.write(BufferUtil.toArray(bufferWithValidSynStreamFrame));
-
- byte concatenatedFramesByteArray[] = outputStream.toByteArray();
- ByteBuffer concatenatedBuffer1 = BufferUtil.toBuffer(Arrays.copyOfRange(concatenatedFramesByteArray,0,20));
- ByteBuffer concatenatedBuffer2 = BufferUtil.toBuffer(Arrays.copyOfRange(concatenatedFramesByteArray,20, 30));
- ByteBuffer concatenatedBuffer3 = BufferUtil.toBuffer(Arrays.copyOfRange(concatenatedFramesByteArray,30,
- concatenatedFramesByteArray.length));
-
- final CountDownLatch latch = new CountDownLatch(2);
- Parser parser = new Parser(new NoCompressionCompressionFactory.NoCompressionDecompressor());
- parser.addListener(new Parser.Listener.Adapter()
- {
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- latch.countDown();
- }
-
- @Override
- public void onStreamException(StreamException x)
- {
- latch.countDown();
- }
- });
- parser.parse(concatenatedBuffer1);
- parser.parse(concatenatedBuffer2);
- parser.parse(concatenatedBuffer3);
-
- assertThat(latch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- private static class NoCompressionCompressionFactory implements CompressionFactory
- {
-
- @Override
- public Compressor newCompressor()
- {
- return null;
- }
-
- @Override
- public Decompressor newDecompressor()
- {
- return null;
- }
-
- public static class NoCompressionCompressor implements Compressor
- {
-
- private byte[] input;
-
- @Override
- public void setInput(byte[] input)
- {
- this.input = input;
- }
-
- @Override
- public void setDictionary(byte[] dictionary)
- {
- }
-
- @Override
- public int compress(byte[] output)
- {
- System.arraycopy(input, 0, output, 0, input.length);
- return input.length;
- }
- }
-
- public static class NoCompressionDecompressor implements Decompressor
- {
- private byte[] input;
-
- @Override
- public void setDictionary(byte[] dictionary)
- {
- }
-
- @Override
- public void setInput(byte[] input)
- {
- this.input = input;
- }
-
- @Override
- public int decompress(byte[] output) throws ZipException
- {
- System.arraycopy(input, 0, output, 0, input.length);
- return input.length;
- }
- }
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/LiveChromiumRequestParserTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/LiveChromiumRequestParserTest.java
deleted file mode 100644
index 2ad3a83d78..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/LiveChromiumRequestParserTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.ControlFrameType;
-import org.eclipse.jetty.spdy.frames.SynStreamFrame;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class LiveChromiumRequestParserTest
-{
- @Test
- public void testSynStream() throws Exception
- {
- // Bytes taken with wireshark from a live chromium request
- byte[] bytes1 = toBytes("" +
- "800200010100011a0000000100000000000038eadfa251b262e0626083a41706" +
- "7bb80b75302cd6ae4017cdcdb12eb435d0b3d4d1d2d702b32c18f850732c036f" +
- "68889bae850e44da94811f2d0b3308821ca80375a14e714a72065c0d2cd619f8" +
- "52f37443837552f3a076b080b234033f28de73404c2b43630b135306b65c6059" +
- "929fc2c0ecee1ac2c0560c4c7eb9a940b52525050ccc206f32ea337021f22643" +
- "bb6f7e55664e4ea2bea99e81824684a1a135400a3e9979a5150a151666f16626" +
- "9a0a8e40afa686a726796796e89b1a9bea992b68787b84f8fae828e46466a72a" +
- "b8a72667e76b2a842695e69594ea1b0203d640c1390358e06496e6ea1b9ae901" +
- "c3c5d048cfdc1c22988a22149c98965894093195811d1a150c1cb01802000000" +
- "ffff");
- byte[] bytes2 = toBytes("" +
- "800200010100002700000003000000008000428a106660d00ee640e5d14f4b2c" +
- "cb0466313d203154c217000000ffff");
-
- final AtomicReference<ControlFrame> frameRef = new AtomicReference<>();
- Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
- parser.addListener(new Parser.Listener.Adapter()
- {
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- frameRef.set(frame);
- }
- });
- parser.parse(ByteBuffer.wrap(bytes1));
-
- ControlFrame frame = frameRef.get();
- Assert.assertNotNull(frame);
- Assert.assertEquals(ControlFrameType.SYN_STREAM, frame.getType());
- SynStreamFrame synStream = (SynStreamFrame)frame;
- Assert.assertEquals(2, synStream.getVersion());
- Assert.assertEquals(1, synStream.getStreamId());
- Assert.assertEquals(0, synStream.getAssociatedStreamId());
- Assert.assertEquals(0, synStream.getPriority());
- Assert.assertNotNull(synStream.getHeaders());
- Assert.assertFalse(synStream.getHeaders().isEmpty());
-
- frameRef.set(null);
- parser.parse(ByteBuffer.wrap(bytes2));
-
- frame = frameRef.get();
- Assert.assertNotNull(frame);
- Assert.assertEquals(ControlFrameType.SYN_STREAM, frame.getType());
- synStream = (SynStreamFrame)frame;
- Assert.assertEquals(2, synStream.getVersion());
- Assert.assertEquals(3, synStream.getStreamId());
- Assert.assertEquals(0, synStream.getAssociatedStreamId());
- Assert.assertEquals(2, synStream.getPriority());
- Assert.assertNotNull(synStream.getHeaders());
- Assert.assertFalse(synStream.getHeaders().isEmpty());
- }
-
- private byte[] toBytes(String hexs)
- {
- byte[] bytes = new byte[hexs.length() / 2];
- for (int i = 0; i < hexs.length(); i += 2)
- {
- String hex = hexs.substring(i, i + 2);
- bytes[i / 2] = (byte)Integer.parseInt(hex, 16);
- }
- return bytes;
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/ParseVersusCacheBenchmarkTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/ParseVersusCacheBenchmarkTest.java
deleted file mode 100644
index 4c5e5d68d9..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/ParseVersusCacheBenchmarkTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class ParseVersusCacheBenchmarkTest
-{
- @Ignore
- @Test
- public void testParseVersusCache() throws Exception
- {
- // The parser knows the header name and value lengths, so it creates strings
- // out of the bytes; however, this involves creating a byte[] copy the bytes,
- // and creating a new String.
- // The alternative is to use a cache<ByteBuffer, String>. Is that faster ?
- // See also: http://jeremymanson.blogspot.com/2008/04/immutability-in-java.html
-
- String name = "Content-Type";
- String value = "application/octect-stream";
- ByteBuffer buffer = ByteBuffer.wrap((name + value).getBytes(StandardCharsets.ISO_8859_1));
- int iterations = 100_000_000;
-
- long begin = System.nanoTime();
- for (int i = 0; i < iterations; ++i)
- {
- byte[] nameBytes = new byte[name.length()];
- buffer.get(nameBytes);
- String name2 = new String(nameBytes, StandardCharsets.ISO_8859_1);
- Assert.assertEquals(name2, name);
-
- byte[] valueBytes = new byte[value.length()];
- buffer.get(valueBytes);
- String value2 = new String(valueBytes, StandardCharsets.ISO_8859_1);
- Assert.assertEquals(value2, value);
-
- buffer.flip();
- }
- long end = System.nanoTime();
- System.err.printf("parse time: %d%n", TimeUnit.NANOSECONDS.toMillis(end - begin));
-
- Map<ByteBuffer, String> map = new HashMap<>();
- map.put(ByteBuffer.wrap(name.getBytes(StandardCharsets.ISO_8859_1)), name);
- map.put(ByteBuffer.wrap(value.getBytes(StandardCharsets.ISO_8859_1)), value);
- final Map<ByteBuffer, String> cache = Collections.unmodifiableMap(map);
-
- begin = System.nanoTime();
- for (int i = 0; i < iterations; ++i)
- {
- buffer.limit(buffer.position() + name.length());
- String name2 = cache.get(buffer);
- Assert.assertEquals(name2, name);
-
- buffer.position(buffer.limit());
- buffer.limit(buffer.position() + value.length());
- String value2 = cache.get(buffer);
- Assert.assertEquals(value2, value);
-
- buffer.position(buffer.limit());
- buffer.flip();
- }
- end = System.nanoTime();
- System.err.printf("cache time: %d%n", TimeUnit.NANOSECONDS.toMillis(end - begin));
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/UnknownControlFrameTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/UnknownControlFrameTest.java
deleted file mode 100644
index 9bd9909493..0000000000
--- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/parser/UnknownControlFrameTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.parser;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.SessionException;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.StreamException;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.DataFrame;
-import org.eclipse.jetty.spdy.frames.SynStreamFrame;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class UnknownControlFrameTest
-{
- @Test
- public void testUnknownControlFrame() throws Exception
- {
- SynStreamFrame frame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, new Fields());
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory.StandardCompressor());
- ByteBuffer buffer = generator.control(frame);
- // Change the frame type to unknown
- buffer.putShort(2, (short)0);
-
- final CountDownLatch latch = new CountDownLatch(1);
- Parser parser = new Parser(new StandardCompressionFactory.StandardDecompressor());
- parser.addListener(new Parser.Listener.Adapter()
- {
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- latch.countDown();
- }
-
- @Override
- public void onDataFrame(DataFrame frame, ByteBuffer data)
- {
- latch.countDown();
- }
-
- @Override
- public void onStreamException(StreamException x)
- {
- latch.countDown();
- }
-
- @Override
- public void onSessionException(SessionException x)
- {
- latch.countDown();
- }
- });
- parser.parse(buffer);
-
- Assert.assertFalse(latch.await(1, TimeUnit.SECONDS));
- }
-}
diff --git a/jetty-spdy/spdy-core/src/test/resources/jetty-logging.properties b/jetty-spdy/spdy-core/src/test/resources/jetty-logging.properties
deleted file mode 100644
index 5250a08562..0000000000
--- a/jetty-spdy/spdy-core/src/test/resources/jetty-logging.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-org.eclipse.jetty.spdy.LEVEL=WARN
diff --git a/jetty-spdy/spdy-core/src/test/resources/keystore.jks b/jetty-spdy/spdy-core/src/test/resources/keystore.jks
deleted file mode 100644
index 428ba54776..0000000000
--- a/jetty-spdy/spdy-core/src/test/resources/keystore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-core/src/test/resources/truststore.jks b/jetty-spdy/spdy-core/src/test/resources/truststore.jks
deleted file mode 100644
index 839cb8c351..0000000000
--- a/jetty-spdy/spdy-core/src/test/resources/truststore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-example-webapp/pom.xml b/jetty-spdy/spdy-example-webapp/pom.xml
deleted file mode 100644
index 0045fc1cfb..0000000000
--- a/jetty-spdy/spdy-example-webapp/pom.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-parent</artifactId>
- <version>9.2.15-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <artifactId>spdy-example-webapp</artifactId>
- <packaging>war</packaging>
- <name>Jetty :: SPDY :: HTTP Web Application</name>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
- <version>${project.version}</version>
- <configuration>
- <stopPort>8888</stopPort>
- <stopKey>quit</stopKey>
- <jvmArgs>
- -Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${npn.version}/npn-boot-${npn.version}.jar
- </jvmArgs>
- <jettyXml>${basedir}/src/main/config/example-jetty-spdy.xml</jettyXml>
- <contextPath>/</contextPath>
- <excludedGoals>
- <excludedGoal>run</excludedGoal>
- <excludedGoal>run-war</excludedGoal>
- <excludedGoal>deploy</excludedGoal>
- <excludedGoal>start</excludedGoal>
- <excludedGoal>stop</excludedGoal>
- </excludedGoals>
- </configuration>
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-http-server</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
- </plugin>
- </plugins>
- </build>
-
- <profiles>
- <profile>
- <id>proxy</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
- <version>${project.version}</version>
- <configuration>
- <stopPort>8888</stopPort>
- <stopKey>quit</stopKey>
- <jvmArgs>
- -Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${npn.version}/npn-boot-${npn.version}.jar
- </jvmArgs>
- <jettyXml>${basedir}/src/main/config/example-jetty-spdy-proxy.xml</jettyXml>
- <contextPath>/</contextPath>
- <excludedGoals>
- <excludedGoal>run</excludedGoal>
- <excludedGoal>run-war</excludedGoal>
- <excludedGoal>deploy</excludedGoal>
- <excludedGoal>start</excludedGoal>
- <excludedGoal>stop</excludedGoal>
- </excludedGoals>
- </configuration>
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-http-server</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-
-</project>
diff --git a/jetty-spdy/spdy-example-webapp/src/main/config/example-jetty-spdy-proxy.xml b/jetty-spdy/spdy-example-webapp/src/main/config/example-jetty-spdy-proxy.xml
deleted file mode 100644
index 7d3d360ac8..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/config/example-jetty-spdy-proxy.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
-
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
- <Set name="keyStorePath">src/main/resources/keystore.jks</Set>
- <Set name="keyStorePassword">storepwd</Set>
- <Set name="trustStorePath">src/main/resources/truststore.jks</Set>
- <Set name="trustStorePassword">storepwd</Set>
- <Set name="protocol">TLSv1</Set>
- </New>
-
- <!--
- <Set class="org.eclipse.jetty.npn.NextProtoNego" name="debug" type="boolean">true</Set>
- -->
-
- <New id="tlsHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
- <Arg>
- <New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
- <Set name="secureScheme">https</Set>
- <Set name="securePort">
- <Property name="jetty.tls.port" default="8443"/>
- </Set>
- <Set name="outputBufferSize">32768</Set>
- <Set name="requestHeaderSize">8192</Set>
- <Set name="responseHeaderSize">8192</Set>
-
- <!-- Uncomment to enable handling of X-Forwarded- style headers
- <Call name="addCustomizer">
- <Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
- </Call>
- -->
- </New>
- </Arg>
- <Call name="addCustomizer">
- <Arg>
- <New class="org.eclipse.jetty.server.SecureRequestCustomizer"/>
- </Arg>
- </Call>
- </New>
-
- <!--
- This is the upstream server connector. It speaks non-SSL SPDY/3(HTTP) on port 9090.
- -->
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.ServerConnector">
- <Arg name="server">
- <Ref refid="Server"/>
- </Arg>
- <Arg name="factories">
- <Array type="org.eclipse.jetty.server.ConnectionFactory">
- <!-- SPDY/3 Connection factory -->
- <Item>
- <New class="org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory">
- <Arg name="version" type="int">3</Arg>
- <Arg name="config">
- <Ref refid="tlsHttpConfig"/>
- </Arg>
- </New>
- </Item>
- </Array>
- </Arg>
- <Set name="port">9090</Set>
- </New>
- </Arg>
- </Call>
-
- <!--
- This ProxyEngine translates the incoming SPDY/x(HTTP) request to SPDY/2(HTTP)
- -->
- <New id="spdyProxyEngine" class="org.eclipse.jetty.spdy.server.proxy.SPDYProxyEngine">
- <Arg>
- <New class="org.eclipse.jetty.spdy.client.SPDYClient$Factory">
- <Call name="start"/>
- </New>
- </Arg>
- </New>
-
- <!--
- The ProxyEngineSelector receives SPDY/x(HTTP) requests from proxy connectors below
- and is configured to process requests for host "localhost".
- Such requests are converted from SPDY/x(HTTP) to SPDY/3(HTTP) by the configured ProxyEngine
- and forwarded to 127.0.0.1:9090, where they are served by the upstream server above.
- -->
- <New id="proxyEngineSelector" class="org.eclipse.jetty.spdy.server.proxy.ProxyEngineSelector">
- <Call name="putProxyEngine">
- <Arg>spdy/3</Arg>
- <Arg>
- <Ref refid="spdyProxyEngine"/>
- </Arg>
- </Call>
- <Set name="proxyServerInfos">
- <Map>
- <Entry>
- <Item>localhost</Item>
- <Item>
- <New class="org.eclipse.jetty.spdy.server.proxy.ProxyEngineSelector$ProxyServerInfo">
- <Arg type="String">spdy/3</Arg>
- <Arg>127.0.0.1</Arg>
- <Arg type="int">9090</Arg>
- </New>
- </Item>
- </Entry>
- </Map>
- </Set>
- </New>
-
- <!--
- These are the reverse proxy connectors accepting requests from clients.
- They accept non-SSL (on port 8080) and SSL (on port 8443) HTTP,
- SPDY/2(HTTP) and SPDY/3(HTTP).
- Non-SPDY HTTP requests are converted to SPDY internally and passed to the
- ProxyEngine above.
- -->
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.spdy.server.proxy.HTTPSPDYProxyServerConnector">
- <Arg>
- <Ref refid="Server"/>
- </Arg>
- <Arg>
- <Ref refid="proxyEngineSelector"/>
- </Arg>
- <Set name="Port">8080</Set>
- </New>
- </Arg>
- </Call>
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.spdy.server.proxy.HTTPSPDYProxyServerConnector">
- <Arg>
- <Ref refid="Server"/>
- </Arg>
- <Arg>
- <Ref refid="sslContextFactory"/>
- </Arg>
- <Arg>
- <Ref refid="proxyEngineSelector"/>
- </Arg>
- <Set name="Port">8443</Set>
- </New>
- </Arg>
- </Call>
-
-</Configure>
diff --git a/jetty-spdy/spdy-example-webapp/src/main/config/example-jetty-spdy.xml b/jetty-spdy/spdy-example-webapp/src/main/config/example-jetty-spdy.xml
deleted file mode 100644
index 47f83be825..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/config/example-jetty-spdy.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
-
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
- <Set name="keyStorePath">src/main/resources/keystore.jks</Set>
- <Set name="keyStorePassword">storepwd</Set>
- <Set name="trustStorePath">src/main/resources/truststore.jks</Set>
- <Set name="trustStorePassword">storepwd</Set>
- <Set name="protocol">TLSv1</Set>
- </New>
-
- <New id="tlsHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
- <Arg>
- <New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
- <Set name="secureScheme">https</Set>
- <Set name="securePort">
- <Property name="jetty.tls.port" default="8443"/>
- </Set>
- <Set name="outputBufferSize">32768</Set>
- <Set name="requestHeaderSize">8192</Set>
- <Set name="responseHeaderSize">8192</Set>
-
- <!-- Uncomment to enable handling of X-Forwarded- style headers
- <Call name="addCustomizer">
- <Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
- </Call>
- -->
- </New>
- </Arg>
- <Call name="addCustomizer">
- <Arg>
- <New class="org.eclipse.jetty.server.SecureRequestCustomizer"/>
- </Arg>
- </Call>
- </New>
-
- <New id="pushStrategy" class="org.eclipse.jetty.spdy.server.http.ReferrerPushStrategy">
- <!-- Uncomment to blacklist browsers for this push strategy. If one of the blacklisted Strings occurs in the
- user-agent header sent by the client, push will be disabled for this browser. This is case insensitive" -->
- <!--
- <Set name="UserAgentBlacklist">
- <Array type="String">
- <Item>.*(?i)firefox/14.*</Item>
- <Item>.*(?i)firefox/15.*</Item>
- <Item>.*(?i)firefox/16.*</Item>
- </Array>
- </Set>
- -->
-
- <!-- Uncomment to override default file extensions to push -->
- <!--
- <Set name="PushRegexps">
- <Array type="String">
- <Item>.*\.css</Item>
- <Item>.*\.js</Item>
- <Item>.*\.png</Item>
- <Item>.*\.jpg</Item>
- <Item>.*\.gif</Item>
- </Array>
- </Set>
- -->
- <Set name="referrerPushPeriod">5000</Set>
- <Set name="maxAssociatedResources">32</Set>
- </New>
-
- <Call id="sslConnector" name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.ServerConnector">
- <Arg name="server"><Ref refid="Server"/></Arg>
- <Arg name="factories">
- <Array type="org.eclipse.jetty.server.ConnectionFactory">
-
- <!-- SSL Connection factory with NPN as next protocol -->
- <Item>
- <New class="org.eclipse.jetty.server.SslConnectionFactory">
- <Arg name="next">npn</Arg>
- <Arg name="sslContextFactory">
- <Ref refid="sslContextFactory"/>
- </Arg>
- </New>
- </Item>
-
- <!-- NPN Connection factory with HTTP as default protocol -->
- <Item>
- <New class="org.eclipse.jetty.spdy.server.NPNServerConnectionFactory">
- <Arg name="protocols">
- <Array type="String">
- <Item>spdy/3</Item>
- <Item>spdy/2</Item>
- <Item>http/1.1</Item>
- </Array>
- </Arg>
- <Set name="defaultProtocol">http/1.1</Set>
- </New>
- </Item>
-
- <!-- SPDY/3 Connection factory -->
- <Item>
- <New class="org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory">
- <Arg name="version" type="int">3</Arg>
- <Arg name="config">
- <Ref refid="tlsHttpConfig"/>
- </Arg>
- <Arg name="pushStrategy">
- <Ref refid="pushStrategy"/>
- </Arg>
- </New>
- </Item>
-
- <!-- SPDY/2 Connection factory -->
- <Item>
- <New class="org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory">
- <Arg name="version" type="int">2</Arg>
- <Arg name="config">
- <Ref refid="tlsHttpConfig"/>
- </Arg>
- </New>
- </Item>
-
- <!-- HTTP Connection factory -->
- <Item>
- <New class="org.eclipse.jetty.server.HttpConnectionFactory">
- <Arg name="config">
- <Ref refid="tlsHttpConfig"/>
- </Arg>
- </New>
- </Item>
- </Array>
- </Arg>
-
- <Set name="port">8443</Set>
- </New>
- </Arg>
- </Call>
-
-</Configure>
diff --git a/jetty-spdy/spdy-example-webapp/src/main/resources/jetty-logging.properties b/jetty-spdy/spdy-example-webapp/src/main/resources/jetty-logging.properties
deleted file mode 100644
index 5250a08562..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/resources/jetty-logging.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-org.eclipse.jetty.spdy.LEVEL=WARN
diff --git a/jetty-spdy/spdy-example-webapp/src/main/resources/keystore.jks b/jetty-spdy/spdy-example-webapp/src/main/resources/keystore.jks
deleted file mode 100644
index 428ba54776..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/resources/keystore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-example-webapp/src/main/resources/truststore.jks b/jetty-spdy/spdy-example-webapp/src/main/resources/truststore.jks
deleted file mode 100644
index 839cb8c351..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/resources/truststore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-example-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-spdy/spdy-example-webapp/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index eb49319a3e..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<web-app xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
- version="3.0">
-</web-app>
diff --git a/jetty-spdy/spdy-example-webapp/src/main/webapp/form.jsp b/jetty-spdy/spdy-example-webapp/src/main/webapp/form.jsp
deleted file mode 100644
index 4e41a655ad..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/webapp/form.jsp
+++ /dev/null
@@ -1,3 +0,0 @@
-<div>
- <p>This paragraph has been retrieved via an AJAX call</p>
-</div>
diff --git a/jetty-spdy/spdy-example-webapp/src/main/webapp/included.jsp b/jetty-spdy/spdy-example-webapp/src/main/webapp/included.jsp
deleted file mode 100644
index d69cd4a729..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/webapp/included.jsp
+++ /dev/null
@@ -1,3 +0,0 @@
-<div>
- <p>This paragraph is an included content via &lt;jsp:include&gt;</p>
-</div>
diff --git a/jetty-spdy/spdy-example-webapp/src/main/webapp/index.jsp b/jetty-spdy/spdy-example-webapp/src/main/webapp/index.jsp
deleted file mode 100644
index f190e572ab..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/webapp/index.jsp
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
- <title>SPDY TEST PAGE</title>
- <link rel="stylesheet" href="stylesheet.css" />
- <script type="text/javascript">
- function submit()
- {
- var xhr = new XMLHttpRequest();
- xhr.open("POST", "${pageContext.request.contextPath}/form.jsp", false);
- xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
- xhr.send("param=1");
- window.document.getElementById("form").innerHTML = xhr.responseText;
- }
- </script>
-</head>
-<body>
-<h2>SPDY TEST PAGE</h2>
-<div>
- <p><span id="css">This paragraph should have a colored background, meaning that the CSS has been loaded.</span></p>
-</div>
-<div id="image">
- <p>Below there should be an image</p>
- <img src="${pageContext.request.contextPath}/logo.jpg" alt="logo" />
-</div>
-<div>
- <jsp:include page="included.jsp" />
-</div>
-<div>
- <p>Click on the button below to perform an AJAX call</p>
- <button type="button" onclick="submit()">
- PERFORM AJAX CALL
- </button>
- <p id="form"></p>
-</div>
-</body>
-</html>
diff --git a/jetty-spdy/spdy-example-webapp/src/main/webapp/logo.jpg b/jetty-spdy/spdy-example-webapp/src/main/webapp/logo.jpg
deleted file mode 100644
index e8eb8c55fd..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/webapp/logo.jpg
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-example-webapp/src/main/webapp/stylesheet.css b/jetty-spdy/spdy-example-webapp/src/main/webapp/stylesheet.css
deleted file mode 100644
index 169c339849..0000000000
--- a/jetty-spdy/spdy-example-webapp/src/main/webapp/stylesheet.css
+++ /dev/null
@@ -1,9 +0,0 @@
-body
-{
- font-family: Verdana, sans-serif;
-}
-
-#css
-{
- background: #0FF;
-}
diff --git a/jetty-spdy/spdy-http-client-transport/pom.xml b/jetty-spdy/spdy-http-client-transport/pom.xml
deleted file mode 100644
index 1cb3ae6970..0000000000
--- a/jetty-spdy/spdy-http-client-transport/pom.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-parent</artifactId>
- <version>9.2.15-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>spdy-http-client-transport</artifactId>
- <name>Jetty :: SPDY :: HTTP Client Transport</name>
-
- <properties>
- <bundle-symbolic-name>${project.groupId}.client.http</bundle-symbolic-name>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>manifest</goal>
- </goals>
- <configuration>
- <instructions>
- <Export-Package>org.eclipse.jetty.spdy.client.http;version="9.1"</Export-Package>
- <Import-Package>!org.eclipse.jetty.npn,org.eclipse.jetty.*;version="[9.0,10.0)",*</Import-Package>
- </instructions>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-client</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-client</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-http-common</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-server</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-http-server</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpChannelOverSPDY.java b/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpChannelOverSPDY.java
deleted file mode 100644
index 0f32567e4a..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpChannelOverSPDY.java
+++ /dev/null
@@ -1,78 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client.http;
-
-import org.eclipse.jetty.client.HttpChannel;
-import org.eclipse.jetty.client.HttpDestination;
-import org.eclipse.jetty.client.HttpExchange;
-import org.eclipse.jetty.client.api.Result;
-import org.eclipse.jetty.spdy.api.Session;
-
-public class HttpChannelOverSPDY extends HttpChannel
-{
- private final HttpConnectionOverSPDY connection;
- private final Session session;
- private final HttpSenderOverSPDY sender;
- private final HttpReceiverOverSPDY receiver;
-
- public HttpChannelOverSPDY(HttpDestination destination, HttpConnectionOverSPDY connection, Session session)
- {
- super(destination);
- this.connection = connection;
- this.session = session;
- this.sender = new HttpSenderOverSPDY(this);
- this.receiver = new HttpReceiverOverSPDY(this);
- }
-
- public Session getSession()
- {
- return session;
- }
-
- public HttpSenderOverSPDY getHttpSender()
- {
- return sender;
- }
-
- public HttpReceiverOverSPDY getHttpReceiver()
- {
- return receiver;
- }
-
- @Override
- public void send()
- {
- HttpExchange exchange = getHttpExchange();
- if (exchange != null)
- sender.send(exchange);
- }
-
- @Override
- public void release()
- {
- connection.release(this);
- }
-
- @Override
- public void exchangeTerminated(HttpExchange exchange, Result result)
- {
- super.exchangeTerminated(exchange, result);
- release();
- }
-}
diff --git a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpClientTransportOverSPDY.java b/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpClientTransportOverSPDY.java
deleted file mode 100644
index 2aef0a5db8..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpClientTransportOverSPDY.java
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client.http;
-
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.util.Map;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.HttpClientTransport;
-import org.eclipse.jetty.client.HttpDestination;
-import org.eclipse.jetty.client.Origin;
-import org.eclipse.jetty.client.api.Connection;
-import org.eclipse.jetty.io.ClientConnectionFactory;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.util.Promise;
-
-public class HttpClientTransportOverSPDY implements HttpClientTransport
-{
- private final SPDYClient client;
- private final ClientConnectionFactory connectionFactory;
- private HttpClient httpClient;
-
- public HttpClientTransportOverSPDY(SPDYClient client)
- {
- this.client = client;
- this.connectionFactory = client.getClientConnectionFactory();
- client.setClientConnectionFactory(new ClientConnectionFactory()
- {
- @Override
- public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
- {
- HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
- return destination.getClientConnectionFactory().newConnection(endPoint, context);
- }
- });
- }
-
- @Override
- public void setHttpClient(HttpClient client)
- {
- httpClient = client;
- }
-
- @Override
- public HttpDestination newHttpDestination(Origin origin)
- {
- return new HttpDestinationOverSPDY(httpClient, origin);
- }
-
- @Override
- public void connect(SocketAddress address, Map<String, Object> context)
- {
- final HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
- @SuppressWarnings("unchecked")
- final Promise<Connection> promise = (Promise<Connection>)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY);
-
- SessionFrameListener.Adapter listener = new SessionFrameListener.Adapter()
- {
- @Override
- public void onFailure(Session session, Throwable x)
- {
- destination.abort(x);
- }
- };
-
- client.connect(address, listener, new Promise<Session>()
- {
- @Override
- public void succeeded(Session session)
- {
- promise.succeeded(new HttpConnectionOverSPDY(destination, session));
- }
-
- @Override
- public void failed(Throwable x)
- {
- promise.failed(x);
- }
- }, context);
- }
-
- @Override
- public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
- {
- return connectionFactory.newConnection(endPoint, context);
- }
-}
diff --git a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpConnectionOverSPDY.java b/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpConnectionOverSPDY.java
deleted file mode 100644
index f3055e9f13..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpConnectionOverSPDY.java
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client.http;
-
-import java.nio.channels.AsynchronousCloseException;
-import java.util.Set;
-
-import org.eclipse.jetty.client.HttpChannel;
-import org.eclipse.jetty.client.HttpConnection;
-import org.eclipse.jetty.client.HttpDestination;
-import org.eclipse.jetty.client.HttpExchange;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.ConcurrentHashSet;
-
-public class HttpConnectionOverSPDY extends HttpConnection
-{
- private final Set<HttpChannel> channels = new ConcurrentHashSet<>();
- private final Session session;
-
- public HttpConnectionOverSPDY(HttpDestination destination, Session session)
- {
- super(destination);
- this.session = session;
- }
-
- @Override
- protected void send(HttpExchange exchange)
- {
- normalizeRequest(exchange.getRequest());
- // One connection maps to N channels, so for each exchange we create a new channel
- HttpChannel channel = new HttpChannelOverSPDY(getHttpDestination(), this, session);
- channels.add(channel);
- if (channel.associate(exchange))
- channel.send();
- else
- channel.release();
- }
-
- protected void release(HttpChannel channel)
- {
- channels.remove(channel);
- }
-
- @Override
- public void close()
- {
- // First close then abort, to be sure that the connection cannot be reused
- // from an onFailure() handler or by blocking code waiting for completion.
- getHttpDestination().close(this);
- session.goAway(new GoAwayInfo(), Callback.Adapter.INSTANCE);
- abort(new AsynchronousCloseException());
- }
-
- private void abort(Throwable failure)
- {
- for (HttpChannel channel : channels)
- {
- HttpExchange exchange = channel.getHttpExchange();
- if (exchange != null)
- exchange.getRequest().abort(failure);
- }
- channels.clear();
- }
-}
diff --git a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpDestinationOverSPDY.java b/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpDestinationOverSPDY.java
deleted file mode 100644
index c52e0c4e03..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpDestinationOverSPDY.java
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client.http;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.HttpExchange;
-import org.eclipse.jetty.client.MultiplexHttpDestination;
-import org.eclipse.jetty.client.Origin;
-
-public class HttpDestinationOverSPDY extends MultiplexHttpDestination<HttpConnectionOverSPDY>
-{
- public HttpDestinationOverSPDY(HttpClient client, Origin origin)
- {
- super(client, origin);
- }
-
- @Override
- protected void send(HttpConnectionOverSPDY connection, HttpExchange exchange)
- {
- connection.send(exchange);
- }
-}
diff --git a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpReceiverOverSPDY.java b/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpReceiverOverSPDY.java
deleted file mode 100644
index 51b315137d..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpReceiverOverSPDY.java
+++ /dev/null
@@ -1,152 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client.http;
-
-import org.eclipse.jetty.client.HttpExchange;
-import org.eclipse.jetty.client.HttpReceiver;
-import org.eclipse.jetty.client.HttpResponse;
-import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.http.HttpVersion;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-
-public class HttpReceiverOverSPDY extends HttpReceiver implements StreamFrameListener
-{
- public HttpReceiverOverSPDY(HttpChannelOverSPDY channel)
- {
- super(channel);
- }
-
- @Override
- public HttpChannelOverSPDY getHttpChannel()
- {
- return (HttpChannelOverSPDY)super.getHttpChannel();
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- HttpExchange exchange = getHttpExchange();
- if (exchange == null)
- return;
-
- try
- {
- HttpResponse response = exchange.getResponse();
-
- Fields fields = replyInfo.getHeaders();
- short spdy = stream.getSession().getVersion();
- HttpVersion version = HttpVersion.fromString(fields.get(HTTPSPDYHeader.VERSION.name(spdy)).getValue());
- response.version(version);
- String[] status = fields.get(HTTPSPDYHeader.STATUS.name(spdy)).getValue().split(" ", 2);
-
- Integer code = Integer.parseInt(status[0]);
- response.status(code);
- String reason = status.length < 2 ? HttpStatus.getMessage(code) : status[1];
- response.reason(reason);
-
- if (responseBegin(exchange))
- {
- for (Fields.Field field : fields)
- {
- String name = field.getName();
- if (HTTPSPDYHeader.from(spdy, name) != null)
- continue;
- // TODO: handle multiple values properly
- HttpField httpField = new HttpField(name, field.getValue());
- responseHeader(exchange, httpField);
- }
-
- if (responseHeaders(exchange))
- {
- if (replyInfo.isClose())
- {
- responseSuccess(exchange);
- }
- }
- }
- }
- catch (Exception x)
- {
- responseFailure(x);
- }
- }
-
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- // SPDY push not supported
- getHttpChannel().getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), Callback.Adapter.INSTANCE);
- return null;
- }
-
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- // TODO: see above handling of headers
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- HttpExchange exchange = getHttpExchange();
- if (exchange == null)
- return;
-
- try
- {
- int length = dataInfo.length();
- // TODO: avoid data copy here
- // TODO: handle callback properly
- boolean process = responseContent(exchange, dataInfo.asByteBuffer(false), new Callback.Adapter());
- dataInfo.consume(length);
-
- if (process)
- {
- if (dataInfo.isClose())
- {
- responseSuccess(exchange);
- }
- }
- }
- catch (Exception x)
- {
- responseFailure(x);
- }
- }
-
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- HttpExchange exchange = getHttpExchange();
- if (exchange == null)
- return;
- exchange.getRequest().abort(x);
- }
-}
diff --git a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpSenderOverSPDY.java b/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpSenderOverSPDY.java
deleted file mode 100644
index 7429fcf3a0..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/main/java/org/eclipse/jetty/spdy/client/http/HttpSenderOverSPDY.java
+++ /dev/null
@@ -1,118 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client.http;
-
-import org.eclipse.jetty.client.HttpContent;
-import org.eclipse.jetty.client.HttpExchange;
-import org.eclipse.jetty.client.HttpSender;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-
-public class HttpSenderOverSPDY extends HttpSender
-{
- private volatile Stream stream;
-
- public HttpSenderOverSPDY(HttpChannelOverSPDY channel)
- {
- super(channel);
- }
-
- @Override
- public HttpChannelOverSPDY getHttpChannel()
- {
- return (HttpChannelOverSPDY)super.getHttpChannel();
- }
-
- @Override
- protected void sendHeaders(HttpExchange exchange, final HttpContent content, final Callback callback)
- {
- final Request request = exchange.getRequest();
- final long idleTimeout = request.getIdleTimeout();
- short spdyVersion = getHttpChannel().getSession().getVersion();
- Fields fields = new Fields();
- HttpField hostHeader = null;
- for (HttpField header : request.getHeaders())
- {
- String name = header.getName();
- // The host header needs a special treatment
- if (HTTPSPDYHeader.from(spdyVersion, name) != HTTPSPDYHeader.HOST)
- fields.add(name, header.getValue());
- else
- hostHeader = header;
- }
-
- // Add special SPDY headers
- fields.put(HTTPSPDYHeader.METHOD.name(spdyVersion), request.getMethod());
- String path = request.getPath();
- String query = request.getQuery();
- if (query != null)
- path += "?" + query;
- fields.put(HTTPSPDYHeader.URI.name(spdyVersion), path);
- fields.put(HTTPSPDYHeader.VERSION.name(spdyVersion), request.getVersion().asString());
- if (hostHeader != null)
- fields.put(HTTPSPDYHeader.HOST.name(spdyVersion), hostHeader.getValue());
-
- SynInfo synInfo = new SynInfo(fields, !content.hasContent());
- getHttpChannel().getSession().syn(synInfo, getHttpChannel().getHttpReceiver(), new Promise<Stream>()
- {
- @Override
- public void succeeded(Stream stream)
- {
- stream.setIdleTimeout(idleTimeout);
- if (content.hasContent())
- HttpSenderOverSPDY.this.stream = stream;
- callback.succeeded();
- }
-
- @Override
- public void failed(Throwable failure)
- {
- callback.failed(failure);
- }
- });
- }
-
- @Override
- protected void sendContent(HttpExchange exchange, HttpContent content, Callback callback)
- {
- if (content.isConsumed())
- {
- callback.succeeded();
- }
- else
- {
- ByteBufferDataInfo dataInfo = new ByteBufferDataInfo(content.getByteBuffer(), content.isLast());
- stream.data(dataInfo, callback);
- }
- }
-
- @Override
- protected void reset()
- {
- super.reset();
- stream = null;
- }
-}
diff --git a/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/AbstractHttpClientServerTest.java b/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/AbstractHttpClientServerTest.java
deleted file mode 100644
index ab7a2a7b5b..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/AbstractHttpClientServerTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client.http;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.http.HttpScheme;
-import org.eclipse.jetty.server.AbstractConnectionFactory;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory;
-import org.eclipse.jetty.toolchain.test.TestTracker;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.junit.After;
-import org.junit.Rule;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public abstract class AbstractHttpClientServerTest
-{
- @Parameterized.Parameters
- public static Collection<SslContextFactory[]> parameters()
- {
- return Arrays.asList(new SslContextFactory[]{null}, new SslContextFactory[]{new SslContextFactory()});
- }
-
- @Rule
- public final TestTracker tracker = new TestTracker();
-
- protected SslContextFactory sslContextFactory;
- protected String scheme;
- protected Server server;
- protected ServerConnector connector;
- protected SPDYClient.Factory factory;
- protected HttpClient client;
-
- public AbstractHttpClientServerTest(SslContextFactory sslContextFactory)
- {
- this.sslContextFactory = sslContextFactory;
- this.scheme = (sslContextFactory == null ? HttpScheme.HTTP : HttpScheme.HTTPS).asString();
- }
-
- public void start(Handler handler) throws Exception
- {
- short version = SPDY.V3;
-
- HTTPSPDYServerConnectionFactory httpSPDY = new HTTPSPDYServerConnectionFactory(version, new HttpConfiguration());
- if (sslContextFactory != null)
- {
- sslContextFactory.setEndpointIdentificationAlgorithm("");
- sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
- sslContextFactory.setKeyStorePassword("storepwd");
- sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
- sslContextFactory.setTrustStorePassword("storepwd");
- }
-
- server = new Server();
- connector = new ServerConnector(server, AbstractConnectionFactory.getFactories(sslContextFactory, httpSPDY));
- server.addConnector(connector);
- server.setHandler(handler);
- server.start();
-
- QueuedThreadPool executor = new QueuedThreadPool();
- executor.setName(executor.getName() + "-client");
-
- factory = new SPDYClient.Factory(executor);
- factory.start();
- client = new HttpClient(new HttpClientTransportOverSPDY(factory.newSPDYClient(version)), sslContextFactory);
- client.setExecutor(executor);
- client.start();
- }
-
- @After
- public void dispose() throws Exception
- {
- if (client != null)
- client.stop();
- if (factory != null)
- factory.stop();
- if (server != null)
- server.stop();
- }
-}
diff --git a/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/EmptyServerHandler.java b/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/EmptyServerHandler.java
deleted file mode 100644
index 34743bf61c..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/EmptyServerHandler.java
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client.http;
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-
-public class EmptyServerHandler extends AbstractHandler
-{
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- }
-}
diff --git a/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/HttpClientCustomProxyTest.java b/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/HttpClientCustomProxyTest.java
deleted file mode 100644
index 7753ae4536..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/HttpClientCustomProxyTest.java
+++ /dev/null
@@ -1,262 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client.http;
-
-import java.io.IOException;
-import java.net.URI;
-import java.nio.ByteBuffer;
-import java.util.Map;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.HttpClientTransport;
-import org.eclipse.jetty.client.HttpDestination;
-import org.eclipse.jetty.client.Origin;
-import org.eclipse.jetty.client.ProxyConfiguration;
-import org.eclipse.jetty.client.api.Connection;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.ClientConnectionFactory;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.AbstractConnectionFactory;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory;
-import org.eclipse.jetty.spdy.server.http.PushStrategy;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class HttpClientCustomProxyTest
-{
- public static final byte[] CAFE_BABE = new byte[]{(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE};
-
- private Server server;
- private ServerConnector connector;
- private SPDYClient.Factory factory;
- private HttpClient httpClient;
-
- public void prepare(Handler handler) throws Exception
- {
- server = new Server();
- connector = new ServerConnector(server, new CAFEBABEServerConnectionFactory(new HTTPSPDYServerConnectionFactory(SPDY.V3, new HttpConfiguration(), new PushStrategy.None())));
- server.addConnector(connector);
- server.setHandler(handler);
- server.start();
-
- QueuedThreadPool executor = new QueuedThreadPool();
- executor.setName(executor.getName() + "-client");
-
- factory = new SPDYClient.Factory(executor);
- factory.start();
-
- httpClient = new HttpClient(new HttpClientTransportOverSPDY(factory.newSPDYClient(SPDY.V3)), null);
- httpClient.setExecutor(executor);
- httpClient.start();
- }
-
- @After
- public void dispose() throws Exception
- {
- if (httpClient != null)
- httpClient.stop();
- if (factory != null)
- factory.stop();
- if (server != null)
- server.stop();
- }
-
- @Test
- public void testCustomProxy() throws Exception
- {
- final String serverHost = "server";
- final int status = HttpStatus.NO_CONTENT_204;
- prepare(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- if (!URI.create(baseRequest.getUri().toString()).isAbsolute())
- response.setStatus(HttpServletResponse.SC_USE_PROXY);
- else if (serverHost.equals(request.getServerName()))
- response.setStatus(status);
- else
- response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
- }
- });
-
- // Setup the custom proxy
- int proxyPort = connector.getLocalPort();
- int serverPort = proxyPort + 1; // Any port will do for these tests - just not the same as the proxy
- httpClient.getProxyConfiguration().getProxies().add(new CAFEBABEProxy(new Origin.Address("localhost", proxyPort), false));
-
- ContentResponse response = httpClient.newRequest(serverHost, serverPort)
- .timeout(5, TimeUnit.SECONDS)
- .send();
-
- Assert.assertEquals(status, response.getStatus());
- }
-
- private class CAFEBABEProxy extends ProxyConfiguration.Proxy
- {
- private CAFEBABEProxy(Origin.Address address, boolean secure)
- {
- super(address, secure);
- }
-
- @Override
- public ClientConnectionFactory newClientConnectionFactory(ClientConnectionFactory connectionFactory)
- {
- return new CAFEBABEClientConnectionFactory(connectionFactory);
- }
- }
-
- private static class CAFEBABEClientConnectionFactory implements ClientConnectionFactory
- {
- private final ClientConnectionFactory connectionFactory;
-
- private CAFEBABEClientConnectionFactory(ClientConnectionFactory connectionFactory)
- {
- this.connectionFactory = connectionFactory;
- }
-
- @Override
- public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
- {
- HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY);
- Executor executor = destination.getHttpClient().getExecutor();
- return new CAFEBABEConnection(endPoint, executor, connectionFactory, context);
- }
- }
-
- private static class CAFEBABEConnection extends AbstractConnection
- {
- private final ClientConnectionFactory connectionFactory;
- private final Map<String, Object> context;
-
- public CAFEBABEConnection(EndPoint endPoint, Executor executor, ClientConnectionFactory connectionFactory, Map<String, Object> context)
- {
- super(endPoint, executor);
- this.connectionFactory = connectionFactory;
- this.context = context;
- }
-
- @Override
- public void onOpen()
- {
- super.onOpen();
- fillInterested();
- getEndPoint().write(new Callback.Adapter(), ByteBuffer.wrap(CAFE_BABE));
- }
-
- @Override
- public void onFillable()
- {
- try
- {
- ByteBuffer buffer = BufferUtil.allocate(4);
- int filled = getEndPoint().fill(buffer);
- Assert.assertEquals(4, filled);
- Assert.assertArrayEquals(CAFE_BABE, buffer.array());
-
- // We are good, upgrade the connection
- ClientConnectionFactory.Helper.replaceConnection(this, connectionFactory.newConnection(getEndPoint(), context));
- }
- catch (Throwable x)
- {
- close();
- @SuppressWarnings("unchecked")
- Promise<Connection> promise = (Promise<Connection>)context.get(HttpClientTransport.HTTP_CONNECTION_PROMISE_CONTEXT_KEY);
- promise.failed(x);
- }
- }
- }
-
- private class CAFEBABEServerConnectionFactory extends AbstractConnectionFactory
- {
- private final org.eclipse.jetty.server.ConnectionFactory connectionFactory;
-
- private CAFEBABEServerConnectionFactory(org.eclipse.jetty.server.ConnectionFactory connectionFactory)
- {
- super("cafebabe");
- this.connectionFactory = connectionFactory;
- }
-
- @Override
- public org.eclipse.jetty.io.Connection newConnection(Connector connector, EndPoint endPoint)
- {
- return new CAFEBABEServerConnection(connector, endPoint, connectionFactory);
- }
- }
-
- private class CAFEBABEServerConnection extends AbstractConnection
- {
- private final org.eclipse.jetty.server.ConnectionFactory connectionFactory;
-
- public CAFEBABEServerConnection(Connector connector, EndPoint endPoint, org.eclipse.jetty.server.ConnectionFactory connectionFactory)
- {
- super(endPoint, connector.getExecutor());
- this.connectionFactory = connectionFactory;
- }
-
- @Override
- public void onOpen()
- {
- super.onOpen();
- fillInterested();
- }
-
- @Override
- public void onFillable()
- {
- try
- {
- ByteBuffer buffer = BufferUtil.allocate(4);
- int filled = getEndPoint().fill(buffer);
- Assert.assertEquals(4, filled);
- Assert.assertArrayEquals(CAFE_BABE, buffer.array());
- getEndPoint().write(new Callback.Adapter(), buffer);
-
- // We are good, upgrade the connection
- ClientConnectionFactory.Helper.replaceConnection(this, connectionFactory.newConnection(connector, getEndPoint()));
- }
- catch (Throwable x)
- {
- close();
- }
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/HttpClientTest.java b/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/HttpClientTest.java
deleted file mode 100644
index 2fcf1e9555..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/test/java/org/eclipse/jetty/spdy/client/http/HttpClientTest.java
+++ /dev/null
@@ -1,467 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.client.http;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URLEncoder;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.zip.GZIPOutputStream;
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.client.api.Result;
-import org.eclipse.jetty.client.util.BytesContentProvider;
-import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.toolchain.test.annotation.Slow;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class HttpClientTest extends AbstractHttpClientServerTest
-{
- public HttpClientTest(SslContextFactory sslContextFactory)
- {
- super(sslContextFactory);
- }
-
- @Test
- public void test_GET_ResponseWithoutContent() throws Exception
- {
- start(new EmptyServerHandler());
-
- Response response = client.GET(scheme + "://localhost:" + connector.getLocalPort());
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- }
-
- @Test
- public void test_GET_ResponseWithContent() throws Exception
- {
- final byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7};
- start(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- response.getOutputStream().write(data);
- baseRequest.setHandled(true);
- }
- });
-
- ContentResponse response = client.GET(scheme + "://localhost:" + connector.getLocalPort());
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- byte[] content = response.getContent();
- Assert.assertArrayEquals(data, content);
- }
-
- @Test
- public void test_GET_WithParameters_ResponseWithContent() throws Exception
- {
- final String paramName1 = "a";
- final String paramName2 = "b";
- start(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- response.setCharacterEncoding("UTF-8");
- ServletOutputStream output = response.getOutputStream();
- String paramValue1 = request.getParameter(paramName1);
- output.write(paramValue1.getBytes("UTF-8"));
- String paramValue2 = request.getParameter(paramName2);
- Assert.assertEquals("", paramValue2);
- output.write("empty".getBytes("UTF-8"));
- baseRequest.setHandled(true);
- }
- });
-
- String value1 = "\u20AC";
- String paramValue1 = URLEncoder.encode(value1, "UTF-8");
- String query = paramName1 + "=" + paramValue1 + "&" + paramName2;
- ContentResponse response = client.GET(scheme + "://localhost:" + connector.getLocalPort() + "/?" + query);
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- String content = new String(response.getContent(), "UTF-8");
- Assert.assertEquals(value1 + "empty", content);
- }
-
- @Test
- public void test_GET_WithParametersMultiValued_ResponseWithContent() throws Exception
- {
- final String paramName1 = "a";
- final String paramName2 = "b";
- start(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- response.setCharacterEncoding("UTF-8");
- ServletOutputStream output = response.getOutputStream();
- String[] paramValues1 = request.getParameterValues(paramName1);
- for (String paramValue : paramValues1)
- output.write(paramValue.getBytes("UTF-8"));
- String paramValue2 = request.getParameter(paramName2);
- output.write(paramValue2.getBytes("UTF-8"));
- baseRequest.setHandled(true);
- }
- });
-
- String value11 = "\u20AC";
- String value12 = "\u20AA";
- String value2 = "&";
- String paramValue11 = URLEncoder.encode(value11, "UTF-8");
- String paramValue12 = URLEncoder.encode(value12, "UTF-8");
- String paramValue2 = URLEncoder.encode(value2, "UTF-8");
- String query = paramName1 + "=" + paramValue11 + "&" + paramName1 + "=" + paramValue12 + "&" + paramName2 + "=" + paramValue2;
- ContentResponse response = client.GET(scheme + "://localhost:" + connector.getLocalPort() + "/?" + query);
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- String content = new String(response.getContent(), "UTF-8");
- Assert.assertEquals(value11 + value12 + value2, content);
- }
-
- @Test
- public void test_POST_WithParameters() throws Exception
- {
- final String paramName = "a";
- final String paramValue = "\u20AC";
- start(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- String value = request.getParameter(paramName);
- if (paramValue.equals(value))
- {
- response.setCharacterEncoding("UTF-8");
- response.setContentType("text/plain");
- response.getOutputStream().print(value);
- }
- }
- });
-
- ContentResponse response = client.POST(scheme + "://localhost:" + connector.getLocalPort())
- .param(paramName, paramValue)
- .timeout(5, TimeUnit.SECONDS)
- .send();
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- Assert.assertEquals(paramValue, new String(response.getContent(), "UTF-8"));
- }
-
- @Test
- public void test_PUT_WithParameters() throws Exception
- {
- final String paramName = "a";
- final String paramValue = "\u20AC";
- final String encodedParamValue = URLEncoder.encode(paramValue, "UTF-8");
- start(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- String value = request.getParameter(paramName);
- if (paramValue.equals(value))
- {
- response.setCharacterEncoding("UTF-8");
- response.setContentType("text/plain");
- response.getOutputStream().print(value);
- }
- }
- });
-
- URI uri = URI.create(scheme + "://localhost:" + connector.getLocalPort() + "/path?" + paramName + "=" + encodedParamValue);
- ContentResponse response = client.newRequest(uri)
- .method(HttpMethod.PUT)
- .timeout(5, TimeUnit.SECONDS)
- .send();
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- Assert.assertEquals(paramValue, new String(response.getContent(), "UTF-8"));
- }
-
- @Test
- public void test_POST_WithParameters_WithContent() throws Exception
- {
- final byte[] content = {0, 1, 2, 3};
- final String paramName = "a";
- final String paramValue = "\u20AC";
- start(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- String value = request.getParameter(paramName);
- if (paramValue.equals(value))
- {
- response.setCharacterEncoding("UTF-8");
- response.setContentType("application/octet-stream");
- response.getOutputStream().write(content);
- }
- }
- });
-
- ContentResponse response = client.POST(scheme + "://localhost:" + connector.getLocalPort() + "/?b=1")
- .param(paramName, paramValue)
- .content(new BytesContentProvider(content))
- .timeout(5, TimeUnit.SECONDS)
- .send();
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- Assert.assertArrayEquals(content, response.getContent());
- }
-
- @Test
- public void test_POST_WithContent_NotifiesRequestContentListener() throws Exception
- {
- final byte[] content = {0, 1, 2, 3};
- start(new EmptyServerHandler());
-
- ContentResponse response = client.POST(scheme + "://localhost:" + connector.getLocalPort())
- .onRequestContent(new Request.ContentListener()
- {
- @Override
- public void onContent(Request request, ByteBuffer buffer)
- {
- byte[] bytes = new byte[buffer.remaining()];
- buffer.get(bytes);
- if (!Arrays.equals(content, bytes))
- request.abort(new Exception());
- }
- })
- .content(new BytesContentProvider(content))
- .timeout(5, TimeUnit.SECONDS)
- .send();
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- }
-
- @Test
- public void test_POST_WithContent_TracksProgress() throws Exception
- {
- start(new EmptyServerHandler());
-
- final AtomicInteger progress = new AtomicInteger();
- ContentResponse response = client.POST(scheme + "://localhost:" + connector.getLocalPort())
- .onRequestContent(new Request.ContentListener()
- {
- @Override
- public void onContent(Request request, ByteBuffer buffer)
- {
- byte[] bytes = new byte[buffer.remaining()];
- Assert.assertEquals(1, bytes.length);
- buffer.get(bytes);
- Assert.assertEquals(bytes[0], progress.getAndIncrement());
- }
- })
- .content(new BytesContentProvider(new byte[]{0}, new byte[]{1}, new byte[]{2}, new byte[]{3}, new byte[]{4}))
- .timeout(5, TimeUnit.SECONDS)
- .send();
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- Assert.assertEquals(5, progress.get());
- }
-
- @Test
- public void test_GZIP_ContentEncoding() throws Exception
- {
- final byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- start(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- response.setHeader("Content-Encoding", "gzip");
- GZIPOutputStream gzipOutput = new GZIPOutputStream(response.getOutputStream());
- gzipOutput.write(data);
- gzipOutput.finish();
- }
- });
-
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
- .scheme(scheme)
- .timeout(5, TimeUnit.SECONDS)
- .send();
-
- Assert.assertEquals(200, response.getStatus());
- Assert.assertArrayEquals(data, response.getContent());
- }
-
- @Slow
- @Test
- public void test_Request_IdleTimeout() throws Exception
- {
- final long idleTimeout = 1000;
- start(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- try
- {
- baseRequest.setHandled(true);
- TimeUnit.MILLISECONDS.sleep(2 * idleTimeout);
- }
- catch (InterruptedException x)
- {
- throw new ServletException(x);
- }
- }
- });
-
- final String host = "localhost";
- final int port = connector.getLocalPort();
- try
- {
- client.newRequest(host, port)
- .scheme(scheme)
- .idleTimeout(idleTimeout, TimeUnit.MILLISECONDS)
- .timeout(3 * idleTimeout, TimeUnit.MILLISECONDS)
- .send();
- Assert.fail();
- }
- catch (ExecutionException expected)
- {
- Assert.assertTrue(expected.getCause() instanceof TimeoutException);
- }
-
- // Make another request without specifying the idle timeout, should not fail
- ContentResponse response = client.newRequest(host, port)
- .scheme(scheme)
- .timeout(3 * idleTimeout, TimeUnit.MILLISECONDS)
- .send();
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- }
-
- @Test
- public void testSendToIPv6Address() throws Exception
- {
- start(new EmptyServerHandler());
-
- ContentResponse response = client.newRequest("[::1]", connector.getLocalPort())
- .scheme(scheme)
- .timeout(5, TimeUnit.SECONDS)
- .send();
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- }
-
- @Test
- public void test_HEAD_With_ResponseContentLength() throws Exception
- {
- final int length = 1024;
- start(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- response.getOutputStream().write(new byte[length]);
- }
- });
-
- // HEAD requests receive a Content-Length header, but do not
- // receive the content so they must handle this case properly
- ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
- .scheme(scheme)
- .method(HttpMethod.HEAD)
- .timeout(5, TimeUnit.SECONDS)
- .send();
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- Assert.assertEquals(0, response.getContent().length);
-
- // Perform a normal GET request to be sure the content is now read
- response = client.newRequest("localhost", connector.getLocalPort())
- .scheme(scheme)
- .timeout(5, TimeUnit.SECONDS)
- .send();
-
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatus());
- Assert.assertEquals(length, response.getContent().length);
- }
-
- @Test
- public void testLongPollIsAbortedWhenClientIsStopped() throws Exception
- {
- final CountDownLatch latch = new CountDownLatch(1);
- start(new AbstractHandler()
- {
- @Override
- public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- request.startAsync();
- latch.countDown();
- }
- });
-
- final CountDownLatch completeLatch = new CountDownLatch(1);
- client.newRequest("localhost", connector.getLocalPort())
- .scheme(scheme)
- .send(new Response.CompleteListener()
- {
- @Override
- public void onComplete(Result result)
- {
- if (result.isFailed())
- completeLatch.countDown();
- }
- });
-
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
-
- // Stop the client, the complete listener must be invoked.
- client.stop();
-
- Assert.assertTrue(completeLatch.await(5, TimeUnit.SECONDS));
- }
-}
diff --git a/jetty-spdy/spdy-http-client-transport/src/test/resources/jetty-logging.properties b/jetty-spdy/spdy-http-client-transport/src/test/resources/jetty-logging.properties
deleted file mode 100644
index 8163013d57..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/test/resources/jetty-logging.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-#org.eclipse.jetty.LEVEL=DEBUG
-#org.eclipse.jetty.client.LEVEL=DEBUG
-#org.eclipse.jetty.spdy.LEVEL=DEBUG
diff --git a/jetty-spdy/spdy-http-client-transport/src/test/resources/keystore.jks b/jetty-spdy/spdy-http-client-transport/src/test/resources/keystore.jks
deleted file mode 100644
index 428ba54776..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/test/resources/keystore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-http-client-transport/src/test/resources/truststore.jks b/jetty-spdy/spdy-http-client-transport/src/test/resources/truststore.jks
deleted file mode 100644
index 839cb8c351..0000000000
--- a/jetty-spdy/spdy-http-client-transport/src/test/resources/truststore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-http-common/pom.xml b/jetty-spdy/spdy-http-common/pom.xml
deleted file mode 100644
index 769206b738..0000000000
--- a/jetty-spdy/spdy-http-common/pom.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-parent</artifactId>
- <version>9.2.15-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>spdy-http-common</artifactId>
- <name>Jetty :: SPDY :: HTTP Common</name>
-
- <properties>
- <bundle-symbolic-name>${project.groupId}.http.common</bundle-symbolic-name>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>manifest</goal>
- </goals>
- <configuration>
- <instructions>
- <Export-Package>org.eclipse.jetty.spdy.http;version="9.1"</Export-Package>
- <Import-Package>!org.eclipse.jetty.npn,org.eclipse.jetty.*;version="[9.0,10.0)",*</Import-Package>
- </instructions>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-core</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/jetty-spdy/spdy-http-common/src/main/java/org/eclipse/jetty/spdy/http/HTTPSPDYHeader.java b/jetty-spdy/spdy-http-common/src/main/java/org/eclipse/jetty/spdy/http/HTTPSPDYHeader.java
deleted file mode 100644
index 2959d6e09a..0000000000
--- a/jetty-spdy/spdy-http-common/src/main/java/org/eclipse/jetty/spdy/http/HTTPSPDYHeader.java
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.http;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.jetty.spdy.api.SPDY;
-
-/**
- * <p>{@link HTTPSPDYHeader} defines the SPDY headers that are not also HTTP headers,
- * such as <tt>method</tt>, <tt>version</tt>, etc. or that are treated differently
- * by the SPDY protocol, such as <tt>host</tt>.</p>
- */
-public enum HTTPSPDYHeader
-{
- METHOD("method", ":method"),
- URI("url", ":path"),
- VERSION("version", ":version"),
- SCHEME("scheme", ":scheme"),
- HOST("host", ":host"),
- STATUS("status", ":status");
-
- public static HTTPSPDYHeader from(short version, String name)
- {
- switch (version)
- {
- case SPDY.V2:
- return Names.v2Names.get(name);
- case SPDY.V3:
- return Names.v3Names.get(name);
- default:
- throw new IllegalStateException();
- }
- }
-
- private final String v2Name;
- private final String v3Name;
-
- private HTTPSPDYHeader(String v2Name, String v3Name)
- {
- this.v2Name = v2Name;
- Names.v2Names.put(v2Name, this);
- this.v3Name = v3Name;
- Names.v3Names.put(v3Name, this);
- }
-
- public String name(short version)
- {
- switch (version)
- {
- case SPDY.V2:
- return v2Name;
- case SPDY.V3:
- return v3Name;
- default:
- throw new IllegalStateException();
- }
- }
-
- private static class Names
- {
- private static final Map<String, HTTPSPDYHeader> v2Names = new HashMap<>();
- private static final Map<String, HTTPSPDYHeader> v3Names = new HashMap<>();
- }
-}
diff --git a/jetty-spdy/spdy-http-server/pom.xml b/jetty-spdy/spdy-http-server/pom.xml
deleted file mode 100644
index b20584099e..0000000000
--- a/jetty-spdy/spdy-http-server/pom.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-parent</artifactId>
- <version>9.2.15-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <artifactId>spdy-http-server</artifactId>
- <name>Jetty :: SPDY :: HTTP Server</name>
-
- <properties>
- <bundle-symbolic-name>${project.groupId}.http.server</bundle-symbolic-name>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- <configuration>
- <descriptorRefs>
- <descriptorRef>config</descriptorRef>
- </descriptorRefs>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <executions>
- <execution>
- <id>artifact-jars</id>
- <goals>
- <goal>jar</goal>
- <goal>test-jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>manifest</goal>
- </goals>
- <configuration>
- <instructions>
- <Export-Package>org.eclipse.jetty.spdy.server.http;version="9.1",
- org.eclipse.jetty.spdy.server.proxy;version="9.1"
- </Export-Package>
- <Import-Package>!org.eclipse.jetty.npn,org.eclipse.jetty.*;version="[9.0,10.0)",*
- </Import-Package>
- <_nouses>true</_nouses>
- </instructions>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-http-common</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-server</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-client</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-servlet</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-servlets</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.npn</groupId>
- <artifactId>npn-api</artifactId>
- <version>${npn.api.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-continuation</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/jetty-spdy/spdy-http-server/src/main/config/etc/jetty-spdy-proxy.xml b/jetty-spdy/spdy-http-server/src/main/config/etc/jetty-spdy-proxy.xml
deleted file mode 100644
index c525bd1797..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/etc/jetty-spdy-proxy.xml
+++ /dev/null
@@ -1,158 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
-
-<!-- ============================================================= -->
-<!-- Configure the Jetty Server instance with an ID "Server" -->
-<!-- by adding a SPDY connector. -->
-<!-- This configuration must be used in conjunction with jetty.xml -->
-<!-- It should not be used with jetty-https.xml as this connector -->
-<!-- can provide both HTTPS and SPDY connections -->
-<!-- ============================================================= -->
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <!-- =========================================================== -->
- <!-- Setup the SSL Context factory used to establish all TLS -->
- <!-- Connections and session. -->
- <!-- -->
- <!-- Consult the javadoc of o.e.j.util.ssl.SslContextFactory -->
- <!-- o.e.j.server.HttpConnectionFactory for all configuration -->
- <!-- that may be set here. -->
- <!-- =========================================================== -->
- <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
- <Set name="KeyStorePath"><Property name="jetty.home" default="." />/etc/keystore</Set>
- <Set name="KeyStorePassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
- <Set name="KeyManagerPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
- <Set name="TrustStorePath"><Property name="jetty.home" default="." />/etc/keystore</Set>
- <Set name="TrustStorePassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
- </New>
-
- <!-- =========================================================== -->
- <!-- Enables NPN debugging on System.err -->
- <!-- ===========================================================
- <Set class="org.eclipse.jetty.npn.NextProtoNego" name="debug" type="boolean">true</Set>
- -->
-
- <!-- =========================================================== -->
- <!-- Create a TLS specific HttpConfiguration based on the -->
- <!-- common HttpConfiguration defined in jetty.xml -->
- <!-- Add a SecureRequestCustomizer to extract certificate and -->
- <!-- session information -->
- <!-- =========================================================== -->
- <New id="tlsHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
- <Arg><Ref refid="httpConfig"/></Arg>
- <Call name="addCustomizer">
- <Arg><New class="org.eclipse.jetty.server.SecureRequestCustomizer"/></Arg>
- </Call>
- </New>
-
- <!-- =========================================================== -->
- <!-- This is the upstream server connector. -->
- <!-- It speaks non-SSL SPDY/3(HTTP) on port 9090. -->
- <!-- =========================================================== -->
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.ServerConnector">
- <Arg name="server">
- <Ref refid="Server"/>
- </Arg>
- <Arg name="factories">
- <Array type="org.eclipse.jetty.server.ConnectionFactory">
- <!-- SPDY/3 Connection factory -->
- <Item>
- <New class="org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory">
- <Arg name="version" type="int">3</Arg>
- <Arg name="config">
- <Ref refid="tlsHttpConfig"/>
- </Arg>
- </New>
- </Item>
- </Array>
- </Arg>
- <Set name="port">9090</Set>
- </New>
- </Arg>
- </Call>
-
- <!-- =========================================================== -->
- <!-- This ProxyEngine translates the incoming SPDY/x(HTTP) -->
- <!-- requests to SPDY/2(HTTP) -->
- <!-- =========================================================== -->
- <New id="spdyProxyEngine" class="org.eclipse.jetty.spdy.server.proxy.SPDYProxyEngine">
- <Arg>
- <New class="org.eclipse.jetty.spdy.client.SPDYClient$Factory">
- <Call name="start"/>
- </New>
- </Arg>
- </New>
-
- <!-- =========================================================== -->
- <!-- The ProxyEngineSelector receives SPDY/x(HTTP) requests -->
- <!-- from proxy connectors below and is configured to process -->
- <!-- requests for host "localhost". -->
- <!-- Such requests are converted from SPDY/x(HTTP) to -->
- <!-- SPDY/3(HTTP) by the configured ProxyEngine and forwarded -->
- <!-- to 127.0.0.1:9090, where they are served by the upstream -->
- <!-- server above. -->
- <!-- =========================================================== -->
- <New id="proxyEngineSelector" class="org.eclipse.jetty.spdy.server.proxy.ProxyEngineSelector">
- <Call name="putProxyEngine">
- <Arg>spdy/3</Arg>
- <Arg>
- <Ref refid="spdyProxyEngine"/>
- </Arg>
- </Call>
- <Set name="proxyServerInfos">
- <Map>
- <Entry>
- <Item>localhost</Item>
- <Item>
- <New class="org.eclipse.jetty.spdy.server.proxy.ProxyEngineSelector$ProxyServerInfo">
- <Arg type="String">spdy/3</Arg>
- <Arg>127.0.0.1</Arg>
- <Arg type="int">9090</Arg>
- </New>
- </Item>
- </Entry>
- </Map>
- </Set>
- </New>
-
- <!-- =========================================================== -->
- <!-- These are the reverse proxy connectors accepting requests -->
- <!-- from clients. -->
- <!-- They accept non-SSL (on port 8080) and SSL (on port 8443) -->
- <!-- HTTP, SPDY/2(HTTP) and SPDY/3(HTTP). -->
- <!-- Non-SPDY HTTP requests are converted to SPDY internally -->
- <!-- and passed to the ProxyEngine above. -->
- <!-- =========================================================== -->
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.spdy.server.proxy.HTTPSPDYProxyServerConnector">
- <Arg>
- <Ref refid="Server"/>
- </Arg>
- <Arg>
- <Ref refid="proxyEngineSelector"/>
- </Arg>
- <Set name="Port">8080</Set>
- </New>
- </Arg>
- </Call>
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.spdy.server.proxy.HTTPSPDYProxyServerConnector">
- <Arg>
- <Ref refid="Server"/>
- </Arg>
- <Arg>
- <Ref refid="sslContextFactory"/>
- </Arg>
- <Arg>
- <Ref refid="proxyEngineSelector"/>
- </Arg>
- <Set name="Port">8443</Set>
- </New>
- </Arg>
- </Call>
-
-</Configure>
diff --git a/jetty-spdy/spdy-http-server/src/main/config/etc/jetty-spdy.xml b/jetty-spdy/spdy-http-server/src/main/config/etc/jetty-spdy.xml
deleted file mode 100644
index b094d7ce85..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/etc/jetty-spdy.xml
+++ /dev/null
@@ -1,139 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
-
-<!-- ============================================================= -->
-<!-- Configure a SPDY connector. -->
-<!-- This configuration must be used in conjunction with jetty.xml -->
-<!-- and jetty-ssl.xml -->
-<!-- ============================================================= -->
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <!-- =========================================================== -->
- <!-- Create a push strategy which can be used by reference by -->
- <!-- individual connection factories below. -->
- <!-- -->
- <!-- Consult the javadoc of o.e.j.spdy.server.http.ReferrerPushStrategy -->
- <!-- for all configuration that may be set here. -->
- <!-- =========================================================== -->
- <New id="pushStrategy" class="org.eclipse.jetty.spdy.server.http.ReferrerPushStrategy">
- <!-- Uncomment to blacklist browsers for this push strategy. If one of the blacklisted Strings occurs in the
- user-agent header sent by the client, push will be disabled for this browser. This is case insensitive" -->
- <!--
- <Set name="UserAgentBlacklist">
- <Array type="String">
- <Item>.*(?i)firefox/14.*</Item>
- <Item>.*(?i)firefox/15.*</Item>
- <Item>.*(?i)firefox/16.*</Item>
- </Array>
- </Set>
- -->
-
- <!-- Uncomment to override default file extensions to push -->
- <!--
- <Set name="PushRegexps">
- <Array type="String">
- <Item>.*\.css</Item>
- <Item>.*\.js</Item>
- <Item>.*\.png</Item>
- <Item>.*\.jpg</Item>
- <Item>.*\.gif</Item>
- </Array>
- </Set>
- -->
- <Set name="referrerPushPeriod">5000</Set>
- <Set name="maxAssociatedResources">32</Set>
- </New>
-
- <!-- =========================================================== -->
- <!-- Add a SPDY/HTTPS Connector. -->
- <!-- Configure an o.e.j.server.ServerConnector with connection -->
- <!-- factories for TLS (aka SSL), ProtoNego, SPDY and HTTP to -->
- <!-- provide a connector that can accept HTTPS or SPDY -->
- <!-- connections. -->
- <!-- -->
- <!-- All accepted TLS connections are initially wired to a -->
- <!-- Protonego connection, which attempts to use a TLS extension -->
- <!-- to negotiation the protocol. If it is not supported by -->
- <!-- the client, then the connection is replaced by a HTTP -->
- <!-- connection. If a specific protocol version (eg spdy/3) is -->
- <!-- negotiated, then the appropriate connection factory -->
- <!-- is used to create a connection to replace the connection -->
- <!-- -->
- <!-- The final result is a SPDY or HTTP connection wired behind -->
- <!-- a TLS (aka SSL) connection. -->
- <!-- -->
- <!-- Consult the javadoc of o.e.j.server.ServerConnector and the -->
- <!-- specific connection factory types for all configuration -->
- <!-- that may be set here. -->
- <!-- =========================================================== -->
- <Call id="spdyConnector" name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.ServerConnector">
- <Arg name="server">
- <Ref refid="Server"/>
- </Arg>
- <Arg name="factories">
- <Array type="org.eclipse.jetty.server.ConnectionFactory">
-
- <!-- SSL Connection factory with Protonego as next protocol -->
- <Item>
- <New class="org.eclipse.jetty.server.SslConnectionFactory">
- <Arg name="next"><Property name="protonego"/></Arg>
- <Arg name="sslContextFactory">
- <Ref refid="sslContextFactory"/>
- </Arg>
- </New>
- </Item>
-
- <!-- NPN Connection factory with HTTP as default protocol -->
- <Item>
- <Ref refid="protonego"/>
- </Item>
-
- <!-- SPDY/3 Connection factory -->
- <Item>
- <New class="org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory">
- <Arg name="version" type="int">3</Arg>
- <Arg name="config">
- <Ref refid="sslHttpConfig"/>
- </Arg>
- <!-- Set the initial window size for this SPDY connector. -->
- <!-- See: http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3#TOC-2.6.8-WINDOW_UPDATE -->
- <Set name="initialWindowSize"><Property name="spdy.initialWindowSize" default="65536"/></Set>
- <!-- Uncomment to enable ReferrerPushStrategy -->
- <!--<Arg name="pushStrategy"><Ref refid="pushStrategy"/></Arg>-->
- </New>
- </Item>
-
- <!-- SPDY/2 Connection factory -->
- <Item>
- <New class="org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory">
- <Arg name="version" type="int">2</Arg>
- <Arg name="config">
- <Ref refid="sslHttpConfig"/>
- </Arg>
- <!-- Set the initial window size for this SPDY connector. -->
- <!-- See: http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3#TOC-2.6.8-WINDOW_UPDATE -->
- <Set name="initialWindowSize"><Property name="spdy.initialWindowSize" default="65536"/></Set>
- </New>
- </Item>
-
- <!-- HTTP Connection factory -->
- <Item>
- <New class="org.eclipse.jetty.server.HttpConnectionFactory">
- <Arg name="config">
- <Ref refid="sslHttpConfig"/>
- </Arg>
- </New>
- </Item>
- </Array>
- </Arg>
-
- <Set name="host"><Property name="jetty.host"/></Set>
- <Set name="port"><Property name="spdy.port" default="443"/></Set>
- <Set name="idleTimeout"><Property name="spdy.timeout" default="30000"/></Set>
- </New>
- </Arg>
- </Call>
-
-</Configure>
diff --git a/jetty-spdy/spdy-http-server/src/main/config/etc/protonego-npn.xml b/jetty-spdy/spdy-http-server/src/main/config/etc/protonego-npn.xml
deleted file mode 100644
index 6e30f39ed6..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/etc/protonego-npn.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
-
-<Configure id="protonego" class="org.eclipse.jetty.spdy.server.NPNServerConnectionFactory">
- <Arg name="protocols">
- <Array type="String">
- <Item>spdy/3</Item>
- <Item>spdy/2</Item>
- <Item>http/1.1</Item>
- </Array>
- </Arg>
-
- <Set name="defaultProtocol">http/1.1</Set>
-
- <!-- =========================================================== -->
- <!-- Enables NPN debugging on System.err -->
- <!-- ===========================================================
- <Set class="org.eclipse.jetty.npn.NextProtoNego" name="debug" type="boolean">true</Set>
- -->
-
-</Configure>
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_04.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_04.mod
deleted file mode 100644
index 007570b675..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_04.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.0.v20120525/npn-boot-1.1.0.v20120525.jar|lib/npn/npn-boot-1.1.0.v20120525.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.0.v20120525.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_05.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_05.mod
deleted file mode 100644
index 007570b675..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_05.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.0.v20120525/npn-boot-1.1.0.v20120525.jar|lib/npn/npn-boot-1.1.0.v20120525.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.0.v20120525.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_06.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_06.mod
deleted file mode 100644
index 868a7a77fc..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_06.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.1.v20121030/npn-boot-1.1.1.v20121030.jar|lib/npn/npn-boot-1.1.1.v20121030.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.1.v20121030.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_07.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_07.mod
deleted file mode 100644
index 868a7a77fc..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_07.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.1.v20121030/npn-boot-1.1.1.v20121030.jar|lib/npn/npn-boot-1.1.1.v20121030.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.1.v20121030.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_09.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_09.mod
deleted file mode 100644
index 20c1db27bd..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_09.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.3.v20130313/npn-boot-1.1.3.v20130313.jar|lib/npn/npn-boot-1.1.3.v20130313.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.3.v20130313.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_10.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_10.mod
deleted file mode 100644
index 20c1db27bd..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_10.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.3.v20130313/npn-boot-1.1.3.v20130313.jar|lib/npn/npn-boot-1.1.3.v20130313.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.3.v20130313.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_11.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_11.mod
deleted file mode 100644
index 20c1db27bd..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_11.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.3.v20130313/npn-boot-1.1.3.v20130313.jar|lib/npn/npn-boot-1.1.3.v20130313.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.3.v20130313.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_13.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_13.mod
deleted file mode 100644
index 1645a52dba..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_13.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.4.v20130313/npn-boot-1.1.4.v20130313.jar|lib/npn/npn-boot-1.1.4.v20130313.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.4.v20130313.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_15.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_15.mod
deleted file mode 100644
index 73bc09007e..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_15.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar|lib/npn/npn-boot-1.1.5.v20130313.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.5.v20130313.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_17.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_17.mod
deleted file mode 100644
index 73bc09007e..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_17.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar|lib/npn/npn-boot-1.1.5.v20130313.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.5.v20130313.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_21.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_21.mod
deleted file mode 100644
index 73bc09007e..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_21.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar|lib/npn/npn-boot-1.1.5.v20130313.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.5.v20130313.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_25.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_25.mod
deleted file mode 100644
index 73bc09007e..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_25.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar|lib/npn/npn-boot-1.1.5.v20130313.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.5.v20130313.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_40.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_40.mod
deleted file mode 100644
index 465e6f034b..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_40.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.6.v20130911/npn-boot-1.1.6.v20130911.jar|lib/npn/npn-boot-1.1.6.v20130911.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.6.v20130911.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_45.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_45.mod
deleted file mode 100644
index 465e6f034b..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_45.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.6.v20130911/npn-boot-1.1.6.v20130911.jar|lib/npn/npn-boot-1.1.6.v20130911.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.6.v20130911.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_51.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_51.mod
deleted file mode 100644
index 465e6f034b..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_51.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.6.v20130911/npn-boot-1.1.6.v20130911.jar|lib/npn/npn-boot-1.1.6.v20130911.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.6.v20130911.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_55.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_55.mod
deleted file mode 100644
index 5f8704d68a..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_55.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.8.v20141013/npn-boot-1.1.8.v20141013.jar|lib/npn/npn-boot-1.1.8.v20141013.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.8.v20141013.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_60.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_60.mod
deleted file mode 100644
index 5f8704d68a..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_60.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.8.v20141013/npn-boot-1.1.8.v20141013.jar|lib/npn/npn-boot-1.1.8.v20141013.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.8.v20141013.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_65.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_65.mod
deleted file mode 100644
index 5f8704d68a..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_65.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.8.v20141013/npn-boot-1.1.8.v20141013.jar|lib/npn/npn-boot-1.1.8.v20141013.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.8.v20141013.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_67.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_67.mod
deleted file mode 100644
index 5f8704d68a..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_67.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.8.v20141013/npn-boot-1.1.8.v20141013.jar|lib/npn/npn-boot-1.1.8.v20141013.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.8.v20141013.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_71.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_71.mod
deleted file mode 100644
index 851aca8727..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_71.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.9.v20141016/npn-boot-1.1.9.v20141016.jar|lib/npn/npn-boot-1.1.9.v20141016.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.9.v20141016.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_72.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_72.mod
deleted file mode 100644
index 851aca8727..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_72.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.9.v20141016/npn-boot-1.1.9.v20141016.jar|lib/npn/npn-boot-1.1.9.v20141016.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.9.v20141016.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_75.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_75.mod
deleted file mode 100644
index a5fac1140c..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_75.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.10.v20150130/npn-boot-1.1.10.v20150130.jar|lib/npn/npn-boot-1.1.10.v20150130.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.10.v20150130.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_76.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_76.mod
deleted file mode 100644
index a5fac1140c..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_76.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.10.v20150130/npn-boot-1.1.10.v20150130.jar|lib/npn/npn-boot-1.1.10.v20150130.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.10.v20150130.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_79.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_79.mod
deleted file mode 100644
index a5fac1140c..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_79.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.10.v20150130/npn-boot-1.1.10.v20150130.jar|lib/npn/npn-boot-1.1.10.v20150130.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.10.v20150130.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_80.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_80.mod
deleted file mode 100644
index 2cce5fab7c..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn-1.7.0_80.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-[name]
-protonego-boot
-
-[files]
-http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.11.v20150415/npn-boot-1.1.11.v20150415.jar|lib/npn/npn-boot-1.1.11.v20150415.jar
-
-[exec]
--Xbootclasspath/p:lib/npn/npn-boot-1.1.11.v20150415.jar
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod
deleted file mode 100644
index 1a2c71d721..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod
+++ /dev/null
@@ -1,37 +0,0 @@
-# NPN is provided via a -Xbootclasspath that modifies the secure connections
-# in java to support the NPN layer needed for SPDY.
-#
-# This modification has a tight dependency on specific updates of Java 1.7.
-# (No support for Java 8 exists for npn / npn-boot, use alpn instead)
-#
-# The npn module will use an appropriate npn-boot jar for your specific
-# version of Java.
-#
-# IMPORTANT: Versions of Java that exist after this module was created are
-# not guaranteed to work with existing npn-boot jars, and might
-# need a new npn-boot to be created / tested / deployed by the
-# Jetty project in order to provide support for these future
-# Java versions.
-#
-# All versions of npn-boot can be found at
-# http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/
-
-
-[name]
-protonego-impl
-
-[depend]
-protonego-impl/npn-${java.version}
-
-[xml]
-etc/protonego-npn.xml
-
-[files]
-lib/
-lib/npn/
-
-[license]
-NPN is a hosted at github under the GPL v2 with ClassPath Exception.
-NPN replaces/modifies OpenJDK classes in the java.sun.security.ssl package.
-http://github.com/jetty-project/jetty-npn
-http://openjdk.java.net/legal/gplv2+ce.html
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/spdy.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/spdy.mod
deleted file mode 100644
index cf79dfa0f2..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/spdy.mod
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# SPDY Support Module
-#
-
-[depend]
-ssl
-protonego
-
-[lib]
-lib/spdy/*.jar
-
-[xml]
-etc/jetty-ssl.xml
-etc/jetty-spdy.xml
-
-[ini-template]
-## SPDY Configuration
-
-# Port for SPDY connections
-spdy.port=8443
-
-# SPDY idle timeout in milliseconds
-spdy.timeout=30000
-
-# Initial Window Size for SPDY
-#spdy.initialWindowSize=65536
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HTTPSPDYServerConnectionFactory.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HTTPSPDYServerConnectionFactory.java
deleted file mode 100644
index 34eef7c66e..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HTTPSPDYServerConnectionFactory.java
+++ /dev/null
@@ -1,167 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.http;
-
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.annotation.Name;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class HTTPSPDYServerConnectionFactory extends SPDYServerConnectionFactory implements HttpConfiguration.ConnectionFactory
-{
- private static final String CHANNEL_ATTRIBUTE = "org.eclipse.jetty.spdy.server.http.HTTPChannelOverSPDY";
- private static final Logger LOG = Log.getLogger(HTTPSPDYServerConnectionFactory.class);
-
- private final PushStrategy pushStrategy;
- private final HttpConfiguration httpConfiguration;
-
- public HTTPSPDYServerConnectionFactory(
- @Name("version") int version,
- @Name("config") HttpConfiguration config)
- {
- this(version,config,new PushStrategy.None());
- }
-
- public HTTPSPDYServerConnectionFactory(
- @Name("version") int version,
- @Name("config") HttpConfiguration config,
- @Name("pushStrategy") PushStrategy pushStrategy)
- {
- super(version);
- this.pushStrategy = pushStrategy;
- httpConfiguration = config;
- addBean(httpConfiguration);
- }
-
- @Override
- public HttpConfiguration getHttpConfiguration()
- {
- return httpConfiguration;
- }
-
- @Override
- protected ServerSessionFrameListener provideServerSessionFrameListener(Connector connector, EndPoint endPoint)
- {
- return new HTTPServerFrameListener(connector,endPoint);
- }
-
- private class HTTPServerFrameListener extends ServerSessionFrameListener.Adapter implements StreamFrameListener
- {
- private final Connector connector;
- private final EndPoint endPoint;
-
- public HTTPServerFrameListener(Connector connector,EndPoint endPoint)
- {
- this.endPoint = endPoint;
- this.connector=connector;
- }
-
- @Override
- public StreamFrameListener onSyn(final Stream stream, SynInfo synInfo)
- {
- // Every time we have a SYN, it maps to a HTTP request.
- // We can have multiple concurrent SYNs on the same connection,
- // and this is very different from HTTP, where only one request
- // can arrive on the same connection, so we need to create an
- // HttpChannel for each SYN in order to run concurrently.
-
- if (LOG.isDebugEnabled())
- LOG.debug("Received {} on {}", synInfo, stream);
-
- Fields headers = synInfo.getHeaders();
- // According to SPDY/3 spec section 3.2.1 user-agents MUST support gzip compression. Firefox omits the
- // accept-encoding header as it is redundant to negotiate gzip compression support with the server,
- // if clients have to accept it.
- // So we inject the accept-encoding header here, even if not set by the client. This will enforce SPDY
- // clients to follow the spec and enable gzip compression if GzipFilter or the like is enabled.
- if (!(headers.get("accept-encoding") != null && headers.get("accept-encoding").getValue().contains
- ("gzip")))
- headers.add("accept-encoding", "gzip");
- HttpTransportOverSPDY transport = new HttpTransportOverSPDY(connector, httpConfiguration, endPoint,
- pushStrategy, stream, headers);
- HttpInputOverSPDY input = new HttpInputOverSPDY();
- HttpChannelOverSPDY channel = new HttpChannelOverSPDY(connector, httpConfiguration, endPoint, transport, input, stream);
- stream.setAttribute(CHANNEL_ATTRIBUTE, channel);
-
- channel.requestStart(headers, synInfo.isClose());
-
- if (headers.isEmpty())
- {
- // If the SYN has no headers, they may come later in a HEADERS frame
- return this;
- }
- else
- {
- if (synInfo.isClose())
- return null;
- else
- return this;
- }
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- // Do nothing, servers cannot get replies
- }
-
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Received {} on {}", headersInfo, stream);
- HttpChannelOverSPDY channel = (HttpChannelOverSPDY)stream.getAttribute(CHANNEL_ATTRIBUTE);
- channel.requestHeaders(headersInfo.getHeaders(), headersInfo.isClose());
- }
-
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- return null;
- }
-
- @Override
- public void onData(Stream stream, final DataInfo dataInfo)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Received {} on {}", dataInfo, stream);
- HttpChannelOverSPDY channel = (HttpChannelOverSPDY)stream.getAttribute(CHANNEL_ATTRIBUTE);
- channel.requestContent(dataInfo, dataInfo.isClose());
- }
-
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- LOG.debug(x);
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HTTPSPDYServerConnector.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HTTPSPDYServerConnector.java
deleted file mode 100644
index 25d1e39797..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HTTPSPDYServerConnector.java
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.eclipse.jetty.server.AbstractConnectionFactory;
-import org.eclipse.jetty.server.ConnectionFactory;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-
-public class HTTPSPDYServerConnector extends ServerConnector
-{
- public HTTPSPDYServerConnector(Server server)
- {
- this(server, Collections.<Short, PushStrategy>emptyMap());
- }
-
- public HTTPSPDYServerConnector(Server server, SslContextFactory sslContextFactory)
- {
- this(server, sslContextFactory, Collections.<Short, PushStrategy>emptyMap());
- }
-
- public HTTPSPDYServerConnector(Server server, Map<Short, PushStrategy> pushStrategies)
- {
- this(server, null, pushStrategies);
- }
-
- public HTTPSPDYServerConnector(Server server, SslContextFactory sslContextFactory, Map<Short, PushStrategy> pushStrategies)
- {
- this(server, new HttpConfiguration(), sslContextFactory, pushStrategies);
- }
-
- public HTTPSPDYServerConnector(Server server, short version, HttpConfiguration httpConfiguration, PushStrategy push)
- {
- super(server, new HTTPSPDYServerConnectionFactory(version, httpConfiguration, push));
- }
-
- public HTTPSPDYServerConnector(Server server, HttpConfiguration config, SslContextFactory sslContextFactory, Map<Short, PushStrategy> pushStrategies)
- {
- super(server, AbstractConnectionFactory.getFactories(sslContextFactory,
- sslContextFactory == null
- ? new ConnectionFactory[]{new HttpConnectionFactory(config)}
- : new ConnectionFactory[]{new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"),
- new HttpConnectionFactory(config),
- new HTTPSPDYServerConnectionFactory(SPDY.V3, config, getPushStrategy(SPDY.V3, pushStrategies)),
- new HTTPSPDYServerConnectionFactory(SPDY.V2, config, getPushStrategy(SPDY.V2, pushStrategies))}));
- NPNServerConnectionFactory npnConnectionFactory = getConnectionFactory(NPNServerConnectionFactory.class);
- if (npnConnectionFactory != null)
- npnConnectionFactory.setDefaultProtocol("http/1.1");
- }
-
- private static PushStrategy getPushStrategy(short version, Map<Short, PushStrategy> pushStrategies)
- {
- PushStrategy pushStrategy = pushStrategies.get(version);
- if (pushStrategy == null)
- pushStrategy = new PushStrategy.None();
- return pushStrategy;
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java
deleted file mode 100644
index f336f4f47c..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java
+++ /dev/null
@@ -1,246 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.http.HttpVersion;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpChannel;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpTransport;
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class HttpChannelOverSPDY extends HttpChannel<DataInfo>
-{
- private static final Logger LOG = Log.getLogger(HttpChannelOverSPDY.class);
-
- private final Stream stream;
- private boolean dispatched; // Guarded by synchronization on tasks
- private boolean redispatch; // Guarded by synchronization on tasks
- private boolean headersComplete;
-
- public HttpChannelOverSPDY(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInputOverSPDY input, Stream stream)
- {
- super(connector, configuration, endPoint, transport, input);
- this.stream = stream;
- }
-
- @Override
- public long getIdleTimeout()
- {
- return stream.getIdleTimeout();
- }
-
- @Override
- public boolean headerComplete()
- {
- headersComplete = true;
- return super.headerComplete();
- }
-
- private void dispatch()
- {
- synchronized (this)
- {
- if (dispatched)
- redispatch=true;
- else
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Dispatch {}", this);
- dispatched=true;
- execute(this);
- }
- }
- }
-
- @Override
- public void run()
- {
- boolean execute=true;
-
- while(execute)
- {
- try
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Executing {}",this);
- super.run();
- }
- finally
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Completing {}", this);
- synchronized (this)
- {
- dispatched = redispatch;
- redispatch=false;
- execute=dispatched;
- }
- }
- }
- }
-
-
- public void requestStart(final Fields headers, final boolean endRequest)
- {
- if (!headers.isEmpty())
- requestHeaders(headers, endRequest);
- }
-
- public void requestHeaders(Fields headers, boolean endRequest)
- {
- boolean proceed = performBeginRequest(headers);
- if (!proceed)
- return;
-
- performHeaders(headers);
-
- if (endRequest)
- {
- boolean dispatch = headerComplete();
- if (messageComplete())
- dispatch=true;
- if (dispatch)
- dispatch();
- }
- }
-
- public void requestContent(final DataInfo dataInfo, boolean endRequest)
- {
- boolean dispatch=false;
- if (!headersComplete && headerComplete())
- dispatch=true;
-
- if (LOG.isDebugEnabled())
- LOG.debug("HTTP > {} bytes of content", dataInfo.length());
-
- // We need to copy the dataInfo since we do not know when its bytes
- // will be consumed. When the copy is consumed, we consume also the
- // original, so the implementation can send a window update.
- ByteBuffer copyByteBuffer = dataInfo.asByteBuffer(false);
- ByteBufferDataInfo copyDataInfo = new ByteBufferDataInfo(copyByteBuffer, dataInfo.isClose())
- {
- @Override
- public void consume(int delta)
- {
- super.consume(delta);
- dataInfo.consume(delta);
- }
- };
- if (LOG.isDebugEnabled())
- LOG.debug("Queuing last={} content {}", endRequest, copyDataInfo);
-
- if (content(copyDataInfo))
- dispatch=true;
-
- if (endRequest && messageComplete())
- dispatch=true;
-
- if (dispatch)
- dispatch();
- }
-
- @Override
- public boolean messageComplete()
- {
- super.messageComplete();
- return false;
- }
-
- private boolean performBeginRequest(Fields headers)
- {
- short version = stream.getSession().getVersion();
- Fields.Field methodHeader = headers.get(HTTPSPDYHeader.METHOD.name(version));
- Fields.Field uriHeader = headers.get(HTTPSPDYHeader.URI.name(version));
- Fields.Field versionHeader = headers.get(HTTPSPDYHeader.VERSION.name(version));
-
- if (methodHeader == null || uriHeader == null || versionHeader == null)
- {
- badMessage(400, "Missing required request line elements");
- return false;
- }
-
- HttpMethod httpMethod = HttpMethod.fromString(methodHeader.getValue());
- HttpVersion httpVersion = HttpVersion.fromString(versionHeader.getValue());
-
- // TODO should handle URI as byte buffer as some bad clients send WRONG encodings in query string
- // that we have to deal with
- ByteBuffer uri = BufferUtil.toBuffer(uriHeader.getValue());
-
- if (LOG.isDebugEnabled())
- LOG.debug("HTTP > {} {} {}", httpMethod, uriHeader.getValue(), httpVersion);
- startRequest(httpMethod, httpMethod.asString(), uri, httpVersion);
-
- Fields.Field schemeHeader = headers.get(HTTPSPDYHeader.SCHEME.name(version));
- if (schemeHeader != null)
- getRequest().setScheme(schemeHeader.getValue());
- return true;
- }
-
- private void performHeaders(Fields headers)
- {
- for (Fields.Field header : headers)
- {
- String name = header.getName();
-
- // Skip special SPDY headers, unless it's the "host" header
- HTTPSPDYHeader specialHeader = HTTPSPDYHeader.from(stream.getSession().getVersion(), name);
- if (specialHeader != null)
- {
- if (specialHeader == HTTPSPDYHeader.HOST)
- name = "host";
- else
- continue;
- }
-
- switch (name)
- {
- case "connection":
- case "keep-alive":
- case "proxy-connection":
- case "transfer-encoding":
- {
- // Spec says to ignore these headers
- continue;
- }
- default:
- {
- // Spec says headers must be single valued
- String value = header.getValue();
- if (LOG.isDebugEnabled())
- LOG.debug("HTTP > {}: {}", name, value);
- parsedHeader(new HttpField(name,value));
- break;
- }
- }
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpInputOverSPDY.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpInputOverSPDY.java
deleted file mode 100644
index 08bb592d3a..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpInputOverSPDY.java
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import org.eclipse.jetty.server.QueuedHttpInput;
-import org.eclipse.jetty.spdy.api.DataInfo;
-
-public class HttpInputOverSPDY extends QueuedHttpInput<DataInfo>
-{
- @Override
- protected int remaining(DataInfo item)
- {
- return item.available();
- }
-
- @Override
- protected int get(DataInfo item, byte[] buffer, int offset, int length)
- {
- return item.readInto(buffer, offset, length);
- }
-
- @Override
- protected void consume(DataInfo item, int length)
- {
- item.consume(length);
- }
-
- @Override
- protected void onContentConsumed(DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java
deleted file mode 100644
index aa46cd3f42..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java
+++ /dev/null
@@ -1,423 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.nio.ByteBuffer;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpGenerator;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.http.HttpVersion;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.EofException;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpTransport;
-import org.eclipse.jetty.spdy.StreamException;
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.ConcurrentArrayQueue;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class HttpTransportOverSPDY implements HttpTransport
-{
- private static final Logger LOG = Log.getLogger(HttpTransportOverSPDY.class);
-
- private final Connector connector;
- private final HttpConfiguration configuration;
- private final EndPoint endPoint;
- private final PushStrategy pushStrategy;
- private final Stream stream;
- private final short version;
- private final Fields requestHeaders;
- private final AtomicBoolean committed = new AtomicBoolean();
-
- public HttpTransportOverSPDY(Connector connector, HttpConfiguration configuration, EndPoint endPoint, PushStrategy pushStrategy, Stream stream, Fields requestHeaders)
- {
- this.connector = connector;
- this.configuration = configuration;
- this.endPoint = endPoint;
- this.pushStrategy = pushStrategy == null ? new PushStrategy.None() : pushStrategy;
- this.stream = stream;
- this.requestHeaders = requestHeaders;
- Session session = stream.getSession();
- this.version = session.getVersion();
- }
-
- protected Stream getStream()
- {
- return stream;
- }
-
- protected Fields getRequestHeaders()
- {
- return requestHeaders;
- }
-
-
- @Override
- public void send(ByteBuffer responseBodyContent, boolean lastContent, Callback callback)
- {
- // TODO can this be more efficient?
- send(null, responseBodyContent, lastContent, callback);
- }
-
- @Override
- public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, final Callback callback)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Sending {} {} {} {} last={}", this, stream, info, BufferUtil.toDetailString(content), lastContent);
-
- if (stream.isClosed() || stream.isReset())
- {
- EofException exception = new EofException("stream closed");
- callback.failed(exception);
- return;
- }
-
- // info==null content==null lastContent==false should not happen
- // info==null content==null lastContent==true signals no more content - complete
- // info==null content!=null lastContent==false send data on committed response
- // info==null content!=null lastContent==true send last data on committed response - complete
- // info!=null content==null lastContent==false reply, commit
- // info!=null content==null lastContent==true reply, commit and complete
- // info!=null content!=null lastContent==false reply, commit with content
- // info!=null content!=null lastContent==true reply, commit with content and complete
-
- boolean isHeadRequest = HttpMethod.HEAD.name().equalsIgnoreCase(requestHeaders.get(HTTPSPDYHeader.METHOD.name(version)).getValue());
- boolean hasContent = BufferUtil.hasContent(content) && !isHeadRequest;
- boolean close = !hasContent && lastContent;
-
- if (info != null)
- {
- if (!committed.compareAndSet(false, true))
- {
- StreamException exception = new StreamException(stream.getId(), StreamStatus.PROTOCOL_ERROR,
- "Stream already committed!");
- callback.failed(exception);
- if (LOG.isDebugEnabled())
- LOG.debug("Committed response twice.", exception);
- return;
- }
- sendReply(info, !hasContent ? callback : new Callback.Adapter()
- {
- @Override
- public void failed(Throwable x)
- {
- callback.failed(x);
- }
- }, close);
- }
-
- // Do we have some content to send as well
- if (hasContent)
- {
- // send the data and let it call the callback
- if (LOG.isDebugEnabled())
- LOG.debug("Send content: {} on stream: {} lastContent={}", BufferUtil.toDetailString(content), stream,
- lastContent);
- stream.data(new ByteBufferDataInfo(endPoint.getIdleTimeout(), TimeUnit.MILLISECONDS, content, lastContent
- ), callback);
- }
- // else do we need to close
- else if (lastContent && info == null)
- {
- // send empty data to close and let the send call the callback
- if (LOG.isDebugEnabled())
- LOG.debug("No content and lastContent=true. Sending empty ByteBuffer to close stream: {}", stream);
- stream.data(new ByteBufferDataInfo(endPoint.getIdleTimeout(), TimeUnit.MILLISECONDS,
- BufferUtil.EMPTY_BUFFER, lastContent), callback);
- }
- else if (!lastContent && !hasContent && info == null)
- throw new IllegalStateException("not lastContent, no content and no responseInfo!");
-
- }
-
- private void sendReply(HttpGenerator.ResponseInfo info, Callback callback, boolean close)
- {
- Fields headers = new Fields();
-
- HttpVersion httpVersion = HttpVersion.HTTP_1_1;
- headers.put(HTTPSPDYHeader.VERSION.name(version), httpVersion.asString());
-
- int status = info.getStatus();
- StringBuilder httpStatus = new StringBuilder().append(status);
- String reason = info.getReason();
- if (reason == null)
- reason = HttpStatus.getMessage(status);
- if (reason != null)
- httpStatus.append(" ").append(reason);
- headers.put(HTTPSPDYHeader.STATUS.name(version), httpStatus.toString());
- if (LOG.isDebugEnabled())
- LOG.debug("HTTP < {} {}", httpVersion, httpStatus);
-
- // TODO merge the two Field classes into one
- HttpFields fields = info.getHttpFields();
- if (fields != null)
- {
- for (int i = 0; i < fields.size(); ++i)
- {
- HttpField field = fields.getField(i);
- String name = field.getName();
- String value = field.getValue();
- headers.add(name, value);
- if (LOG.isDebugEnabled())
- LOG.debug("HTTP < {}: {}", name, value);
- }
- }
-
- if (configuration.getSendServerVersion())
- headers.add(HttpHeader.SERVER.asString(), HttpConfiguration.SERVER_VERSION);
- if (configuration.getSendXPoweredBy())
- headers.add(HttpHeader.X_POWERED_BY.asString(), HttpConfiguration.SERVER_VERSION);
-
- ReplyInfo reply = new ReplyInfo(headers, close);
- if (LOG.isDebugEnabled())
- LOG.debug("Sending reply: {} on stream: {}", reply, stream);
- reply(stream, reply, callback);
- }
-
- @Override
- public void completed()
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Completed {}", this);
- }
-
- private void reply(Stream stream, ReplyInfo replyInfo, Callback callback)
- {
- if (!stream.isUnidirectional())
- stream.reply(replyInfo, callback);
- else
- stream.headers(new HeadersInfo(replyInfo.getHeaders(), replyInfo.isClose()), callback);
-
- Fields responseHeaders = replyInfo.getHeaders();
- if (responseHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().startsWith("200") && !stream.isClosed())
- {
- Set<String> pushResources = pushStrategy.apply(stream, requestHeaders, responseHeaders);
- if (pushResources.size() > 0)
- {
- PushResourceCoordinator pushResourceCoordinator = new PushResourceCoordinator(pushResources);
- pushResourceCoordinator.coordinate();
- }
- }
- }
-
- private static class PushHttpTransportOverSPDY extends HttpTransportOverSPDY
- {
- private final PushResourceCoordinator coordinator;
- private final short version;
-
- private PushHttpTransportOverSPDY(Connector connector, HttpConfiguration configuration, EndPoint endPoint,
- PushStrategy pushStrategy, Stream stream, Fields requestHeaders,
- PushResourceCoordinator coordinator, short version)
- {
- super(connector, configuration, endPoint, pushStrategy, stream, requestHeaders);
- this.coordinator = coordinator;
- this.version = version;
- }
-
- @Override
- public void completed()
- {
- Stream stream = getStream();
- if (LOG.isDebugEnabled())
- LOG.debug("Resource pushed for {} on {}",
- getRequestHeaders().get(HTTPSPDYHeader.URI.name(version)), stream);
- coordinator.complete();
- }
- }
-
- private class PushResourceCoordinator
- {
- private final Queue<PushResource> queue = new ConcurrentArrayQueue<>();
- private final Set<String> resources;
- private AtomicBoolean active = new AtomicBoolean(false);
-
- private PushResourceCoordinator(Set<String> resources)
- {
- this.resources = resources;
- }
-
- private void coordinate()
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Pushing resources: {}", resources);
- // Must send all push frames to the client at once before we
- // return from this method and send the main resource data
- for (String pushResource : resources)
- pushResource(pushResource);
- }
-
- private void sendNextResourceData()
- {
- if (LOG.isDebugEnabled())
- LOG.debug("{} sendNextResourceData active: {}", hashCode(), active.get());
- if (active.compareAndSet(false, true))
- {
- PushResource resource = queue.poll();
- if (resource != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Opening new push channel for: {}", resource);
- HttpChannelOverSPDY pushChannel = newHttpChannelOverSPDY(resource.getPushStream(), resource.getPushRequestHeaders());
- pushChannel.requestStart(resource.getPushRequestHeaders(), true);
- return;
- }
-
- if (active.compareAndSet(true, false))
- {
- if (queue.peek() != null)
- sendNextResourceData();
- }
- else
- {
- throw new IllegalStateException("active must not be false here! Concurrency bug!");
- }
- }
- }
-
- private HttpChannelOverSPDY newHttpChannelOverSPDY(Stream pushStream, Fields pushRequestHeaders)
- {
- HttpTransport transport = new PushHttpTransportOverSPDY(connector, configuration, endPoint, pushStrategy,
- pushStream, pushRequestHeaders, this, version);
- HttpInputOverSPDY input = new HttpInputOverSPDY();
- return new HttpChannelOverSPDY(connector, configuration, endPoint, transport, input, pushStream);
- }
-
- private void pushResource(String pushResource)
- {
- Fields.Field scheme = requestHeaders.get(HTTPSPDYHeader.SCHEME.name(version));
- Fields.Field host = requestHeaders.get(HTTPSPDYHeader.HOST.name(version));
- Fields.Field uri = requestHeaders.get(HTTPSPDYHeader.URI.name(version));
- final Fields pushHeaders = createPushHeaders(scheme, host, pushResource);
- final Fields pushRequestHeaders = createRequestHeaders(scheme, host, uri, pushResource);
-
- stream.push(new PushInfo(pushHeaders, false), new Promise<Stream>()
- {
- @Override
- public void succeeded(Stream pushStream)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Headers pushed for {} on {}", pushHeaders.get(HTTPSPDYHeader.URI.name(version)), pushStream);
- queue.offer(new PushResource(pushStream, pushRequestHeaders));
- sendNextResourceData();
- }
-
- @Override
- public void failed(Throwable x)
- {
- LOG.debug("Creating push stream failed.", x);
- sendNextResourceData();
- }
- });
- }
-
- private void complete()
- {
- if (!active.compareAndSet(true, false))
- throw new IllegalStateException();
- sendNextResourceData();
- }
-
- private Fields createRequestHeaders(Fields.Field scheme, Fields.Field host, Fields.Field uri, String pushResourcePath)
- {
- final Fields newRequestHeaders = new Fields(requestHeaders, false);
- newRequestHeaders.put(HTTPSPDYHeader.METHOD.name(version), "GET");
- newRequestHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- newRequestHeaders.put(scheme);
- newRequestHeaders.put(host);
- newRequestHeaders.put(HTTPSPDYHeader.URI.name(version), pushResourcePath);
- String referrer = scheme.getValue() + "://" + host.getValue() + uri.getValue();
- newRequestHeaders.put("referer", referrer);
- newRequestHeaders.put("x-spdy-push", "true");
- return newRequestHeaders;
- }
-
- private Fields createPushHeaders(Fields.Field scheme, Fields.Field host, String pushResourcePath)
- {
- final Fields pushHeaders = new Fields();
- if (version == SPDY.V2)
- pushHeaders.put(HTTPSPDYHeader.URI.name(version), scheme.getValue() + "://" + host.getValue() + pushResourcePath);
- else
- {
- pushHeaders.put(HTTPSPDYHeader.URI.name(version), pushResourcePath);
- pushHeaders.put(scheme);
- pushHeaders.put(host);
- }
- return pushHeaders;
- }
- }
-
- private static class PushResource
- {
- private final Stream pushStream;
- private final Fields pushRequestHeaders;
-
- public PushResource(Stream pushStream, Fields pushRequestHeaders)
- {
- this.pushStream = pushStream;
- this.pushRequestHeaders = pushRequestHeaders;
- }
-
- public Stream getPushStream()
- {
- return pushStream;
- }
-
- public Fields getPushRequestHeaders()
- {
- return pushRequestHeaders;
- }
-
- @Override
- public String toString()
- {
- return "PushResource{" +
- "pushStream=" + pushStream +
- ", pushRequestHeaders=" + pushRequestHeaders +
- '}';
- }
- }
-
- @Override
- public void abort()
- {
- // TODO close the stream in a way to indicate an incomplete response?
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/PushStrategy.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/PushStrategy.java
deleted file mode 100644
index 2c553c95eb..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/PushStrategy.java
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.util.Collections;
-import java.util.Set;
-
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.util.Fields;
-
-/**
- * <p>{@link PushStrategy} encapsulates the decisions about performing
- * SPDY pushes of secondary resources associated with a primary resource.</p>
- */
-public interface PushStrategy
-{
- /**
- * <p>Applies the SPDY push logic for the primary resource.</p>
- *
- * @param stream the primary resource stream
- * @param requestHeaders the primary resource request headers
- * @param responseHeaders the primary resource response headers
- * @return a list of secondary resource URIs to push
- */
- public Set<String> apply(Stream stream, Fields requestHeaders, Fields responseHeaders);
-
- /**
- * An implementation that returns an empty list of secondary resources
- */
- public static class None implements PushStrategy
- {
- @Override
- public Set<String> apply(Stream stream, Fields requestHeaders, Fields responseHeaders)
- {
- return Collections.emptySet();
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategy.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategy.java
deleted file mode 100644
index f2beb38d4c..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategy.java
+++ /dev/null
@@ -1,342 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.regex.Pattern;
-
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-/**
- * <p>A SPDY push strategy that auto-populates push metadata based on referrer URLs.<p>A typical request for a main
- * resource such as {@code index.html} is immediately followed by a number of requests for associated resources.
- * Associated resource requests will have a {@code Referer} HTTP header that points to {@code index.html}, which is used
- * to link the associated resource to the main resource.<p>However, also following a hyperlink generates a HTTP request
- * with a {@code Referer} HTTP header that points to {@code index.html}; therefore a proper value for {@link
- * #setReferrerPushPeriod(int)} has to be set. If the referrerPushPeriod for a main resource has elapsed, no more
- * associated resources will be added for that main resource.<p>This class distinguishes associated main resources by
- * their URL path suffix and content type. CSS stylesheets, images and JavaScript files have recognizable URL path
- * suffixes that are classified as associated resources. The suffix regexs can be configured by constructor argument</p>
- * <p>When CSS stylesheets refer to images, the CSS image request will have the CSS stylesheet as referrer. This
- * implementation will push also the CSS image.<p>The push metadata built by this implementation is limited by the
- * number of pages of the application itself, and by the {@link #setMaxAssociatedResources(int)} max associated
- * resources} parameter. This parameter limits the number of associated resources per each main resource, so that if a
- * main resource has hundreds of associated resources, only up to the number specified by this parameter will be
- * pushed.
- */
-public class ReferrerPushStrategy implements PushStrategy
-{
- private static final Logger LOG = Log.getLogger(ReferrerPushStrategy.class);
- private final ConcurrentMap<String, MainResource> mainResources = new ConcurrentHashMap<>();
- private final Set<Pattern> pushRegexps = new HashSet<>();
- private final Set<String> pushContentTypes = new HashSet<>();
- private final Set<Pattern> allowedPushOrigins = new HashSet<>();
- private final Set<Pattern> userAgentBlacklist = new HashSet<>();
- private volatile int maxAssociatedResources = 32;
- private volatile int referrerPushPeriod = 5000;
-
- public ReferrerPushStrategy()
- {
- List<String> defaultPushRegexps = Arrays.asList(".*\\.css", ".*\\.js", ".*\\.png", ".*\\.jpeg", ".*\\.jpg",
- ".*\\.gif", ".*\\.ico");
- addPushRegexps(defaultPushRegexps);
-
- List<String> defaultPushContentTypes = Arrays.asList(
- "text/css",
- "text/javascript", "application/javascript", "application/x-javascript",
- "image/png", "image/x-png",
- "image/jpeg",
- "image/gif",
- "image/x-icon", "image/vnd.microsoft.icon");
- this.pushContentTypes.addAll(defaultPushContentTypes);
- }
-
- public void setPushRegexps(List<String> pushRegexps)
- {
- pushRegexps.clear();
- addPushRegexps(pushRegexps);
- }
-
- private void addPushRegexps(List<String> pushRegexps)
- {
- for (String pushRegexp : pushRegexps)
- this.pushRegexps.add(Pattern.compile(pushRegexp));
- }
-
- public void setPushContentTypes(List<String> pushContentTypes)
- {
- pushContentTypes.clear();
- pushContentTypes.addAll(pushContentTypes);
- }
-
- public void setAllowedPushOrigins(List<String> allowedPushOrigins)
- {
- allowedPushOrigins.clear();
- for (String allowedPushOrigin : allowedPushOrigins)
- this.allowedPushOrigins.add(Pattern.compile(allowedPushOrigin.replace(".", "\\.").replace("*", ".*")));
- }
-
- public void setUserAgentBlacklist(List<String> userAgentPatterns)
- {
- userAgentBlacklist.clear();
- for (String userAgentPattern : userAgentPatterns)
- userAgentBlacklist.add(Pattern.compile(userAgentPattern));
- }
-
- public void setMaxAssociatedResources(int maxAssociatedResources)
- {
- this.maxAssociatedResources = maxAssociatedResources;
- }
-
- public void setReferrerPushPeriod(int referrerPushPeriod)
- {
- this.referrerPushPeriod = referrerPushPeriod;
- }
-
- public Set<Pattern> getPushRegexps()
- {
- return pushRegexps;
- }
-
- public Set<String> getPushContentTypes()
- {
- return pushContentTypes;
- }
-
- public Set<Pattern> getAllowedPushOrigins()
- {
- return allowedPushOrigins;
- }
-
- public Set<Pattern> getUserAgentBlacklist()
- {
- return userAgentBlacklist;
- }
-
- public int getMaxAssociatedResources()
- {
- return maxAssociatedResources;
- }
-
- public int getReferrerPushPeriod()
- {
- return referrerPushPeriod;
- }
-
- @Override
- public Set<String> apply(Stream stream, Fields requestHeaders, Fields responseHeaders)
- {
- Set<String> result = Collections.<String>emptySet();
- short version = stream.getSession().getVersion();
- if (!isIfModifiedSinceHeaderPresent(requestHeaders) && isValidMethod(requestHeaders.get(HTTPSPDYHeader.METHOD
- .name(version)).getValue()) && !isUserAgentBlacklisted(requestHeaders))
- {
- String scheme = requestHeaders.get(HTTPSPDYHeader.SCHEME.name(version)).getValue();
- String host = requestHeaders.get(HTTPSPDYHeader.HOST.name(version)).getValue();
- String origin = scheme + "://" + host;
- String url = requestHeaders.get(HTTPSPDYHeader.URI.name(version)).getValue();
- String absoluteURL = origin + url;
- if (LOG.isDebugEnabled())
- LOG.debug("Applying push strategy for {}", absoluteURL);
- if (isMainResource(url, responseHeaders))
- {
- MainResource mainResource = getOrCreateMainResource(absoluteURL);
- result = mainResource.getResources();
- }
- else if (isPushResource(url, responseHeaders))
- {
- Fields.Field referrerHeader = requestHeaders.get("referer");
- if (referrerHeader != null)
- {
- String referrer = referrerHeader.getValue();
- MainResource mainResource = mainResources.get(referrer);
- if (mainResource == null)
- mainResource = getOrCreateMainResource(referrer);
-
- Set<String> pushResources = mainResource.getResources();
- if (!pushResources.contains(url))
- mainResource.addResource(url, origin, referrer);
- else
- result = getPushResources(absoluteURL);
- }
- }
- if (LOG.isDebugEnabled())
- LOG.debug("Pushing {} resources for {}: {}", result.size(), absoluteURL, result);
- }
- return result;
- }
-
- private Set<String> getPushResources(String absoluteURL)
- {
- Set<String> result = Collections.emptySet();
- if (mainResources.get(absoluteURL) != null)
- result = mainResources.get(absoluteURL).getResources();
- return result;
- }
-
- private MainResource getOrCreateMainResource(String absoluteURL)
- {
- MainResource mainResource = mainResources.get(absoluteURL);
- if (mainResource == null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Creating new main resource for {}", absoluteURL);
- MainResource value = new MainResource(absoluteURL);
- mainResource = mainResources.putIfAbsent(absoluteURL, value);
- if (mainResource == null)
- mainResource = value;
- }
- return mainResource;
- }
-
- private boolean isIfModifiedSinceHeaderPresent(Fields headers)
- {
- return headers.get("if-modified-since") != null;
- }
-
- private boolean isValidMethod(String method)
- {
- return "GET".equalsIgnoreCase(method);
- }
-
- private boolean isMainResource(String url, Fields responseHeaders)
- {
- return !isPushResource(url, responseHeaders);
- }
-
- public boolean isUserAgentBlacklisted(Fields headers)
- {
- Fields.Field userAgentHeader = headers.get("user-agent");
- if (userAgentHeader != null)
- for (Pattern userAgentPattern : userAgentBlacklist)
- if (userAgentPattern.matcher(userAgentHeader.getValue()).matches())
- return true;
- return false;
- }
-
- private boolean isPushResource(String url, Fields responseHeaders)
- {
- for (Pattern pushRegexp : pushRegexps)
- {
- if (pushRegexp.matcher(url).matches())
- {
- Fields.Field header = responseHeaders.get("content-type");
- if (header == null)
- return true;
-
- String contentType = header.getValue().toLowerCase(Locale.ENGLISH);
- for (String pushContentType : pushContentTypes)
- if (contentType.startsWith(pushContentType))
- return true;
- }
- }
- return false;
- }
-
- private class MainResource
- {
- private final String name;
- private final CopyOnWriteArraySet<String> resources = new CopyOnWriteArraySet<>();
- private final AtomicLong firstResourceAdded = new AtomicLong(-1);
-
- private MainResource(String name)
- {
- this.name = name;
- }
-
- public boolean addResource(String url, String origin, String referrer)
- {
- // We start the push period here and not when initializing the main resource, because a browser with a
- // prefilled cache won't request the subresources. If the browser with warmed up cache now hits the main
- // resource after a server restart, the push period shouldn't start until the first subresource is
- // being requested.
- firstResourceAdded.compareAndSet(-1, System.nanoTime());
-
- long delay = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - firstResourceAdded.get());
- if (!referrer.startsWith(origin) && !isPushOriginAllowed(origin))
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Skipped store of push metadata {} for {}: Origin: {} doesn't match or origin not allowed",
- url, name, origin);
- return false;
- }
-
- // This check is not strictly concurrent-safe, but limiting
- // the number of associated resources is achieved anyway
- // although in rare cases few more resources will be stored
- if (resources.size() >= maxAssociatedResources)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Skipped store of push metadata {} for {}: max associated resources ({}) reached",
- url, name, maxAssociatedResources);
- return false;
- }
- if (delay > referrerPushPeriod)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Delay: {}ms longer than referrerPushPeriod ({}ms). Not adding resource: {} for: {}",
- delay, referrerPushPeriod, url, name);
- return false;
- }
-
- if (LOG.isDebugEnabled())
- LOG.debug("Adding: {} to: {} with delay: {}ms.", url, this, delay);
- resources.add(url);
- return true;
- }
-
- public Set<String> getResources()
- {
- return Collections.unmodifiableSet(resources);
- }
-
- public String toString()
- {
- return String.format("%s@%x{name=%s,resources=%s}",
- getClass().getSimpleName(),
- hashCode(),
- name,
- resources
- );
- }
-
- private boolean isPushOriginAllowed(String origin)
- {
- for (Pattern allowedPushOrigin : allowedPushOrigins)
- if (allowedPushOrigin.matcher(origin).matches())
- return true;
- return false;
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPProxyEngine.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPProxyEngine.java
deleted file mode 100644
index 5906f22ac7..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPProxyEngine.java
+++ /dev/null
@@ -1,276 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.client.util.DeferredContentProvider;
-import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.http.HttpVersion;
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.HttpCookieStore;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-/**
- * <p>{@link HTTPProxyEngine} implements a SPDY to HTTP proxy, that is, converts SPDY events received by clients into
- * HTTP events for the servers.</p>
- */
-public class HTTPProxyEngine extends ProxyEngine
-{
- private static final Logger LOG = Log.getLogger(HTTPProxyEngine.class);
- private static final Callback LOGGING_CALLBACK = new LoggingCallback();
-
- private final HttpClient httpClient;
-
- public HTTPProxyEngine(HttpClient httpClient)
- {
- this.httpClient = httpClient;
- configureHttpClient(httpClient);
- }
-
- private void configureHttpClient(HttpClient httpClient)
- {
- // Redirects must be proxied as is, not followed
- httpClient.setFollowRedirects(false);
- // Must not store cookies, otherwise cookies of different clients will mix
- httpClient.setCookieStore(new HttpCookieStore.Empty());
- }
-
- public StreamFrameListener proxy(final Stream clientStream, SynInfo clientSynInfo, ProxyEngineSelector.ProxyServerInfo proxyServerInfo)
- {
- short version = clientStream.getSession().getVersion();
- String method = clientSynInfo.getHeaders().get(HTTPSPDYHeader.METHOD.name(version)).getValue();
- String path = clientSynInfo.getHeaders().get(HTTPSPDYHeader.URI.name(version)).getValue();
-
- Fields headers = new Fields(clientSynInfo.getHeaders(), false);
-
- removeHopHeaders(headers);
- addRequestProxyHeaders(clientStream, headers);
- customizeRequestHeaders(clientStream, headers);
-
- String host = proxyServerInfo.getHost();
- int port = proxyServerInfo.getAddress().getPort();
-
- if (LOG.isDebugEnabled())
- LOG.debug("Sending HTTP request to: {}", host + ":" + port);
- final Request request = httpClient.newRequest(host, port)
- .path(path)
- .method(HttpMethod.fromString(method));
- addNonSpdyHeadersToRequest(version, headers, request);
-
- if (!clientSynInfo.isClose())
- {
- request.content(new DeferredContentProvider());
- }
-
- sendRequest(clientStream, request);
-
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- // We proxy to HTTP so we do not receive replies
- throw new UnsupportedOperationException("Not Yet Implemented");
- }
-
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- throw new UnsupportedOperationException("Not Yet Implemented");
- }
-
- @Override
- public void onData(Stream clientStream, final DataInfo clientDataInfo)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("received clientDataInfo: {} for stream: {}", clientDataInfo, clientStream);
-
- DeferredContentProvider contentProvider = (DeferredContentProvider)request.getContent();
- contentProvider.offer(clientDataInfo.asByteBuffer(true));
-
- if (clientDataInfo.isClose())
- contentProvider.close();
- }
- };
- }
-
- private void sendRequest(final Stream clientStream, Request request)
- {
- request.send(new Response.Listener.Adapter()
- {
- private volatile boolean committed;
-
- @Override
- public void onHeaders(final Response response)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("onHeaders called with response: {}. Sending replyInfo to client.", response);
- Fields responseHeaders = createResponseHeaders(clientStream, response);
- removeHopHeaders(responseHeaders);
- ReplyInfo replyInfo = new ReplyInfo(responseHeaders, false);
- clientStream.reply(replyInfo, new Callback.Adapter()
- {
- @Override
- public void failed(Throwable x)
- {
- LOG.debug("failed: ", x);
- response.abort(x);
- }
-
- @Override
- public void succeeded()
- {
- committed = true;
- }
- });
- }
-
- @Override
- public void onContent(final Response response, ByteBuffer content)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("onContent called with response: {} and content: {}. Sending response content to client.",
- response, content);
- final ByteBuffer contentCopy = httpClient.getByteBufferPool().acquire(content.remaining(), true);
- BufferUtil.flipPutFlip(content, contentCopy);
- ByteBufferDataInfo dataInfo = new ByteBufferDataInfo(contentCopy, false);
- clientStream.data(dataInfo, new Callback()
- {
- @Override
- public void failed(Throwable x)
- {
- LOG.debug("failed: ", x);
- releaseBuffer();
- response.abort(x);
- }
-
- @Override
- public void succeeded()
- {
- releaseBuffer();
- }
-
- private void releaseBuffer()
- {
- httpClient.getByteBufferPool().release(contentCopy);
- }
- });
- }
-
- @Override
- public void onSuccess(Response response)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("onSuccess called. Closing client stream.");
- clientStream.data(new ByteBufferDataInfo(BufferUtil.EMPTY_BUFFER, true), LOGGING_CALLBACK);
- }
-
- @Override
- public void onFailure(Response response, Throwable failure)
- {
- LOG.debug("onFailure called: ", failure);
- if (committed)
- {
- LOG.debug("clientStream already committed. Resetting stream.");
- try
- {
- clientStream.getSession().rst(new RstInfo(clientStream.getId(), StreamStatus.INTERNAL_ERROR));
- }
- catch (InterruptedException | ExecutionException | TimeoutException e)
- {
- LOG.debug(e);
- }
- }
- else
- {
- if (clientStream.isClosed())
- return;
- Fields responseHeaders = createResponseHeaders(clientStream, response);
- if (failure instanceof TimeoutException)
- responseHeaders.add(HTTPSPDYHeader.STATUS.name(clientStream.getSession().getVersion()),
- String.valueOf(HttpStatus.GATEWAY_TIMEOUT_504));
- else
- responseHeaders.add(HTTPSPDYHeader.STATUS.name(clientStream.getSession().getVersion()),
- String.valueOf(HttpStatus.BAD_GATEWAY_502));
- ReplyInfo replyInfo = new ReplyInfo(responseHeaders, true);
- clientStream.reply(replyInfo, LOGGING_CALLBACK);
- }
- }
- });
- }
-
- private Fields createResponseHeaders(Stream clientStream, Response response)
- {
- Fields responseHeaders = new Fields();
- for (HttpField header : response.getHeaders())
- responseHeaders.add(header.getName(), header.getValue());
- short version = clientStream.getSession().getVersion();
- if (response.getStatus() > 0)
- responseHeaders.add(HTTPSPDYHeader.STATUS.name(version),
- String.valueOf(response.getStatus()));
- responseHeaders.add(HTTPSPDYHeader.VERSION.name(version), HttpVersion.HTTP_1_1.asString());
- addResponseProxyHeaders(clientStream, responseHeaders);
- return responseHeaders;
- }
-
- private void addNonSpdyHeadersToRequest(short version, Fields headers, Request request)
- {
- for (Fields.Field header : headers)
- if (HTTPSPDYHeader.from(version, header.getName()) == null)
- request.header(header.getName(), header.getValue());
- }
-
- static class LoggingCallback extends Callback.Adapter
- {
- @Override
- public void failed(Throwable x)
- {
- LOG.debug(x);
- }
-
- @Override
- public void succeeded()
- {
- if (LOG.isDebugEnabled())
- LOG.debug("succeeded");
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPSPDYProxyServerConnector.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPSPDYProxyServerConnector.java
deleted file mode 100644
index c29b0e86d9..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPSPDYProxyServerConnector.java
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.util.Objects;
-
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.NegotiatingServerConnectionFactory;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
-import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-
-public class HTTPSPDYProxyServerConnector extends ServerConnector
-{
- public HTTPSPDYProxyServerConnector(Server server, ProxyEngineSelector proxyEngineSelector)
- {
- this(server, new HttpConfiguration(), proxyEngineSelector);
- }
-
- public HTTPSPDYProxyServerConnector(Server server, HttpConfiguration config, ProxyEngineSelector proxyEngineSelector)
- {
- super(server, (SslContextFactory)null, new ProxyHTTPConnectionFactory(config, SPDY.V2, proxyEngineSelector));
- }
-
- public HTTPSPDYProxyServerConnector(Server server, SslContextFactory sslContextFactory, ProxyEngineSelector proxyEngineSelector)
- {
- this(server, sslContextFactory, new HttpConfiguration(), proxyEngineSelector);
- }
-
- public HTTPSPDYProxyServerConnector(Server server, SslContextFactory sslContextFactory, HttpConfiguration config, ProxyEngineSelector proxyEngineSelector)
- {
- this(server, sslContextFactory, config, proxyEngineSelector, new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"));
- }
-
- public HTTPSPDYProxyServerConnector(Server server, SslContextFactory sslContextFactory, HttpConfiguration config, ProxyEngineSelector proxyEngineSelector, NegotiatingServerConnectionFactory negotiatingFactory)
- {
- super(server, Objects.requireNonNull(sslContextFactory), negotiatingFactory,
- new SPDYServerConnectionFactory(SPDY.V3, proxyEngineSelector),
- new SPDYServerConnectionFactory(SPDY.V2, proxyEngineSelector),
- new ProxyHTTPConnectionFactory(config, SPDY.V2, proxyEngineSelector));
- negotiatingFactory.setDefaultProtocol("http/1.1");
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyEngine.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyEngine.java
deleted file mode 100644
index ffa968f4f9..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyEngine.java
+++ /dev/null
@@ -1,129 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Fields;
-
-/**
- * <p>{@link ProxyEngine} is the class for SPDY proxy functionalities that receives a SPDY request and converts it to
- * any protocol to its server side.</p>
- * <p>This class listens for SPDY events sent by clients; subclasses are responsible for translating
- * these SPDY client events into appropriate events to forward to the server, in the appropriate
- * protocol that is understood by the server.</p>
- */
-public abstract class ProxyEngine
-{
- private static final Set<String> HOP_HEADERS = new HashSet<>();
- static
- {
- HOP_HEADERS.add("proxy-connection");
- HOP_HEADERS.add("connection");
- HOP_HEADERS.add("keep-alive");
- HOP_HEADERS.add("transfer-encoding");
- HOP_HEADERS.add("te");
- HOP_HEADERS.add("trailer");
- HOP_HEADERS.add("proxy-authorization");
- HOP_HEADERS.add("proxy-authenticate");
- HOP_HEADERS.add("upgrade");
- }
-
- private final String name;
-
- protected ProxyEngine()
- {
- this(name());
- }
-
- private static String name()
- {
- try
- {
- return InetAddress.getLocalHost().getHostName();
- }
- catch (UnknownHostException x)
- {
- return "localhost";
- }
- }
-
- public abstract StreamFrameListener proxy(Stream clientStream, SynInfo clientSynInfo, ProxyEngineSelector.ProxyServerInfo proxyServerInfo);
-
- protected ProxyEngine(String name)
- {
- this.name = name;
- }
-
- public String getName()
- {
- return name;
- }
-
- protected void removeHopHeaders(Fields headers)
- {
- // Header names are case-insensitive (RFC2616) and oej.util.Fields.add converts the names to lowercase. So we
- // need to compare with the lowercase values only
- for (String hopHeader : HOP_HEADERS)
- headers.remove(hopHeader);
- }
-
- protected void addRequestProxyHeaders(Stream stream, Fields headers)
- {
- addViaHeader(headers);
- Fields.Field schemeField = headers.get(HTTPSPDYHeader.SCHEME.name(stream.getSession().getVersion()));
- if(schemeField != null)
- headers.add("X-Forwarded-Proto", schemeField.getValue());
- InetSocketAddress address = stream.getSession().getRemoteAddress();
- if (address != null)
- {
- headers.add("X-Forwarded-Host", address.getHostName());
- headers.add("X-Forwarded-For", address.toString());
- }
- headers.add("X-Forwarded-Server", name());
- }
-
- protected void addResponseProxyHeaders(Stream stream, Fields headers)
- {
- addViaHeader(headers);
- }
-
- private void addViaHeader(Fields headers)
- {
- headers.add("Via", "http/1.1 " + getName());
- }
-
- protected void customizeRequestHeaders(Stream stream, Fields headers)
- {
- }
-
- protected void customizeResponseHeaders(Stream stream, Fields headers)
- {
- }
-
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyEngineSelector.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyEngineSelector.java
deleted file mode 100644
index 176122a975..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyEngineSelector.java
+++ /dev/null
@@ -1,203 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.net.InetSocketAddress;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.PingResultInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-/**
- * <p>{@link ProxyEngineSelector} is the main entry point for push stream events of a jetty SPDY proxy. It receives the
- * push stream frames from the clients, checks if there's an appropriate {@link ProxyServerInfo} for the given target
- * host and forwards the push to a {@link ProxyEngine} for the protocol defined in {@link ProxyServerInfo}.</p>
- *
- * <p>If no {@link ProxyServerInfo} can be found for the given target host or no {@link ProxyEngine} can be found for
- * the given protocol, it resets the client stream.</p>
- *
- * <p>This class also provides configuration for the proxy rules.</p>
- */
-public class ProxyEngineSelector extends ServerSessionFrameListener.Adapter
-{
- protected final Logger LOG = Log.getLogger(getClass());
- private final Map<String, ProxyServerInfo> proxyInfos = new ConcurrentHashMap<>();
- private final Map<String, ProxyEngine> proxyEngines = new ConcurrentHashMap<>();
-
- @Override
- public final StreamFrameListener onSyn(final Stream clientStream, SynInfo clientSynInfo)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("C -> P {} on {}", clientSynInfo, clientStream);
-
- final Session clientSession = clientStream.getSession();
- short clientVersion = clientSession.getVersion();
- Fields headers = new Fields(clientSynInfo.getHeaders(), false);
-
- Fields.Field hostHeader = headers.get(HTTPSPDYHeader.HOST.name(clientVersion));
- if (hostHeader == null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("No host header found: " + headers);
- rst(clientStream);
- return null;
- }
-
- String host = hostHeader.getValue();
- int colon = host.indexOf(':');
- if (colon >= 0)
- host = host.substring(0, colon);
-
- ProxyServerInfo proxyServerInfo = getProxyServerInfo(host);
- if (proxyServerInfo == null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("No matching ProxyServerInfo found for: " + host);
- rst(clientStream);
- return null;
- }
-
- String protocol = proxyServerInfo.getProtocol();
- ProxyEngine proxyEngine = proxyEngines.get(protocol);
- if (proxyEngine == null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("No matching ProxyEngine found for: " + protocol);
- rst(clientStream);
- return null;
- }
- if (LOG.isDebugEnabled())
- LOG.debug("Forwarding request: {} -> {}", clientSynInfo, proxyServerInfo);
- return proxyEngine.proxy(clientStream, clientSynInfo, proxyServerInfo);
- }
-
- @Override
- public void onPing(Session clientSession, PingResultInfo pingResultInfo)
- {
- // We do not know to which upstream server
- // to send the PING so we just ignore it
- }
-
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayResultInfo)
- {
- // TODO:
- }
-
- public Map<String, ProxyEngine> getProxyEngines()
- {
- return new HashMap<>(proxyEngines);
- }
-
- public void setProxyEngines(Map<String, ProxyEngine> proxyEngines)
- {
- this.proxyEngines.clear();
- this.proxyEngines.putAll(proxyEngines);
- }
-
- public ProxyEngine getProxyEngine(String protocol)
- {
- return proxyEngines.get(protocol);
- }
-
- public void putProxyEngine(String protocol, ProxyEngine proxyEngine)
- {
- proxyEngines.put(protocol, proxyEngine);
- }
-
- public Map<String, ProxyServerInfo> getProxyServerInfos()
- {
- return new HashMap<>(proxyInfos);
- }
-
- protected ProxyServerInfo getProxyServerInfo(String host)
- {
- return proxyInfos.get(host);
- }
-
- public void setProxyServerInfos(Map<String, ProxyServerInfo> proxyServerInfos)
- {
- this.proxyInfos.clear();
- this.proxyInfos.putAll(proxyServerInfos);
- }
-
- public void putProxyServerInfo(String host, ProxyServerInfo proxyServerInfo)
- {
- proxyInfos.put(host, proxyServerInfo);
- }
-
- private void rst(Stream stream)
- {
- RstInfo rstInfo = new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM);
- stream.getSession().rst(rstInfo, Callback.Adapter.INSTANCE);
- }
-
- public static class ProxyServerInfo
- {
- private final String protocol;
- private final String host;
- private final InetSocketAddress address;
-
- public ProxyServerInfo(String protocol, String host, int port)
- {
- this.protocol = protocol;
- this.host = host;
- this.address = new InetSocketAddress(host, port);
- }
-
- public String getProtocol()
- {
- return protocol;
- }
-
- public String getHost()
- {
- return host;
- }
-
- public InetSocketAddress getAddress()
- {
- return address;
- }
-
- @Override
- public String toString()
- {
- return "ProxyServerInfo{" +
- "protocol='" + protocol + '\'' +
- ", host='" + host + '\'' +
- ", address=" + address +
- '}';
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPConnectionFactory.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPConnectionFactory.java
deleted file mode 100644
index e64b1d905b..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPConnectionFactory.java
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-
-import org.eclipse.jetty.http.HttpVersion;
-import org.eclipse.jetty.io.Connection;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.AbstractConnectionFactory;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
-
-public class ProxyHTTPConnectionFactory extends AbstractConnectionFactory implements HttpConfiguration.ConnectionFactory
-{
- private final short version;
- private final ProxyEngineSelector proxyEngineSelector;
- private final HttpConfiguration httpConfiguration;
-
- public ProxyHTTPConnectionFactory(HttpConfiguration httpConfiguration,short version, ProxyEngineSelector proxyEngineSelector)
- {
- // replaces http/1.1
- super(HttpVersion.HTTP_1_1.asString());
- this.version = version;
- this.proxyEngineSelector = proxyEngineSelector;
- this.httpConfiguration=httpConfiguration;
- }
-
- @Override
- public Connection newConnection(Connector connector, EndPoint endPoint)
- {
- return configure(new ProxyHTTPSPDYConnection(connector, httpConfiguration, endPoint, version, proxyEngineSelector),connector,endPoint);
- }
-
- @Override
- public HttpConfiguration getHttpConfiguration()
- {
- return httpConfiguration;
- }
-
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPSPDYConnection.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPSPDYConnection.java
deleted file mode 100644
index 040068c0e9..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPSPDYConnection.java
+++ /dev/null
@@ -1,385 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.nio.ByteBuffer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpGenerator;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpHeaderValue;
-import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.http.HttpParser;
-import org.eclipse.jetty.http.HttpVersion;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpConnection;
-import org.eclipse.jetty.server.SslConnectionFactory;
-import org.eclipse.jetty.spdy.ISession;
-import org.eclipse.jetty.spdy.IStream;
-import org.eclipse.jetty.spdy.StandardSession;
-import org.eclipse.jetty.spdy.StandardStream;
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-
-public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParser.RequestHandler<ByteBuffer>
-{
- private final short version;
- private final Fields headers = new Fields();
- private final ProxyEngineSelector proxyEngineSelector;
- private final ISession session;
- private HTTPStream stream;
- private ByteBuffer content;
-
- public ProxyHTTPSPDYConnection(Connector connector, HttpConfiguration config, EndPoint endPoint, short version, ProxyEngineSelector proxyEngineSelector)
- {
- super(config, connector, endPoint);
- this.version = version;
- this.proxyEngineSelector = proxyEngineSelector;
- this.session = new HTTPSession(version, connector);
- }
-
- @Override
- protected HttpParser.RequestHandler<ByteBuffer> newRequestHandler()
- {
- return this;
- }
-
- @Override
- public boolean startRequest(HttpMethod method, String methodString, ByteBuffer uri, HttpVersion httpVersion)
- {
- Connector connector = getConnector();
- String scheme = connector.getConnectionFactory(SslConnectionFactory.class) != null ? "https" : "http";
- headers.put(HTTPSPDYHeader.SCHEME.name(version), scheme);
- headers.put(HTTPSPDYHeader.METHOD.name(version), methodString);
- headers.put(HTTPSPDYHeader.URI.name(version), BufferUtil.toUTF8String(uri)); // TODO handle bad encodings
- headers.put(HTTPSPDYHeader.VERSION.name(version), httpVersion.asString());
- return false;
- }
-
- @Override
- public boolean parsedHeader(HttpField field)
- {
- if (field.getHeader() == HttpHeader.HOST)
- headers.put(HTTPSPDYHeader.HOST.name(version), field.getValue());
- else
- headers.put(field.getName(), field.getValue());
- return false;
- }
-
- @Override
- public boolean parsedHostHeader(String host, int port)
- {
- return false;
- }
-
- @Override
- public boolean headerComplete()
- {
- return false;
- }
-
- @Override
- public boolean content(ByteBuffer item)
- {
- if (content == null)
- {
- stream = syn(false);
- content = item;
- }
- else
- {
- stream.getStreamFrameListener().onData(stream, toDataInfo(item, false));
- }
- return false;
- }
-
- @Override
- public boolean messageComplete()
- {
- if (stream == null)
- {
- assert content == null;
- if (headers.isEmpty())
- proxyEngineSelector.onGoAway(session, new GoAwayResultInfo(0, SessionStatus.OK));
- else
- syn(true);
- }
- else
- {
- stream.getStreamFrameListener().onData(stream, toDataInfo(content, true));
- }
- return false;
- }
-
- @Override
- public void completed()
- {
- headers.clear();
- stream = null;
- content = null;
- super.completed();
- }
-
- @Override
- public int getHeaderCacheSize()
- {
- // TODO get from configuration
- return 256;
- }
-
- @Override
- public void earlyEOF()
- {
- // TODO
- }
-
- @Override
- public void badMessage(int status, String reason)
- {
- // TODO
- }
-
- private HTTPStream syn(boolean close)
- {
- HTTPStream stream = new HTTPStream(1, (byte)0, session, null);
- StreamFrameListener streamFrameListener = proxyEngineSelector.onSyn(stream, new SynInfo(headers, close));
- stream.setStreamFrameListener(streamFrameListener);
- return stream;
- }
-
- private DataInfo toDataInfo(ByteBuffer buffer, boolean close)
- {
- return new ByteBufferDataInfo(buffer, close);
- }
-
- private class HTTPSession extends StandardSession
- {
- private HTTPSession(short version, Connector connector)
- {
- super(version, connector.getByteBufferPool(), connector.getScheduler(), null,
- getEndPoint(), null, 1, proxyEngineSelector, null, null);
- }
-
- @Override
- public void rst(RstInfo rstInfo, Callback handler)
- {
- HttpGenerator.ResponseInfo info = new HttpGenerator.ResponseInfo(HttpVersion.fromString(headers.get
- ("version").getValue()), null, 0, 502, "SPDY reset received from upstream server", false);
- send(info, null, true, Callback.Adapter.INSTANCE);
- }
-
- @Override
- public void goAway(GoAwayInfo goAwayInfo, Callback handler)
- {
- ProxyHTTPSPDYConnection.this.close();
- handler.succeeded();
- }
- }
-
- /**
- * <p>This stream will convert the SPDY invocations performed by the proxy into HTTP to be sent to the client.</p>
- */
- private class HTTPStream extends StandardStream
- {
- private final Pattern statusRegexp = Pattern.compile("(\\d{3})\\s+(.*)");
-
- private HTTPStream(int id, byte priority, ISession session, IStream associatedStream)
- {
- super(id, priority, session, associatedStream, getHttpChannel().getScheduler(), null);
- }
-
- @Override
- public void push(PushInfo pushInfo, Promise<Stream> handler)
- {
- // HTTP does not support pushed streams
- handler.succeeded(new HTTPPushStream(2, getPriority(), getSession(), this));
- }
-
- @Override
- public void headers(HeadersInfo headersInfo, Callback handler)
- {
- // TODO
- throw new UnsupportedOperationException("Not Yet Implemented");
- }
-
- @Override
- public void reply(ReplyInfo replyInfo, final Callback handler)
- {
- Fields headers = new Fields(replyInfo.getHeaders(), false);
-
- addPersistenceHeader(headers);
-
- headers.remove(HTTPSPDYHeader.SCHEME.name(version));
-
- String status = headers.remove(HTTPSPDYHeader.STATUS.name(version)).getValue();
- Matcher matcher = statusRegexp.matcher(status);
- matcher.matches();
- int code = Integer.parseInt(matcher.group(1));
- String reason = matcher.group(2).trim();
-
- HttpVersion httpVersion = HttpVersion.fromString(headers.remove(HTTPSPDYHeader.VERSION.name(version)).getValue());
-
- // Convert the Host header from a SPDY special header to a normal header
- Fields.Field host = headers.remove(HTTPSPDYHeader.HOST.name(version));
- if (host != null)
- headers.put("host", host.getValue());
-
- HttpFields fields = new HttpFields();
- for (Fields.Field header : headers)
- {
- String name = camelize(header.getName());
- fields.put(name, header.getValue());
- }
-
- // TODO: handle better the HEAD last parameter
- long contentLength = fields.getLongField(HttpHeader.CONTENT_LENGTH.asString());
- HttpGenerator.ResponseInfo info = new HttpGenerator.ResponseInfo(httpVersion, fields, contentLength, code,
- reason, false);
-
- send(info, null, replyInfo.isClose(), new Adapter()
- {
- @Override
- public void failed(Throwable x)
- {
- handler.failed(x);
- }
- });
-
- if (replyInfo.isClose())
- completed();
-
- handler.succeeded();
- }
-
- private String camelize(String name)
- {
- char[] chars = name.toCharArray();
- chars[0] = Character.toUpperCase(chars[0]);
-
- for (int i = 0; i < chars.length; ++i)
- {
- char c = chars[i];
- int j = i + 1;
- if (c == '-' && j < chars.length)
- chars[j] = Character.toUpperCase(chars[j]);
- }
- return new String(chars);
- }
-
- @Override
- public void data(DataInfo dataInfo, final Callback handler)
- {
- // Data buffer must be copied, as the ByteBuffer is pooled
- ByteBuffer byteBuffer = dataInfo.asByteBuffer(false);
-
- send(null, byteBuffer, dataInfo.isClose(), new Adapter()
- {
- @Override
- public void failed(Throwable x)
- {
- handler.failed(x);
- }
- });
-
- if (dataInfo.isClose())
- completed();
-
- handler.succeeded();
- }
- }
-
- private void addPersistenceHeader(Fields headersToAddTo)
- {
- HttpVersion httpVersion = HttpVersion.fromString(headers.get("version").getValue());
- boolean persistent = false;
- switch (httpVersion)
- {
- case HTTP_1_0:
- {
- Fields.Field keepAliveHeader = headers.get(HttpHeader.KEEP_ALIVE.asString());
- if(keepAliveHeader!=null)
- persistent = HttpHeaderValue.KEEP_ALIVE.asString().equals(keepAliveHeader.getValue());
- if (!persistent)
- persistent = HttpMethod.CONNECT.is(headers.get("method").getValue());
- if (persistent)
- headersToAddTo.add(HttpHeader.CONNECTION.asString(), HttpHeaderValue.KEEP_ALIVE.asString());
- break;
- }
- case HTTP_1_1:
- {
- Fields.Field connectionHeader = headers.get(HttpHeader.CONNECTION.asString());
- if(connectionHeader != null)
- persistent = !HttpHeaderValue.CLOSE.asString().equals(connectionHeader.getValue());
- else
- persistent = true;
- if (!persistent)
- persistent = HttpMethod.CONNECT.is(headers.get("method").getValue());
- if (!persistent)
- headersToAddTo.add(HttpHeader.CONNECTION.asString(), HttpHeaderValue.CLOSE.asString());
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
-
- private class HTTPPushStream extends StandardStream
- {
- private HTTPPushStream(int id, byte priority, ISession session, IStream associatedStream)
- {
- super(id, priority, session, associatedStream, getHttpChannel().getScheduler(), null);
- }
-
- @Override
- public void headers(HeadersInfo headersInfo, Callback handler)
- {
- // Ignore pushed headers
- handler.succeeded();
- }
-
- @Override
- public void data(DataInfo dataInfo, Callback handler)
- {
- // Ignore pushed data
- handler.succeeded();
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/SPDYProxyEngine.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/SPDYProxyEngine.java
deleted file mode 100644
index 349672abde..0000000000
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/SPDYProxyEngine.java
+++ /dev/null
@@ -1,631 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.net.InetSocketAddress;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.Info;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-/**
- * <p>{@link SPDYProxyEngine} implements a SPDY to SPDY proxy, that is, converts SPDY events received by clients into
- * SPDY events for the servers.</p>
- */
-public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
-{
- private static final Logger LOG = Log.getLogger(SPDYProxyEngine.class);
-
- private static final String STREAM_PROMISE_ATTRIBUTE = "org.eclipse.jetty.spdy.server.http.proxy.streamPromise";
- private static final String CLIENT_STREAM_ATTRIBUTE = "org.eclipse.jetty.spdy.server.http.proxy.clientStream";
-
- private final ConcurrentMap<String, Session> serverSessions = new ConcurrentHashMap<>();
- private final SessionFrameListener sessionListener = new ProxySessionFrameListener();
- private final SPDYClient.Factory factory;
- private volatile long connectTimeout = 15000;
- private volatile long timeout = 60000;
-
- public SPDYProxyEngine(SPDYClient.Factory factory)
- {
- this.factory = factory;
- }
-
- public long getConnectTimeout()
- {
- return connectTimeout;
- }
-
- public void setConnectTimeout(long connectTimeout)
- {
- this.connectTimeout = connectTimeout;
- }
-
- public long getTimeout()
- {
- return timeout;
- }
-
- public void setTimeout(long timeout)
- {
- this.timeout = timeout;
- }
-
- public StreamFrameListener proxy(final Stream clientStream, SynInfo clientSynInfo, ProxyEngineSelector.ProxyServerInfo proxyServerInfo)
- {
- Fields headers = new Fields(clientSynInfo.getHeaders(), false);
-
- short serverVersion = getVersion(proxyServerInfo.getProtocol());
- InetSocketAddress address = proxyServerInfo.getAddress();
- Session serverSession = produceSession(proxyServerInfo.getHost(), serverVersion, address);
- if (serverSession == null)
- {
- rst(clientStream);
- return null;
- }
-
- final Session clientSession = clientStream.getSession();
-
- addRequestProxyHeaders(clientStream, headers);
- customizeRequestHeaders(clientStream, headers);
- convert(clientSession.getVersion(), serverVersion, headers);
-
- SynInfo serverSynInfo = new SynInfo(headers, clientSynInfo.isClose());
- StreamFrameListener listener = new ProxyStreamFrameListener(clientStream);
- StreamPromise promise = new StreamPromise(clientStream, serverSynInfo);
- clientStream.setAttribute(STREAM_PROMISE_ATTRIBUTE, promise);
- serverSession.syn(serverSynInfo, listener, promise);
- return this;
- }
-
- private static short getVersion(String protocol)
- {
- switch (protocol)
- {
- case "spdy/2":
- return SPDY.V2;
- case "spdy/3":
- return SPDY.V3;
- default:
- throw new IllegalArgumentException("Procotol: " + protocol + " is not a known SPDY protocol");
- }
- }
-
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- throw new IllegalStateException("We shouldn't receive pushes from clients");
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- throw new IllegalStateException("Servers do not receive replies");
- }
-
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- // TODO
- throw new UnsupportedOperationException("Not Yet Implemented");
- }
-
- @Override
- public void onData(Stream clientStream, final DataInfo clientDataInfo)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("C -> P {} on {}", clientDataInfo, clientStream);
-
- ByteBufferDataInfo serverDataInfo = new ByteBufferDataInfo(clientDataInfo.asByteBuffer(false), clientDataInfo.isClose())
- {
- @Override
- public void consume(int delta)
- {
- super.consume(delta);
- clientDataInfo.consume(delta);
- }
- };
-
- StreamPromise streamPromise = (StreamPromise)clientStream.getAttribute(STREAM_PROMISE_ATTRIBUTE);
- streamPromise.data(serverDataInfo);
- }
-
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- LOG.debug(x);
- }
-
- private Session produceSession(String host, short version, InetSocketAddress address)
- {
- try
- {
- Session session = serverSessions.get(host);
- if (session == null)
- {
- SPDYClient client = factory.newSPDYClient(version);
- session = client.connect(address, sessionListener);
- if (LOG.isDebugEnabled())
- LOG.debug("Proxy session connected to {}", address);
- Session existing = serverSessions.putIfAbsent(host, session);
- if (existing != null)
- {
- session.goAway(new GoAwayInfo(), Callback.Adapter.INSTANCE);
- session = existing;
- }
- }
- return session;
- }
- catch (Exception x)
- {
- LOG.debug(x);
- return null;
- }
- }
-
- private void convert(short fromVersion, short toVersion, Fields headers)
- {
- if (fromVersion != toVersion)
- {
- for (HTTPSPDYHeader httpHeader : HTTPSPDYHeader.values())
- {
- Fields.Field header = headers.remove(httpHeader.name(fromVersion));
- if (header != null)
- {
- String toName = httpHeader.name(toVersion);
- for (String value : header.getValues())
- headers.add(toName, value);
- }
- }
- }
- }
-
- private void rst(Stream stream)
- {
- RstInfo rstInfo = new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM);
- stream.getSession().rst(rstInfo, Callback.Adapter.INSTANCE);
- }
-
- private class ProxyPushStreamFrameListener implements StreamFrameListener
- {
- private PushStreamPromise pushStreamPromise;
-
- private ProxyPushStreamFrameListener(PushStreamPromise pushStreamPromise)
- {
- this.pushStreamPromise = pushStreamPromise;
- }
-
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("S -> P pushed {} on {}. Opening new PushStream P -> C now.", pushInfo, stream);
- PushStreamPromise newPushStreamPromise = new PushStreamPromise(stream, pushInfo);
- this.pushStreamPromise.push(newPushStreamPromise);
- return new ProxyPushStreamFrameListener(newPushStreamPromise);
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- // Push streams never send a reply
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void onData(Stream serverStream, final DataInfo serverDataInfo)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("S -> P pushed {} on {}", serverDataInfo, serverStream);
-
- ByteBufferDataInfo clientDataInfo = new ByteBufferDataInfo(serverDataInfo.asByteBuffer(false), serverDataInfo.isClose())
- {
- @Override
- public void consume(int delta)
- {
- super.consume(delta);
- serverDataInfo.consume(delta);
- }
- };
-
- pushStreamPromise.data(clientDataInfo);
- }
-
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- LOG.debug(x);
- }
- }
-
- private class ProxyStreamFrameListener extends StreamFrameListener.Adapter
- {
- private final Stream receiverStream;
-
- public ProxyStreamFrameListener(Stream receiverStream)
- {
- this.receiverStream = receiverStream;
- }
-
- @Override
- public StreamFrameListener onPush(Stream senderStream, PushInfo pushInfo)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("S -> P {} on {}");
- PushInfo newPushInfo = convertPushInfo(pushInfo, senderStream, receiverStream);
- PushStreamPromise pushStreamPromise = new PushStreamPromise(senderStream, newPushInfo);
- receiverStream.push(newPushInfo, pushStreamPromise);
- return new ProxyPushStreamFrameListener(pushStreamPromise);
- }
-
- @Override
- public void onReply(final Stream stream, ReplyInfo replyInfo)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("S -> P {} on {}", replyInfo, stream);
- final ReplyInfo clientReplyInfo = new ReplyInfo(convertHeaders(stream, receiverStream, replyInfo.getHeaders()),
- replyInfo.isClose());
- reply(stream, clientReplyInfo);
- }
-
- private void reply(final Stream stream, final ReplyInfo clientReplyInfo)
- {
- receiverStream.reply(clientReplyInfo, new Callback()
- {
- @Override
- public void succeeded()
- {
- if (LOG.isDebugEnabled())
- LOG.debug("P -> C {} from {} to {}", clientReplyInfo, stream, receiverStream);
- }
-
- @Override
- public void failed(Throwable x)
- {
- LOG.debug(x);
- rst(receiverStream);
- }
- });
- }
-
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- // TODO
- throw new UnsupportedOperationException("Not Yet Implemented");
- }
-
- @Override
- public void onData(final Stream stream, final DataInfo dataInfo)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("S -> P {} on {}", dataInfo, stream);
- data(stream, dataInfo);
- }
-
- private void data(final Stream stream, final DataInfo serverDataInfo)
- {
- final ByteBufferDataInfo clientDataInfo = new ByteBufferDataInfo(serverDataInfo.asByteBuffer(false), serverDataInfo.isClose())
- {
- @Override
- public void consume(int delta)
- {
- super.consume(delta);
- serverDataInfo.consume(delta);
- }
- };
-
- receiverStream.data(clientDataInfo, new Callback() //TODO: timeout???
- {
- @Override
- public void succeeded()
- {
- if (LOG.isDebugEnabled())
- LOG.debug("P -> C {} from {} to {}", clientDataInfo, stream, receiverStream);
- }
-
- @Override
- public void failed(Throwable x)
- {
- LOG.debug(x);
- rst(receiverStream);
- }
- });
- }
- }
-
- /**
- * <p>{@link StreamPromise} implements the forwarding of DATA frames from the client to the server and vice
- * versa.</p> <p>Instances of this class buffer DATA frames sent by clients and send them to the server. The
- * buffering happens between the send of the SYN_STREAM to the server (where DATA frames may arrive from the client
- * before the SYN_STREAM has been fully sent), and between DATA frames, if the client is a fast producer and the
- * server a slow consumer, or if the client is a SPDY v2 client (and hence without flow control) while the server is
- * a SPDY v3 server (and hence with flow control).</p>
- */
- private class StreamPromise implements Promise<Stream>
- {
- private final Queue<DataInfoCallback> queue = new LinkedList<>();
- private final Stream senderStream;
- private final Info info;
- private Stream receiverStream;
-
- private StreamPromise(Stream senderStream, Info info)
- {
- this.senderStream = senderStream;
- this.info = info;
- }
-
- @Override
- public void succeeded(Stream stream)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("P -> S {} from {} to {}", info, senderStream, stream);
-
- stream.setAttribute(CLIENT_STREAM_ATTRIBUTE, senderStream);
-
- DataInfoCallback dataInfoCallback;
- synchronized (queue)
- {
- this.receiverStream = stream;
- dataInfoCallback = queue.peek();
- if (dataInfoCallback != null)
- {
- if (dataInfoCallback.flushing)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("SYN completed, flushing {}, queue size {}", dataInfoCallback.dataInfo, queue.size());
- dataInfoCallback = null;
- }
- else
- {
- dataInfoCallback.flushing = true;
- if (LOG.isDebugEnabled())
- LOG.debug("SYN completed, queue size {}", queue.size());
- }
- }
- else
- {
- if (LOG.isDebugEnabled())
- LOG.debug("SYN completed, queue empty");
- }
- }
- if (dataInfoCallback != null)
- flush(stream, dataInfoCallback);
- }
-
- @Override
- public void failed(Throwable x)
- {
- LOG.debug(x);
- rst(senderStream);
- }
-
- public void data(DataInfo dataInfo)
- {
- Stream receiverStream;
- DataInfoCallback dataInfoCallbackToFlush = null;
- DataInfoCallback dataInfoCallBackToQueue = new DataInfoCallback(dataInfo);
- synchronized (queue)
- {
- queue.offer(dataInfoCallBackToQueue);
- receiverStream = this.receiverStream;
- if (receiverStream != null)
- {
- dataInfoCallbackToFlush = queue.peek();
- if (dataInfoCallbackToFlush.flushing)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Queued {}, flushing {}, queue size {}", dataInfo, dataInfoCallbackToFlush.dataInfo, queue.size());
- receiverStream = null;
- }
- else
- {
- dataInfoCallbackToFlush.flushing = true;
- if (LOG.isDebugEnabled())
- LOG.debug("Queued {}, queue size {}", dataInfo, queue.size());
- }
- }
- else
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Queued {}, SYN incomplete, queue size {}", dataInfo, queue.size());
- }
- }
- if (receiverStream != null)
- flush(receiverStream, dataInfoCallbackToFlush);
- }
-
- private void flush(Stream receiverStream, DataInfoCallback dataInfoCallback)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("P -> S {} on {}", dataInfoCallback.dataInfo, receiverStream);
- receiverStream.data(dataInfoCallback.dataInfo, dataInfoCallback); //TODO: timeout???
- }
-
- private class DataInfoCallback implements Callback
- {
- private final DataInfo dataInfo;
- private boolean flushing;
-
- private DataInfoCallback(DataInfo dataInfo)
- {
- this.dataInfo = dataInfo;
- }
-
- @Override
- public void succeeded()
- {
- Stream serverStream;
- DataInfoCallback dataInfoCallback;
- synchronized (queue)
- {
- serverStream = StreamPromise.this.receiverStream;
- assert serverStream != null;
- dataInfoCallback = queue.poll();
- assert dataInfoCallback == this;
- dataInfoCallback = queue.peek();
- if (dataInfoCallback != null)
- {
- assert !dataInfoCallback.flushing;
- dataInfoCallback.flushing = true;
- if (LOG.isDebugEnabled())
- LOG.debug("Completed {}, queue size {}", dataInfo, queue.size());
- }
- else
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Completed {}, queue empty", dataInfo);
- }
- }
- if (dataInfoCallback != null)
- flush(serverStream, dataInfoCallback);
- }
-
- @Override
- public void failed(Throwable x)
- {
- LOG.debug(x);
- rst(senderStream);
- }
- }
-
- public Stream getSenderStream()
- {
- return senderStream;
- }
-
- public Info getInfo()
- {
- return info;
- }
-
- public Stream getReceiverStream()
- {
- synchronized (queue)
- {
- return receiverStream;
- }
- }
- }
-
- private class PushStreamPromise extends StreamPromise
- {
- private volatile PushStreamPromise pushStreamPromise;
-
- private PushStreamPromise(Stream senderStream, PushInfo pushInfo)
- {
- super(senderStream, pushInfo);
- }
-
- @Override
- public void succeeded(Stream receiverStream)
- {
- super.succeeded(receiverStream);
-
- if (LOG.isDebugEnabled())
- LOG.debug("P -> C PushStreamPromise.succeeded() called with pushStreamPromise: {}", pushStreamPromise);
-
- PushStreamPromise promise = pushStreamPromise;
- if (promise != null)
- receiverStream.push(convertPushInfo((PushInfo)getInfo(), getSenderStream(), receiverStream), pushStreamPromise);
- }
-
- public void push(PushStreamPromise pushStreamPromise)
- {
- Stream receiverStream = getReceiverStream();
-
- if (receiverStream != null)
- receiverStream.push(convertPushInfo((PushInfo)getInfo(), getSenderStream(), receiverStream), pushStreamPromise);
- else
- this.pushStreamPromise = pushStreamPromise;
- }
- }
-
- private class ProxySessionFrameListener extends SessionFrameListener.Adapter
- {
- @Override
- public void onRst(Session serverSession, RstInfo serverRstInfo)
- {
- Stream serverStream = serverSession.getStream(serverRstInfo.getStreamId());
- if (serverStream != null)
- {
- Stream clientStream = (Stream)serverStream.getAttribute(CLIENT_STREAM_ATTRIBUTE);
- if (clientStream != null)
- {
- Session clientSession = clientStream.getSession();
- RstInfo clientRstInfo = new RstInfo(clientStream.getId(), serverRstInfo.getStreamStatus());
- clientSession.rst(clientRstInfo, Callback.Adapter.INSTANCE);
- }
- }
- }
-
- @Override
- public void onGoAway(Session serverSession, GoAwayResultInfo goAwayResultInfo)
- {
- serverSessions.values().remove(serverSession);
- }
- }
-
- private PushInfo convertPushInfo(PushInfo pushInfo, Stream from, Stream to)
- {
- Fields headersToConvert = pushInfo.getHeaders();
- Fields headers = convertHeaders(from, to, headersToConvert);
- return new PushInfo(getTimeout(), TimeUnit.MILLISECONDS, headers, pushInfo.isClose());
- }
-
- private Fields convertHeaders(Stream from, Stream to, Fields headersToConvert)
- {
- Fields headers = new Fields(headersToConvert, false);
- addResponseProxyHeaders(from, headers);
- customizeResponseHeaders(from, headers);
- convert(from.getSession().getVersion(), to.getSession().getVersion(), headers);
- return headers;
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/AbstractHTTPSPDYTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/AbstractHTTPSPDYTest.java
deleted file mode 100644
index 200c8f01fe..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/AbstractHTTPSPDYTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.net.InetSocketAddress;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.concurrent.Executor;
-
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.StdErrLog;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.junit.After;
-import org.junit.Rule;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public abstract class AbstractHTTPSPDYTest
-{
- @Parameterized.Parameters
- public static Collection<Short[]> parameters()
- {
- return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
- }
-
- @Rule
- public final TestWatcher testName = new TestWatcher()
- {
-
- @Override
- public void starting(Description description)
- {
- super.starting(description);
- System.err.printf("Running %s.%s()%n",
- description.getClassName(),
- description.getMethodName());
- }
- };
-
- protected final short version;
- protected Server server;
- protected SPDYClient.Factory clientFactory;
- protected HTTPSPDYServerConnector connector;
-
- protected AbstractHTTPSPDYTest(short version)
- {
- this.version = version;
- }
-
- protected InetSocketAddress startHTTPServer(short version, Handler handler, long idleTimeout) throws Exception
- {
- QueuedThreadPool threadPool = new QueuedThreadPool(256);
- threadPool.setName("serverQTP");
- server = new Server(threadPool);
- connector = newHTTPSPDYServerConnector(version);
- connector.setPort(0);
- connector.setIdleTimeout(idleTimeout);
- server.addConnector(connector);
- server.setHandler(handler);
- server.start();
- return new InetSocketAddress("localhost", connector.getLocalPort());
- }
-
- protected Server getServer()
- {
- return server;
- }
-
- protected HTTPSPDYServerConnector newHTTPSPDYServerConnector(short version)
- {
- // For these tests, we need the connector to speak HTTP over SPDY even in non-SSL
- HttpConfiguration httpConfiguration = new HttpConfiguration();
- httpConfiguration.setSendServerVersion(true);
- httpConfiguration.setSendXPoweredBy(true);
- return new HTTPSPDYServerConnector(server, version, httpConfiguration, new PushStrategy.None());
- }
-
- protected Session startClient(short version, InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
- {
- if (clientFactory == null)
- {
- QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setName(threadPool.getName() + "-client");
- clientFactory = newSPDYClientFactory(threadPool);
- clientFactory.start();
- }
- return clientFactory.newSPDYClient(version).connect(socketAddress, listener);
- }
-
- protected SPDYClient.Factory newSPDYClientFactory(Executor threadPool)
- {
- return new SPDYClient.Factory(threadPool, null, null, connector.getIdleTimeout());
- }
-
- @After
- public void destroy() throws Exception
- {
- ((StdErrLog)Log.getLogger(HTTPSPDYServerConnector.class)).setHideStacks(true);
- if (clientFactory != null)
- {
- clientFactory.stop();
- }
- if (server != null)
- {
- server.stop();
- server.join();
- }
- ((StdErrLog)Log.getLogger(HTTPSPDYServerConnector.class)).setHideStacks(false);
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ConcurrentStreamsTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ConcurrentStreamsTest.java
deleted file mode 100644
index b86517aadc..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ConcurrentStreamsTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ConcurrentStreamsTest extends AbstractHTTPSPDYTest
-{
- public ConcurrentStreamsTest(short version)
- {
- super(version);
- }
-
- @Test
- public void testSlowStreamDoesNotBlockOtherStreams() throws Exception
- {
- final CountDownLatch slowServerLatch = new CountDownLatch(1);
- final CountDownLatch fastServerLatch = new CountDownLatch(1);
- final String fastPath = "/fast";
- final String slowPath = "/slow";
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- try
- {
- request.setHandled(true);
- switch (target)
- {
- case slowPath:
- Assert.assertTrue(fastServerLatch.await(10, TimeUnit.SECONDS));
- slowServerLatch.countDown();
- break;
- case fastPath:
- fastServerLatch.countDown();
- break;
- default:
- Assert.fail();
- break;
- }
- }
- catch (InterruptedException x)
- {
- throw new ServletException(x);
- }
- }
- }, 30000), null);
-
- // Perform slow request. This will wait on server side until the fast request wakes it up
- Fields headers = createHeaders(slowPath);
- final CountDownLatch slowClientLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields replyHeaders = replyInfo.getHeaders();
- Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- slowClientLatch.countDown();
- }
- });
-
- // Perform the fast request. This will wake up the slow request
- headers = createHeaders(fastPath);
- final CountDownLatch fastClientLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields replyHeaders = replyInfo.getHeaders();
- Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- fastClientLatch.countDown();
- }
- });
-
- Assert.assertTrue(fastServerLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(slowServerLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(fastClientLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(slowClientLatch.await(5, TimeUnit.SECONDS));
- }
-
- private Fields createHeaders(String path)
- {
- Fields headers = new Fields();
- headers.put(HTTPSPDYHeader.METHOD.name(version), "GET");
- headers.put(HTTPSPDYHeader.URI.name(version), path);
- headers.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- headers.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + connector.getLocalPort());
- return headers;
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDYTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDYTest.java
deleted file mode 100644
index 1656fd5da1..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDYTest.java
+++ /dev/null
@@ -1,288 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.http.HttpGenerator;
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class HttpTransportOverSPDYTest
-{
- @Mock
- Connector connector;
- @Mock
- HttpConfiguration httpConfiguration;
- @Mock
- EndPoint endPoint;
- @Mock
- PushStrategy pushStrategy;
- @Mock
- Stream stream;
- @Mock
- Callback callback;
- @Mock
- Session session;
- @Mock
- HttpGenerator.ResponseInfo responseInfo;
-
- Random random = new Random();
- short version = SPDY.V3;
-
- HttpTransportOverSPDY httpTransportOverSPDY;
-
- @Before
- public void setUp() throws Exception
- {
- Fields requestHeaders = new Fields();
- requestHeaders.add(HTTPSPDYHeader.METHOD.name(version), "GET");
- when(responseInfo.getStatus()).thenReturn(HttpStatus.OK_200);
- when(stream.getSession()).thenReturn(session);
- when(session.getVersion()).thenReturn(SPDY.V3);
- when(stream.isClosed()).thenReturn(false);
- httpTransportOverSPDY = new HttpTransportOverSPDY(connector, httpConfiguration, endPoint, pushStrategy,
- stream, requestHeaders);
- }
-
- @Test
- public void testSendWithResponseInfoNullAndContentNullAndLastContentTrue() throws Exception
- {
- ByteBuffer content = null;
- boolean lastContent = true;
-
- httpTransportOverSPDY.send(null, content, lastContent, callback);
- ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
- ArgumentCaptor<Callback> callbackCaptor = ArgumentCaptor.forClass(Callback.class);
- verify(stream, times(1)).data(dataInfoCaptor.capture(), callbackCaptor.capture());
- callbackCaptor.getValue().succeeded();
- verify(callback, times(1)).succeeded();
- assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
- assertThat("ByteBuffer is empty", dataInfoCaptor.getValue().length(), is(0));
- }
-
- @Test
- public void testSendWithResponseInfoNullAndContentAndLastContentTrue() throws Exception
- {
- ByteBuffer content = createRandomByteBuffer();
-
- boolean lastContent = true;
-
- httpTransportOverSPDY.send(null, content, lastContent, callback);
- ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
- ArgumentCaptor<Callback> callbackCaptor = ArgumentCaptor.forClass(Callback.class);
- verify(stream, times(1)).data(dataInfoCaptor.capture(), callbackCaptor.capture());
- callbackCaptor.getValue().succeeded();
- verify(callback, times(1)).succeeded();
- assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
- assertThat("ByteBuffer length is 4096", dataInfoCaptor.getValue().length(), is(4096));
- }
-
- @Test
- public void testSendWithResponseInfoNullAndEmptyContentAndLastContentTrue() throws Exception
- {
- ByteBuffer content = BufferUtil.EMPTY_BUFFER;
- boolean lastContent = true;
-
- httpTransportOverSPDY.send(null, content, lastContent, callback);
- ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
- ArgumentCaptor<Callback> callbackCaptor = ArgumentCaptor.forClass(Callback.class);
- verify(stream, times(1)).data(dataInfoCaptor.capture(), callbackCaptor.capture());
- callbackCaptor.getValue().succeeded();
- verify(callback, times(1)).succeeded();
- assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
- assertThat("ByteBuffer is empty", dataInfoCaptor.getValue().length(), is(0));
- }
-
- @Test
- public void testSendWithResponseInfoNullAndContentAndLastContentFalse() throws Exception
- {
- ByteBuffer content = createRandomByteBuffer();
- boolean lastContent = false;
-
- httpTransportOverSPDY.send(null, content, lastContent, callback);
- ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
- ArgumentCaptor<Callback> callbackCaptor = ArgumentCaptor.forClass(Callback.class);
- verify(stream, times(1)).data(dataInfoCaptor.capture(), callbackCaptor.capture());
- callbackCaptor.getValue().succeeded();
- verify(callback, times(1)).succeeded();
- assertThat("lastContent is false", dataInfoCaptor.getValue().isClose(), is(false));
- assertThat("ByteBuffer is empty", dataInfoCaptor.getValue().length(), is(4096));
- }
-
- @Test(expected = IllegalStateException.class)
- public void testSendWithResponseInfoNullAndContentNullAndLastContentFalse() throws Exception
- {
- ByteBuffer content = null;
- boolean lastContent = false;
- httpTransportOverSPDY.send(null, content, lastContent, callback);
- }
-
- @Test(expected = IllegalStateException.class)
- public void testSendWithResponseInfoNullAndEmptyContentAndLastContentFalse() throws Exception
- {
- ByteBuffer content = BufferUtil.EMPTY_BUFFER;
- boolean lastContent = false;
- httpTransportOverSPDY.send(null, content, lastContent, callback);
- }
-
- @Test
- public void testSendWithResponseInfoAndContentNullAndLastContentFalse() throws Exception
- {
- ByteBuffer content = null;
- boolean lastContent = false;
-
- httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
- ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
- ArgumentCaptor<Callback> callbackCaptor = ArgumentCaptor.forClass(Callback.class);
- verify(stream, times(1)).reply(replyInfoCaptor.capture(), callbackCaptor.capture());
- callbackCaptor.getValue().succeeded();
- assertThat("ReplyInfo close is true", replyInfoCaptor.getValue().isClose(), is(false));
-
- verify(stream, times(0)).data(any(ByteBufferDataInfo.class), any(Callback.class));
- verify(callback, times(1)).succeeded();
- }
-
- @Test
- public void testSendWithResponseInfoAndContentNullAndLastContentTrue() throws Exception
- {
- ByteBuffer content = null;
- boolean lastContent = true;
-
- // when stream.isClosed() is called a 2nd time, the reply has closed the stream already
- when(stream.isClosed()).thenReturn(false).thenReturn(true);
-
- httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
- ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
- ArgumentCaptor<Callback> callbackCaptor = ArgumentCaptor.forClass(Callback.class);
- verify(stream, times(1)).reply(replyInfoCaptor.capture(), callbackCaptor.capture());
- callbackCaptor.getValue().succeeded();
- assertThat("ReplyInfo close is true", replyInfoCaptor.getValue().isClose(), is(true));
-
- verify(callback, times(1)).succeeded();
- }
-
- @Test
- public void testSendWithResponseInfoAndContentAndLastContentTrue() throws Exception
- {
- ByteBuffer content = createRandomByteBuffer();
- boolean lastContent = true;
-
- httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
- ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
- ArgumentCaptor<Callback> callbackCaptor = ArgumentCaptor.forClass(Callback.class);
- verify(stream, times(1)).reply(replyInfoCaptor.capture(), callbackCaptor.capture());
- callbackCaptor.getValue().succeeded();
- assertThat("ReplyInfo close is false", replyInfoCaptor.getValue().isClose(), is(false));
- ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
- verify(stream, times(1)).data(dataInfoCaptor.capture(), callbackCaptor.capture());
- callbackCaptor.getValue().succeeded();
- assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
- assertThat("ByteBuffer length is 4096", dataInfoCaptor.getValue().length(), is(4096));
- verify(callback, times(1)).succeeded();
- }
-
- @Test
- public void testSendWithResponseInfoAndContentAndLastContentFalse() throws Exception
- {
- ByteBuffer content = createRandomByteBuffer();
- boolean lastContent = false;
-
- httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
- ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
- ArgumentCaptor<Callback> callbackCaptor = ArgumentCaptor.forClass(Callback.class);
- verify(stream, times(1)).reply(replyInfoCaptor.capture(), callbackCaptor.capture());
- callbackCaptor.getValue().succeeded();
- assertThat("ReplyInfo close is false", replyInfoCaptor.getValue().isClose(), is(false));
-
- ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
- verify(stream, times(1)).data(dataInfoCaptor.capture(), callbackCaptor.capture());
- callbackCaptor.getValue().succeeded();
- assertThat("lastContent is false", dataInfoCaptor.getValue().isClose(), is(false));
- assertThat("ByteBuffer length is 4096", dataInfoCaptor.getValue().length(), is(4096));
-
- verify(callback, times(1)).succeeded();
- }
-
- @Test
- public void testVerifyThatAStreamIsNotCommittedTwice() throws IOException, InterruptedException
- {
- final CountDownLatch failedCalledLatch = new CountDownLatch(1);
- ByteBuffer content = createRandomByteBuffer();
- boolean lastContent = false;
-
- httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
- ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
- verify(stream, times(1)).reply(replyInfoCaptor.capture(), any(Callback.class));
- assertThat("ReplyInfo close is false", replyInfoCaptor.getValue().isClose(), is(false));
-
- httpTransportOverSPDY.send(HttpGenerator.RESPONSE_500_INFO, null, true, new Callback.Adapter()
- {
- @Override
- public void failed(Throwable x)
- {
- failedCalledLatch.countDown();
- }
- });
-
- verify(stream, times(1)).data(any(DataInfo.class), any(Callback.class));
-
- assertThat("callback.failed has been called", failedCalledLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- private ByteBuffer createRandomByteBuffer()
- {
- ByteBuffer content = BufferUtil.allocate(8192);
- BufferUtil.flipToFill(content);
- byte[] randomBytes = new byte[4096];
- random.nextBytes(randomBytes);
- content.put(randomBytes);
- return content;
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/PushStrategyBenchmarkTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/PushStrategyBenchmarkTest.java
deleted file mode 100644
index 39dd32f433..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/PushStrategyBenchmarkTest.java
+++ /dev/null
@@ -1,397 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.Collections;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.client.api.Result;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.server.ConnectionFactory;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-
-@Ignore("make this test pass") // TODO
-public class PushStrategyBenchmarkTest extends AbstractHTTPSPDYTest
-{
- // Sample resources size from webtide.com home page
- private final int[] htmlResources = new int[]
- {8 * 1024};
- private final int[] cssResources = new int[]
- {12 * 1024, 2 * 1024};
- private final int[] jsResources = new int[]
- {75 * 1024, 24 * 1024, 36 * 1024};
- private final int[] pngResources = new int[]
- {1024, 45 * 1024, 6 * 1024, 2 * 1024, 2 * 1024, 2 * 1024, 3 * 1024, 512, 512, 19 * 1024, 512, 128, 32};
- private final Set<String> pushedResources = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
- private final AtomicReference<CountDownLatch> latch = new AtomicReference<>();
- private final long roundtrip = 100;
- private final int runs = 10;
-
- public PushStrategyBenchmarkTest(short version)
- {
- super(version);
- }
-
- @Test
- public void benchmarkPushStrategy() throws Exception
- {
- InetSocketAddress address = startHTTPServer(version, new PushStrategyBenchmarkHandler(), 30000);
-
- // Plain HTTP
- ConnectionFactory factory = new HttpConnectionFactory(new HttpConfiguration());
- connector.setDefaultProtocol(factory.getProtocol());
- HttpClient httpClient = new HttpClient();
- // Simulate browsers, that open 6 connection per origin
- httpClient.setMaxConnectionsPerDestination(6);
- httpClient.start();
- benchmarkHTTP(httpClient);
- httpClient.stop();
-
- // First push strategy
- PushStrategy pushStrategy = new PushStrategy.None();
- factory = new HTTPSPDYServerConnectionFactory(version, new HttpConfiguration(), pushStrategy);
- connector.setDefaultProtocol(factory.getProtocol());
- Session session = startClient(version, address, new ClientSessionFrameListener());
- benchmarkSPDY(pushStrategy, session);
- session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
-
- // Second push strategy
- pushStrategy = new ReferrerPushStrategy();
- factory = new HTTPSPDYServerConnectionFactory(version, new HttpConfiguration(), pushStrategy);
- connector.setDefaultProtocol(factory.getProtocol());
- session = startClient(version, address, new ClientSessionFrameListener());
- benchmarkSPDY(pushStrategy, session);
- session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
- }
-
- private void benchmarkHTTP(HttpClient httpClient) throws Exception
- {
- // Warm up
- performHTTPRequests(httpClient);
- performHTTPRequests(httpClient);
-
- long total = 0;
- for (int i = 0; i < runs; ++i)
- {
- long begin = System.nanoTime();
- int requests = performHTTPRequests(httpClient);
- long elapsed = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - begin);
- total += elapsed;
- System.err.printf("HTTP: run %d, %d request(s), roundtrip delay %d ms, elapsed = %d%n",
- i, requests, roundtrip, elapsed);
- }
- System.err.printf("HTTP: roundtrip delay %d ms, average = %d%n%n",
- roundtrip, total / runs);
- }
-
- private int performHTTPRequests(HttpClient httpClient) throws Exception
- {
- int result = 0;
-
- for (int j = 0; j < htmlResources.length; ++j)
- {
- latch.set(new CountDownLatch(cssResources.length + jsResources.length + pngResources.length));
-
- String primaryPath = "/" + j + ".html";
- String referrer = "http://localhost:" + connector.getLocalPort() + primaryPath;
- ++result;
- ContentResponse response = httpClient.newRequest("localhost", connector.getLocalPort())
- .path(primaryPath)
- .timeout(5, TimeUnit.SECONDS)
- .send();
- Assert.assertEquals(200, response.getStatus());
-
- for (int i = 0; i < cssResources.length; ++i)
- {
- String path = "/" + i + ".css";
- ++result;
- httpClient.newRequest("localhost", connector.getLocalPort())
- .path(path)
- .header(HttpHeader.REFERER, referrer)
- .send(new TestListener());
- }
- for (int i = 0; i < jsResources.length; ++i)
- {
- String path = "/" + i + ".js";
- ++result;
- httpClient.newRequest("localhost", connector.getLocalPort())
- .path(path)
- .header(HttpHeader.REFERER, referrer)
- .send(new TestListener());
- }
- for (int i = 0; i < pngResources.length; ++i)
- {
- String path = "/" + i + ".png";
- ++result;
- httpClient.newRequest("localhost", connector.getLocalPort())
- .path(path)
- .header(HttpHeader.REFERER, referrer)
- .send(new TestListener());
- }
-
- Assert.assertTrue(latch.get().await(5, TimeUnit.SECONDS));
- }
-
- return result;
- }
-
- private void benchmarkSPDY(PushStrategy pushStrategy, Session session) throws Exception
- {
- // Warm up PushStrategy
- performRequests(session);
- performRequests(session);
-
- long total = 0;
- for (int i = 0; i < runs; ++i)
- {
- long begin = System.nanoTime();
- int requests = performRequests(session);
- long elapsed = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - begin);
- total += elapsed;
- System.err.printf("SPDY(%s): run %d, %d request(s), roundtrip delay %d ms, elapsed = %d%n",
- pushStrategy.getClass().getSimpleName(), i, requests, roundtrip, elapsed);
- }
- System.err.printf("SPDY(%s): roundtrip delay %d ms, average = %d%n%n",
- pushStrategy.getClass().getSimpleName(), roundtrip, total / runs);
- }
-
- private int performRequests(Session session) throws Exception
- {
- int result = 0;
-
- for (int j = 0; j < htmlResources.length; ++j)
- {
- latch.set(new CountDownLatch(cssResources.length + jsResources.length + pngResources.length));
- pushedResources.clear();
-
- String primaryPath = "/" + j + ".html";
- String referrer = "http://localhost:" + connector.getLocalPort() + primaryPath;
- Fields headers = new Fields();
- headers.put(HTTPSPDYHeader.METHOD.name(version), "GET");
- headers.put(HTTPSPDYHeader.URI.name(version), primaryPath);
- headers.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- headers.put(HTTPSPDYHeader.SCHEME.name(version), "http");
- headers.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + connector.getLocalPort());
- // Wait for the HTML to simulate browser's behavior
- ++result;
- final CountDownLatch htmlLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- htmlLatch.countDown();
- }
- });
- Assert.assertTrue(htmlLatch.await(5, TimeUnit.SECONDS));
-
- for (int i = 0; i < cssResources.length; ++i)
- {
- String path = "/" + i + ".css";
- if (pushedResources.contains(path))
- continue;
- headers = createRequestHeaders(referrer, path);
- ++result;
- session.syn(new SynInfo(headers, true), new DataListener());
- }
- for (int i = 0; i < jsResources.length; ++i)
- {
- String path = "/" + i + ".js";
- if (pushedResources.contains(path))
- continue;
- headers = createRequestHeaders(referrer, path);
- ++result;
- session.syn(new SynInfo(headers, true), new DataListener());
- }
- for (int i = 0; i < pngResources.length; ++i)
- {
- String path = "/" + i + ".png";
- if (pushedResources.contains(path))
- continue;
- headers = createRequestHeaders(referrer, path);
- ++result;
- session.syn(new SynInfo(headers, true), new DataListener());
- }
-
- Assert.assertTrue(latch.get().await(5, TimeUnit.SECONDS));
- }
-
- return result;
- }
-
- private Fields createRequestHeaders(String referrer, String path)
- {
- Fields headers;
- headers = new Fields();
- headers.put(HTTPSPDYHeader.METHOD.name(version), "GET");
- headers.put(HTTPSPDYHeader.URI.name(version), path);
- headers.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- headers.put(HTTPSPDYHeader.SCHEME.name(version), "http");
- headers.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + connector.getLocalPort());
- headers.put("referer", referrer);
- return headers;
- }
-
- private void sleep(long delay) throws ServletException
- {
- try
- {
- TimeUnit.MILLISECONDS.sleep(delay);
- }
- catch (InterruptedException x)
- {
- throw new ServletException(x);
- }
- }
-
- private class PushStrategyBenchmarkHandler extends AbstractHandler
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
-
- // Sleep half of the roundtrip time, to simulate the delay of responses, even for pushed resources
- sleep(roundtrip / 2);
- // If it's not a pushed resource, sleep half of the roundtrip time, to simulate the delay of requests
- if (request.getHeader("x-spdy-push") == null)
- sleep(roundtrip / 2);
-
- String suffix = target.substring(target.indexOf('.') + 1);
- int index = Integer.parseInt(target.substring(1, target.length() - suffix.length() - 1));
-
- int contentLength;
- String contentType;
- switch (suffix)
- {
- case "html":
- contentLength = htmlResources[index];
- contentType = "text/html";
- break;
- case "css":
- contentLength = cssResources[index];
- contentType = "text/css";
- break;
- case "js":
- contentLength = jsResources[index];
- contentType = "text/javascript";
- break;
- case "png":
- contentLength = pngResources[index];
- contentType = "image/png";
- break;
- default:
- throw new ServletException();
- }
-
- response.setContentType(contentType);
- response.setContentLength(contentLength);
- response.getOutputStream().write(new byte[contentLength]);
- }
- }
-
- private void addPushedResource(String pushedURI)
- {
- switch (version)
- {
- case SPDY.V2:
- {
- Matcher matcher = Pattern.compile("https?://[^:]+:\\d+(/.*)").matcher(pushedURI);
- Assert.assertTrue(matcher.matches());
- pushedResources.add(matcher.group(1));
- break;
- }
- case SPDY.V3:
- {
- pushedResources.add(pushedURI);
- break;
- }
- default:
- {
- throw new IllegalStateException();
- }
- }
- }
-
- private class ClientSessionFrameListener extends SessionFrameListener.Adapter
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- String path = synInfo.getHeaders().get(HTTPSPDYHeader.URI.name(version)).getValue();
- addPushedResource(path);
- return new DataListener();
- }
- }
-
- private class DataListener extends StreamFrameListener.Adapter
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- latch.get().countDown();
- }
- }
-
- private class TestListener extends Response.Listener.Adapter
- {
- @Override
- public void onComplete(Result result)
- {
- if (!result.isFailed())
- latch.get().countDown();
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyTest.java
deleted file mode 100644
index 159e742a39..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyTest.java
+++ /dev/null
@@ -1,1138 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertThat;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.InetSocketAddress;
-import java.util.Arrays;
-import java.util.Random;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.server.ConnectionFactory;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.servlets.gzip.GzipHandler;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Settings;
-import org.eclipse.jetty.spdy.api.SettingsInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.log.StdErrLog;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
-{
- private static final Logger LOG = Log.getLogger(ReferrerPushStrategyTest.class);
-
- private final int referrerPushPeriod = 1000;
- private final String mainResource = "/index.html";
- private final String cssResource = "/style.css";
- private InetSocketAddress serverAddress;
- private ReferrerPushStrategy pushStrategy;
- private ConnectionFactory defaultFactory;
- private Fields mainRequestHeaders;
- private Fields associatedCSSRequestHeaders;
- private Fields associatedJSRequestHeaders;
-
- public ReferrerPushStrategyTest(short version)
- {
- super(version);
- }
-
- @Override
- protected HTTPSPDYServerConnector newHTTPSPDYServerConnector(short version)
- {
- return new HTTPSPDYServerConnector(server, version, new HttpConfiguration(), new ReferrerPushStrategy());
- }
-
- @Before
- public void setUp() throws Exception
- {
- serverAddress = createServer();
- pushStrategy = new ReferrerPushStrategy();
- pushStrategy.setReferrerPushPeriod(referrerPushPeriod);
- defaultFactory = new HTTPSPDYServerConnectionFactory(version, new HttpConfiguration(), pushStrategy);
- connector.addConnectionFactory(defaultFactory);
- if (connector.getConnectionFactory(NPNServerConnectionFactory.class) != null)
- connector.getConnectionFactory(NPNServerConnectionFactory.class).setDefaultProtocol(defaultFactory.getProtocol());
- else
- connector.setDefaultProtocol(defaultFactory.getProtocol());
- mainRequestHeaders = createHeadersWithoutReferrer(mainResource);
- associatedCSSRequestHeaders = createHeaders(cssResource);
- associatedJSRequestHeaders = createHeaders("/application.js");
- }
-
- @Test
- public void testPushHeadersAreValid() throws Exception
- {
- sendMainRequestAndCSSRequest(null, false);
- run2ndClientRequests(true, true);
- }
-
- @Test
- public void testClientResetsPushStreams() throws Exception
- {
- ((StdErrLog)Log.getLogger("org.eclipse.jetty.server.HttpChannel")).setHideStacks(true);
- sendMainRequestAndCSSRequest(null, false);
- final CountDownLatch pushDataLatch = new CountDownLatch(1);
- final CountDownLatch pushSynHeadersValid = new CountDownLatch(1);
- Session session = startClient(version, serverAddress, null);
- // Send main request. That should initiate the push push's which get reset by the client
- sendRequest(session, mainRequestHeaders, pushSynHeadersValid, pushDataLatch, true);
-
- assertThat("No push data is received", pushDataLatch.await(1, TimeUnit.SECONDS), is(false));
- assertThat("Push push headers valid", pushSynHeadersValid.await(5, TimeUnit.SECONDS), is(true));
-
- sendRequest(session, associatedCSSRequestHeaders, pushSynHeadersValid, pushDataLatch, true);
- ((StdErrLog)Log.getLogger("org.eclipse.jetty.server.HttpChannel")).setHideStacks(false);
- }
-
- @Test
- public void testUserAgentBlackList() throws Exception
- {
- pushStrategy.setUserAgentBlacklist(Arrays.asList(".*(?i)firefox/16.*"));
- sendMainRequestAndCSSRequest(null, false);
- run2ndClientRequests(false, false);
- }
-
- @Test
- public void testReferrerPushPeriod() throws Exception
- {
- Session session = sendMainRequestAndCSSRequest(null, false);
-
- // Sleep for pushPeriod This should prevent application.js from being mapped as pushResource
- Thread.sleep(referrerPushPeriod + 1);
- sendRequest(session, associatedJSRequestHeaders, null, null, false);
-
- run2ndClientRequests(false, true);
- }
-
- @Test
- public void testMaxAssociatedResources() throws Exception
- {
- pushStrategy.setMaxAssociatedResources(1);
- Session session = sendMainRequestAndCSSRequest(null, false);
- sendRequest(session, associatedJSRequestHeaders, null, null, false);
-
- final CountDownLatch mainStreamLatch = new CountDownLatch(2);
- final CountDownLatch pushDataLatch = new CountDownLatch(2);
- final CountDownLatch pushSynHeadersValid = new CountDownLatch(1);
- final CountDownLatch pushResponseHeaders = new CountDownLatch(1);
- Session session2 = startClient(version, serverAddress, null);
- session2.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- validateHeaders(pushInfo.getHeaders(), pushSynHeadersValid);
-
- assertThat("Stream is unidirectional", stream.isUnidirectional(), is(true));
- assertThat("URI header ends with css", pushInfo.getHeaders().get(HTTPSPDYHeader.URI.name(version))
- .getValue().endsWith
- ("" +
- ".css"),
- is(true));
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- Fields headers = headersInfo.getHeaders();
- if (validateHeader(headers, HTTPSPDYHeader.STATUS.name(version), "200 OK")
- && validateHeader(headers, HTTPSPDYHeader.VERSION.name(version),
- "HTTP/1.1") && validateHeader(headers, "content-encoding", "gzip"))
- pushResponseHeaders.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertThat("replyInfo.isClose() is false", replyInfo.isClose(), is(false));
- mainStreamLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainStreamLatch.countDown();
- }
- });
-
- assertThat("Main request reply and/or data received", mainStreamLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("Not more than one push is received", pushDataLatch.await(1, TimeUnit.SECONDS), is(false));
- assertThat("Push push headers valid", pushSynHeadersValid.await(5, TimeUnit.SECONDS), is(true));
- assertThat("Push response headers are valid", pushResponseHeaders.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testMaxConcurrentStreamsToDisablePush() throws Exception
- {
- final CountDownLatch pushReceivedLatch = new CountDownLatch(1);
-
- Session pushCacheBuildSession = startClient(version, serverAddress, null);
-
- pushCacheBuildSession.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter());
- pushCacheBuildSession.syn(new SynInfo(associatedCSSRequestHeaders, true), new StreamFrameListener.Adapter());
-
- Session session = startClient(version, serverAddress, null);
-
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.MAX_CONCURRENT_STREAMS, 0));
- SettingsInfo settingsInfo = new SettingsInfo(settings);
- session.settings(settingsInfo);
-
- ((StdErrLog)Log.getLogger("org.eclipse.jetty.spdy.server.http" +
- ".HttpTransportOverSPDY$PushResourceCoordinator$1")).setHideStacks(true);
- session.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- pushReceivedLatch.countDown();
- return super.onPush(stream, pushInfo);
- }
- });
-
- assertThat("No push stream is received", pushReceivedLatch.await(1, TimeUnit.SECONDS), is(false));
- ((StdErrLog)Log.getLogger("org.eclipse.jetty.spdy.server.http" +
- ".HttpTransportOverSPDY$PushResourceCoordinator$1")).setHideStacks(false);
- }
-
- @Test
- public void testPushResourceOrder() throws Exception
- {
- final CountDownLatch allExpectedPushesReceivedLatch = new CountDownLatch(4);
- final CountDownLatch allPushDataReceivedLatch = new CountDownLatch(4);
-
- Session pushCacheBuildSession = startClient(version, serverAddress, null);
-
- sendRequest(pushCacheBuildSession, mainRequestHeaders, null, null, false);
- sendRequest(pushCacheBuildSession, associatedCSSRequestHeaders, null, null, false);
- sendRequest(pushCacheBuildSession, associatedJSRequestHeaders, null, null, false);
- sendRequest(pushCacheBuildSession, createHeaders("/image1.jpg", mainResource), null, null, false);
- sendRequest(pushCacheBuildSession, createHeaders("/image2.jpg", mainResource), null, null, false);
-
- Session session = startClient(version, serverAddress, null);
-
- session.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- LOG.info("onPush: stream: {}, pushInfo: {}", stream, pushInfo);
- String uriHeader = pushInfo.getHeaders().get(HTTPSPDYHeader.URI.name(version)).getValue();
- switch ((int)allExpectedPushesReceivedLatch.getCount())
- {
- case 4:
- assertThat("1st pushed resource is the css", uriHeader.endsWith("css"), is(true));
- break;
- case 3:
- assertThat("2nd pushed resource is the js", uriHeader.endsWith("js"), is(true));
- break;
- case 2:
- assertThat("3rd pushed resource is image1", uriHeader.endsWith("image1.jpg"),
- is(true));
- break;
- case 1:
- assertThat("4th pushed resource is image2", uriHeader.endsWith("image2.jpg"),
- is(true));
- break;
- }
- allExpectedPushesReceivedLatch.countDown();
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- if(dataInfo.isClose())
- allPushDataReceivedLatch.countDown();
- }
- };
- }
- });
-
- assertThat("All expected push resources have been received", allExpectedPushesReceivedLatch.await(5,
- TimeUnit.SECONDS), is(true));
- assertThat("All push data has been fully received", allPushDataReceivedLatch.await(5, TimeUnit.SECONDS),
- is(true));
- }
-
- @Test
- public void testThatPushResourcesAreUnique() throws Exception
- {
- final CountDownLatch pushReceivedLatch = new CountDownLatch(2);
- sendMainRequestAndCSSRequest(null, false);
- sendMainRequestAndCSSRequest(null, false);
-
- Session session = startClient(version, serverAddress, null);
-
- session.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- pushReceivedLatch.countDown();
- LOG.info("Push received: {}", pushInfo);
- return null;
- }
- });
-
- assertThat("style.css has been pushed only once", pushReceivedLatch.await(1, TimeUnit.SECONDS), is(false));
- }
-
- @Test
- public void testPushResourceAreSentNonInterleaved() throws Exception
- {
- final CountDownLatch allExpectedPushesReceivedLatch = new CountDownLatch(4);
- final CountDownLatch allPushDataReceivedLatch = new CountDownLatch(4);
- final CopyOnWriteArrayList<Integer> dataReceivedOrder = new CopyOnWriteArrayList<>();
-
- InetSocketAddress bigResponseServerAddress = startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- byte[] bytes = new byte[32768];
- new Random().nextBytes(bytes);
- ServletOutputStream outputStream = response.getOutputStream();
- outputStream.write(bytes);
- baseRequest.setHandled(true);
- }
- }, 30000);
- Session pushCacheBuildSession = startClient(version, bigResponseServerAddress, null);
-
- Fields mainResourceHeaders = createHeadersWithoutReferrer(mainResource);
- sendRequest(pushCacheBuildSession, mainResourceHeaders, null, null, false);
- sendRequest(pushCacheBuildSession, createHeaders("/style.css", mainResource), null, null, false);
- sendRequest(pushCacheBuildSession, createHeaders("/javascript.js", mainResource), null, null, false);
- sendRequest(pushCacheBuildSession, createHeaders("/image1.jpg", mainResource), null, null, false);
- sendRequest(pushCacheBuildSession, createHeaders("/image2.jpg", mainResource), null, null, false);
-
- Session session = startClient(version, bigResponseServerAddress, null);
-
- session.syn(new SynInfo(mainResourceHeaders, true), new StreamFrameListener.Adapter()
- {
- AtomicInteger currentStreamId = new AtomicInteger(2);
-
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- LOG.info("Received push for stream: {} {}", stream.getId(), pushInfo);
- String uriHeader = pushInfo.getHeaders().get(HTTPSPDYHeader.URI.name(version)).getValue();
- switch ((int)allExpectedPushesReceivedLatch.getCount())
- {
- case 4:
- assertThat("1st pushed resource is the css", uriHeader.endsWith("css"), is(true));
- break;
- case 3:
- assertThat("2nd pushed resource is the js", uriHeader.endsWith("js"), is(true));
- break;
- case 2:
- assertThat("3rd pushed resource is image1", uriHeader.endsWith("image1.jpg"),
- is(true));
- break;
- case 1:
- assertThat("4th pushed resource is image2", uriHeader.endsWith("image2.jpg"),
- is(true));
- break;
- }
- allExpectedPushesReceivedLatch.countDown();
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- if (stream.getId() != currentStreamId.get())
- throw new IllegalStateException("Streams interleaved. Expected StreamId: " +
- currentStreamId + " but was: " + stream.getId());
- dataInfo.consume(dataInfo.available());
- if (dataInfo.isClose())
- {
- currentStreamId.compareAndSet(currentStreamId.get(), currentStreamId.get() + 2);
- dataReceivedOrder.add(stream.getId());
- allPushDataReceivedLatch.countDown();
- }
- LOG.info(stream.getId() + ":" + dataInfo);
- }
- };
- }
- });
-
- assertThat("All push resources received", allExpectedPushesReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("All pushData received", allPushDataReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("The data for different push streams has not been interleaved",
- dataReceivedOrder.toString(), equalTo("[2, 4, 6, 8]"));
- LOG.info(dataReceivedOrder.toString());
- }
-
- private InetSocketAddress createServer() throws Exception
- {
- GzipHandler gzipHandler = new GzipHandler();
- gzipHandler.setHandler(new AbstractHandler()
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- String url = request.getRequestURI();
- PrintWriter output = response.getWriter();
- if (url.endsWith(".html"))
- output.print("<html><head/><body>HELLO</body></html>");
- else if (url.endsWith(".css"))
- output.print("body { background: #FFF; }");
- else if (url.endsWith(".js"))
- output.print("function(){}();");
- baseRequest.setHandled(true);
- }
- });
- return startHTTPServer(version, gzipHandler, 30000);
- }
-
- private Session sendMainRequestAndCSSRequest(SessionFrameListener sessionFrameListener, boolean awaitPush) throws Exception
- {
- Session session = startClient(version, serverAddress, sessionFrameListener);
-
- CountDownLatch pushDataLatch = new CountDownLatch(2);
- sendRequest(session, mainRequestHeaders, null, pushDataLatch, false);
- sendRequest(session, associatedCSSRequestHeaders, null, pushDataLatch, false);
- if (awaitPush)
- assertThat("pushes have been received", pushDataLatch.await(5, TimeUnit.SECONDS), is(true));
-
- return session;
- }
-
- private void sendRequest(Session session, Fields requestHeaders, final CountDownLatch pushSynHeadersValid,
- final CountDownLatch pushDataLatch, final boolean resetPush) throws InterruptedException
- {
- LOG.info("sendRequest. headers={},resetPush={}", requestHeaders, resetPush);
- final CountDownLatch dataReceivedLatch = new CountDownLatch(1);
- session.syn(new SynInfo(requestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- if (pushSynHeadersValid != null)
- validateHeaders(pushInfo.getHeaders(), pushSynHeadersValid);
-
- assertThat("Stream is unidirectional", stream.isUnidirectional(), is(true));
- assertThat("URI header ends with css", pushInfo.getHeaders().get(HTTPSPDYHeader.URI.name(version))
- .getValue().endsWith
- ("" +
- ".css"),
- is(true));
- if (resetPush)
- stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new Callback.Adapter());
- return new StreamFrameListener.Adapter()
- {
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertThat(replyInfo.getHeaders().get(HTTPSPDYHeader.STATUS.name(version)).getValue(), is("200 OK"));
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- dataReceivedLatch.countDown();
- }
- }, new Promise.Adapter<Stream>());
- assertThat(dataReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- private void run2ndClientRequests(final boolean validateHeaders,
- boolean expectPushResource) throws Exception
- {
- final CountDownLatch mainStreamLatch = new CountDownLatch(2);
- final CountDownLatch pushDataLatch = new CountDownLatch(1);
- final CountDownLatch pushSynHeadersValid = new CountDownLatch(1);
- final CountDownLatch pushResponseHeaders = new CountDownLatch(1);
- Session session2 = startClient(version, serverAddress, null);
- session2.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- if (validateHeaders)
- validateHeaders(pushInfo.getHeaders(), pushSynHeadersValid);
-
- assertThat("Stream is unidirectional", stream.isUnidirectional(), is(true));
- assertThat("URI header ends with css", pushInfo.getHeaders().get(HTTPSPDYHeader.URI.name(version))
- .getValue().endsWith
- ("" +
- ".css"),
- is(true));
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- Fields headers = headersInfo.getHeaders();
- if (validateHeader(headers, HTTPSPDYHeader.STATUS.name(version), "200 OK")
- && validateHeader(headers, HTTPSPDYHeader.VERSION.name(version),
- "HTTP/1.1") && validateHeader(headers, "content-encoding", "gzip"))
- pushResponseHeaders.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertThat("replyInfo.isClose() is false", replyInfo.isClose(), is(false));
- mainStreamLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainStreamLatch.countDown();
- }
- });
-
- assertThat("Main request reply and/or data received", mainStreamLatch.await(5, TimeUnit.SECONDS), is(true));
- if (expectPushResource)
- assertThat("Pushed data received", pushDataLatch.await(5, TimeUnit.SECONDS), is(true));
- else
- assertThat("No push data is received", pushDataLatch.await(1, TimeUnit.SECONDS), is(false));
- if (validateHeaders)
- {
- assertThat("Push push headers valid", pushSynHeadersValid.await(5, TimeUnit.SECONDS), is(true));
- assertThat("Push response headers are valid", pushResponseHeaders.await(5, TimeUnit.SECONDS), is(true));
- }
- }
-
- @Test
- public void testAssociatedResourceIsPushed() throws Exception
- {
- InetSocketAddress address = startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- String url = request.getRequestURI();
- PrintWriter output = response.getWriter();
- if (url.endsWith(".html"))
- output.print("<html><head/><body>HELLO</body></html>");
- else if (url.endsWith(".css"))
- output.print("body { background: #FFF; }");
- baseRequest.setHandled(true);
- }
- }, 30000);
- Session session1 = startClient(version, address, null);
-
- final CountDownLatch mainResourceLatch = new CountDownLatch(1);
- Fields mainRequestHeaders = createHeadersWithoutReferrer(mainResource);
-
- session1.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainResourceLatch.countDown();
- }
- });
- Assert.assertTrue(mainResourceLatch.await(5, TimeUnit.SECONDS));
-
- sendRequest(session1, createHeaders(cssResource), null, null, false);
-
- // Create another client, and perform the same request for the main resource, we expect the css being pushed
-
- final CountDownLatch mainStreamLatch = new CountDownLatch(2);
- final CountDownLatch pushDataLatch = new CountDownLatch(1);
- Session session2 = startClient(version, address, null);
- session2.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- Assert.assertTrue(stream.isUnidirectional());
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- mainStreamLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainStreamLatch.countDown();
- }
- });
-
- Assert.assertTrue(mainStreamLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(pushDataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testAssociatedResourceWithWrongContentTypeIsNotPushed() throws Exception
- {
- final String fakeResource = "/fake.png";
- InetSocketAddress address = startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- String url = request.getRequestURI();
- PrintWriter output = response.getWriter();
- if (url.endsWith(".html"))
- {
- response.setContentType("text/html");
- output.print("<html><head/><body>HELLO</body></html>");
- }
- else if (url.equals(fakeResource))
- {
- response.setContentType("text/html");
- output.print("<html><head/><body>IMAGE</body></html>");
- }
- else if (url.endsWith(".css"))
- {
- response.setContentType("text/css");
- output.print("body { background: #FFF; }");
- }
- baseRequest.setHandled(true);
- }
- }, 30000);
- Session session1 = startClient(version, address, null);
-
- final CountDownLatch mainResourceLatch = new CountDownLatch(1);
- Fields mainRequestHeaders = createHeadersWithoutReferrer(mainResource);
-
- session1.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainResourceLatch.countDown();
- }
- });
- Assert.assertTrue(mainResourceLatch.await(5, TimeUnit.SECONDS));
-
- final CountDownLatch associatedResourceLatch = new CountDownLatch(1);
- String cssResource = "/stylesheet.css";
- Fields associatedRequestHeaders = createHeaders(cssResource);
- session1.syn(new SynInfo(associatedRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- associatedResourceLatch.countDown();
- }
- });
- Assert.assertTrue(associatedResourceLatch.await(5, TimeUnit.SECONDS));
-
- final CountDownLatch fakeAssociatedResourceLatch = new CountDownLatch(1);
- Fields fakeAssociatedRequestHeaders = createHeaders(fakeResource);
- session1.syn(new SynInfo(fakeAssociatedRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- fakeAssociatedResourceLatch.countDown();
- }
- });
- Assert.assertTrue(fakeAssociatedResourceLatch.await(5, TimeUnit.SECONDS));
-
- // Create another client, and perform the same request for the main resource,
- // we expect the css being pushed but not the fake PNG
-
- final CountDownLatch mainStreamLatch = new CountDownLatch(2);
- final CountDownLatch pushDataLatch = new CountDownLatch(1);
- Session session2 = startClient(version, address, null);
- session2.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- Assert.assertTrue(stream.isUnidirectional());
- Assert.assertTrue(pushInfo.getHeaders().get(HTTPSPDYHeader.URI.name(version)).getValue().endsWith("" +
- ".css"));
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- mainStreamLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainStreamLatch.countDown();
- }
- });
-
- Assert.assertTrue(mainStreamLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(pushDataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testNestedAssociatedResourceIsPushed() throws Exception
- {
- InetSocketAddress address = startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- String url = request.getRequestURI();
- PrintWriter output = response.getWriter();
- if (url.endsWith(".html"))
- output.print("<html><head/><body>HELLO</body></html>");
- else if (url.endsWith(".css"))
- output.print("body { background: #FFF; }");
- else if (url.endsWith(".gif"))
- output.print("\u0000");
- baseRequest.setHandled(true);
- }
- }, 30000);
- Session session1 = startClient(version, address, null);
-
- final CountDownLatch mainResourceLatch = new CountDownLatch(1);
- Fields mainRequestHeaders = createHeadersWithoutReferrer(mainResource);
-
- session1.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainResourceLatch.countDown();
- }
- });
- Assert.assertTrue(mainResourceLatch.await(5, TimeUnit.SECONDS));
-
- final CountDownLatch associatedResourceLatch = new CountDownLatch(1);
- Fields associatedRequestHeaders = createHeaders(cssResource);
- session1.syn(new SynInfo(associatedRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- associatedResourceLatch.countDown();
- }
- });
- Assert.assertTrue(associatedResourceLatch.await(5, TimeUnit.SECONDS));
-
- final CountDownLatch nestedResourceLatch = new CountDownLatch(1);
- String imageUrl = "/image.gif";
- Fields nestedRequestHeaders = createHeaders(imageUrl, cssResource);
-
- session1.syn(new SynInfo(nestedRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- nestedResourceLatch.countDown();
- }
- });
- Assert.assertTrue(nestedResourceLatch.await(5, TimeUnit.SECONDS));
-
- // Create another client, and perform the same request for the main resource, we expect the css and the image being pushed
-
- final CountDownLatch mainStreamLatch = new CountDownLatch(2);
- final CountDownLatch pushDataLatch = new CountDownLatch(2);
- Session session2 = startClient(version, address, null);
- session2.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- Assert.assertTrue(stream.isUnidirectional());
- return new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- mainStreamLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainStreamLatch.countDown();
- }
- });
-
- Assert.assertTrue(mainStreamLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(pushDataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testMainResourceWithReferrerIsNotPushed() throws Exception
- {
- InetSocketAddress address = startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- String url = request.getRequestURI();
- PrintWriter output = response.getWriter();
- if (url.endsWith(".html"))
- output.print("<html><head/><body>HELLO</body></html>");
- baseRequest.setHandled(true);
- }
- }, 30000);
- Session session1 = startClient(version, address, null);
-
- final CountDownLatch mainResourceLatch = new CountDownLatch(1);
- Fields mainRequestHeaders = createHeadersWithoutReferrer(mainResource);
-
- session1.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainResourceLatch.countDown();
- }
- });
- Assert.assertTrue(mainResourceLatch.await(5, TimeUnit.SECONDS));
-
- final CountDownLatch associatedResourceLatch = new CountDownLatch(1);
- String associatedResource = "/home.html";
- Fields associatedRequestHeaders = createHeaders(associatedResource);
-
- session1.syn(new SynInfo(associatedRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- associatedResourceLatch.countDown();
- }
- });
- Assert.assertTrue(associatedResourceLatch.await(5, TimeUnit.SECONDS));
-
- // Create another client, and perform the same request for the main resource, we expect nothing being pushed
-
- final CountDownLatch mainStreamLatch = new CountDownLatch(2);
- final CountDownLatch pushLatch = new CountDownLatch(1);
- Session session2 = startClient(version, address, new SessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- pushLatch.countDown();
- return null;
- }
- });
- session2.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- mainStreamLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainStreamLatch.countDown();
- }
- });
-
- Assert.assertTrue(mainStreamLatch.await(5, TimeUnit.SECONDS));
- Assert.assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
- }
-
- @Test
- public void testRequestWithIfModifiedSinceHeaderPreventsPush() throws Exception
- {
- InetSocketAddress address = startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- String url = request.getRequestURI();
- PrintWriter output = response.getWriter();
- if (url.endsWith(".html"))
- output.print("<html><head/><body>HELLO</body></html>");
- else if (url.endsWith(".css"))
- output.print("body { background: #FFF; }");
- baseRequest.setHandled(true);
- }
- }, 30000);
- Session session1 = startClient(version, address, null);
-
- final CountDownLatch mainResourceLatch = new CountDownLatch(1);
- Fields mainRequestHeaders = createHeaders(mainResource);
- mainRequestHeaders.put("If-Modified-Since", "Tue, 27 Mar 2012 16:36:52 GMT");
- session1.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainResourceLatch.countDown();
- }
- });
- Assert.assertTrue(mainResourceLatch.await(5, TimeUnit.SECONDS));
-
- final CountDownLatch associatedResourceLatch = new CountDownLatch(1);
- Fields associatedRequestHeaders = createHeaders(cssResource);
- session1.syn(new SynInfo(associatedRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- associatedResourceLatch.countDown();
- }
- });
- Assert.assertTrue(associatedResourceLatch.await(5, TimeUnit.SECONDS));
-
- // Create another client, and perform the same request for the main resource, we expect the css NOT being pushed as the main request contains an
- // if-modified-since header
-
- final CountDownLatch mainStreamLatch = new CountDownLatch(2);
- final CountDownLatch pushDataLatch = new CountDownLatch(1);
- Session session2 = startClient(version, address, new SessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Assert.assertTrue(stream.isUnidirectional());
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
- });
- session2.syn(new SynInfo(mainRequestHeaders, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- mainStreamLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- mainStreamLatch.countDown();
- }
- });
-
- Assert.assertTrue(mainStreamLatch.await(5, TimeUnit.SECONDS));
- Assert.assertFalse("We don't expect data to be pushed as the main request contained an if-modified-since header", pushDataLatch.await(1, TimeUnit.SECONDS));
- }
-
- private void validateHeaders(Fields headers, CountDownLatch pushSynHeadersValid)
- {
- if (validateUriHeader(headers))
- pushSynHeadersValid.countDown();
- }
-
- private boolean validateHeader(Fields headers, String name, String expectedValue)
- {
- Fields.Field header = headers.get(name);
- if (header != null && expectedValue.equals(header.getValue()))
- return true;
- System.out.println(name + " not valid! Expected: " + expectedValue + " headers received:" + headers);
- return false;
- }
-
- private boolean validateUriHeader(Fields headers)
- {
- Fields.Field uriHeader = headers.get(HTTPSPDYHeader.URI.name(version));
- if (uriHeader != null)
- if (version == SPDY.V2 && uriHeader.getValue().startsWith("http://"))
- return true;
- else if (version == SPDY.V3 && uriHeader.getValue().startsWith("/")
- && headers.get(HTTPSPDYHeader.HOST.name(version)) != null && headers.get(HTTPSPDYHeader.SCHEME.name(version)) != null)
- return true;
- System.out.println(HTTPSPDYHeader.URI.name(version) + " not valid!");
- return false;
- }
-
- private Fields createHeaders(String resource)
- {
- return createHeaders(resource, mainResource);
- }
-
- private Fields createHeaders(String resource, String referrer)
- {
- Fields associatedRequestHeaders = createHeadersWithoutReferrer(resource);
- associatedRequestHeaders.put("referer", "http://localhost:" + connector.getLocalPort() + referrer);
- return associatedRequestHeaders;
- }
-
- private Fields createHeadersWithoutReferrer(String resource)
- {
- Fields requestHeaders = new Fields();
- requestHeaders.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:16.0) " +
- "Gecko/20100101 Firefox/16.0");
- requestHeaders.put("accept-encoding", "gzip");
- requestHeaders.put(HTTPSPDYHeader.METHOD.name(version), "GET");
- requestHeaders.put(HTTPSPDYHeader.URI.name(version), resource);
- requestHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- requestHeaders.put(HTTPSPDYHeader.SCHEME.name(version), "http");
- requestHeaders.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + connector.getLocalPort());
- return requestHeaders;
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyUnitTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyUnitTest.java
deleted file mode 100644
index 3a427cefe3..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ReferrerPushStrategyUnitTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.Set;
-
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class ReferrerPushStrategyUnitTest
-{
- public static final short VERSION = SPDY.V3;
- public static final String SCHEME = "http";
- public static final String HOST = "localhost";
- public static final String MAIN_URI = "/index.html";
- public static final String METHOD = "GET";
-
- // class under test
- private ReferrerPushStrategy referrerPushStrategy = new ReferrerPushStrategy();
-
- @Mock
- Stream stream;
- @Mock
- Session session;
-
-
- @Before
- public void setup()
- {
- referrerPushStrategy.setUserAgentBlacklist(Arrays.asList(".*(?i)firefox/16.*"));
- }
-
- @Test
- public void testReferrerCallsAfterTimeoutAreNotAddedAsPushResources() throws InterruptedException
- {
- Fields requestHeaders = getBaseHeaders(VERSION);
- int referrerCallTimeout = 1000;
- referrerPushStrategy.setReferrerPushPeriod(referrerCallTimeout);
- setMockExpectations();
-
- String referrerUrl = fillPushStrategyCache(requestHeaders);
-
- // sleep to pretend that the user manually clicked on a linked resource instead the browser requesting sub
- // resources immediately
- Thread.sleep(referrerCallTimeout + 1);
-
- requestHeaders.put(HTTPSPDYHeader.URI.name(VERSION), "image2.jpg");
- requestHeaders.put("referer", referrerUrl);
- Set<String> pushResources = referrerPushStrategy.apply(stream, requestHeaders, new Fields());
- assertThat("pushResources is empty", pushResources.size(), is(0));
-
- requestHeaders.put(HTTPSPDYHeader.URI.name(VERSION), MAIN_URI);
- pushResources = referrerPushStrategy.apply(stream, requestHeaders, new Fields());
- // as the image2.jpg request has been a link and not a sub resource, we expect that pushResources.size() is
- // still 2
- assertThat("pushResources contains two elements image.jpg and style.css", pushResources.size(), is(2));
- }
-
- @Test
- public void testUserAgentFilter() throws InterruptedException
- {
- Fields requestHeaders = getBaseHeaders(VERSION);
- setMockExpectations();
-
- fillPushStrategyCache(requestHeaders);
-
- Set<String> pushResources = referrerPushStrategy.apply(stream, requestHeaders, new Fields());
- assertThat("pushResources contains two elements image.jpg and style.css as no user-agent header is present",
- pushResources.size(), is(2));
-
- requestHeaders.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4");
- pushResources = referrerPushStrategy.apply(stream, requestHeaders, new Fields());
- assertThat("pushResources contains two elements image.jpg and style.css as chrome is not blacklisted",
- pushResources.size(), is(2));
-
- requestHeaders.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:16.0) Gecko/20100101 Firefox/16.0");
- pushResources = referrerPushStrategy.apply(stream, requestHeaders, new Fields());
- assertThat("no resources are returned as we want to filter firefox", pushResources.size(), is(0));
- }
-
- private Fields getBaseHeaders(short version)
- {
- Fields requestHeaders = new Fields();
- requestHeaders.put(HTTPSPDYHeader.SCHEME.name(version), SCHEME);
- requestHeaders.put(HTTPSPDYHeader.HOST.name(version), HOST);
- requestHeaders.put(HTTPSPDYHeader.URI.name(version), MAIN_URI);
- requestHeaders.put(HTTPSPDYHeader.METHOD.name(version), METHOD);
- return requestHeaders;
- }
-
- private void setMockExpectations()
- {
- when(stream.getSession()).thenReturn(session);
- when(session.getVersion()).thenReturn(VERSION);
- }
-
- private String fillPushStrategyCache(Fields requestHeaders)
- {
- Set<String> pushResources = referrerPushStrategy.apply(stream, requestHeaders, new Fields());
- assertThat("pushResources is empty", pushResources.size(), is(0));
-
- String origin = SCHEME + "://" + HOST;
- String referrerUrl = origin + MAIN_URI;
-
- requestHeaders.put(HTTPSPDYHeader.URI.name(VERSION), "image.jpg");
- requestHeaders.put("referer", referrerUrl);
- pushResources = referrerPushStrategy.apply(stream, requestHeaders, new Fields());
- assertThat("pushResources is empty", pushResources.size(), is(0));
-
- requestHeaders.put(HTTPSPDYHeader.URI.name(VERSION), "style.css");
- pushResources = referrerPushStrategy.apply(stream, requestHeaders, new Fields());
- assertThat("pushResources is empty", pushResources.size(), is(0));
-
- requestHeaders.put(HTTPSPDYHeader.URI.name(VERSION), MAIN_URI);
- pushResources = referrerPushStrategy.apply(stream, requestHeaders, new Fields());
- assertThat("pushResources contains two elements image.jpg and style.css", pushResources.size(), is(2));
- return referrerUrl;
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SPDYTestUtils.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SPDYTestUtils.java
deleted file mode 100644
index e0a6983b1c..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SPDYTestUtils.java
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.http;
-
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-
-public class SPDYTestUtils
-{
- public static Fields createHeaders(String host, int port, short version, String httpMethod, String path)
- {
- Fields headers = new Fields();
- headers.put(HTTPSPDYHeader.METHOD.name(version), httpMethod);
- headers.put(HTTPSPDYHeader.URI.name(version), path);
- headers.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- headers.put(HTTPSPDYHeader.SCHEME.name(version), "http");
- headers.put(HTTPSPDYHeader.HOST.name(version), host + ":" + port);
- return headers;
- }
-
- public static SslContextFactory newSslContextFactory()
- {
- SslContextFactory sslContextFactory = new SslContextFactory();
- sslContextFactory.setEndpointIdentificationAlgorithm("");
- sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
- sslContextFactory.setKeyStorePassword("storepwd");
- sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
- sslContextFactory.setTrustStorePassword("storepwd");
- sslContextFactory.setProtocol("TLSv1");
- sslContextFactory.setIncludeProtocols("TLSv1");
- return sslContextFactory;
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SSLExternalServerTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SSLExternalServerTest.java
deleted file mode 100644
index 4756e1a182..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SSLExternalServerTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class SSLExternalServerTest extends AbstractHTTPSPDYTest
-{
- public SSLExternalServerTest(short version)
- {
- // Google Servers do not support SPDY/2 anymore
- super(SPDY.V3);
- }
-
- @Override
- protected SPDYClient.Factory newSPDYClientFactory(Executor threadPool)
- {
- SslContextFactory sslContextFactory = new SslContextFactory();
- // Force TLSv1
- sslContextFactory.setIncludeProtocols("TLSv1");
- sslContextFactory.setEndpointIdentificationAlgorithm("");
- return new SPDYClient.Factory(threadPool, null, sslContextFactory, 30000);
- }
-
- @Test
- @Ignore("Relies on an external server")
- public void testExternalServer() throws Exception
- {
- String host = "encrypted.google.com";
- int port = 443;
- InetSocketAddress address = new InetSocketAddress(host, port);
-
- try
- {
- // Test whether there is connectivity to avoid fail the test when offline
- Socket socket = new Socket();
- socket.connect(address, 5000);
- socket.close();
- }
- catch (IOException x)
- {
- Assume.assumeNoException(x);
- }
-
- Session session = startClient(version, address, null);
- Fields headers = new Fields();
- headers.put(HTTPSPDYHeader.SCHEME.name(version), "https");
- headers.put(HTTPSPDYHeader.HOST.name(version), host + ":" + port);
- headers.put(HTTPSPDYHeader.METHOD.name(version), "GET");
- headers.put(HTTPSPDYHeader.URI.name(version), "/");
- headers.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- final CountDownLatch latch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields headers = replyInfo.getHeaders();
- Fields.Field versionHeader = headers.get(HTTPSPDYHeader.STATUS.name(version));
- if (versionHeader != null)
- {
- Matcher matcher = Pattern.compile("(\\d{3}).*").matcher(versionHeader.getValue());
- if (matcher.matches() && Integer.parseInt(matcher.group(1)) < 400)
- latch.countDown();
- }
- }
- });
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ServerHTTPSPDYTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ServerHTTPSPDYTest.java
deleted file mode 100644
index 8012510f3f..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ServerHTTPSPDYTest.java
+++ /dev/null
@@ -1,1625 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.servlet.AsyncContext;
-import javax.servlet.AsyncEvent;
-import javax.servlet.AsyncListener;
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.server.HttpChannel;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.spdy.api.BytesDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.log.StdErrLog;
-import org.junit.Assert;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
-{
- public static final String SUSPENDED_ATTRIBUTE = ServerHTTPSPDYTest.class.getName() + ".SUSPENDED";
-
- public ServerHTTPSPDYTest(short version)
- {
- super(version);
- }
-
- @Test
- public void testSimpleGET() throws Exception
- {
- final String path = "/foo";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- assertEquals("GET", httpRequest.getMethod());
- assertEquals(path, target);
- assertEquals(path, httpRequest.getRequestURI());
- assertThat("accept-encoding is set to gzip, even if client didn't set it",
- httpRequest.getHeader("accept-encoding"), containsString("gzip"));
- assertThat(httpRequest.getHeader("host"), is("localhost:" + connector.getLocalPort()));
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getLocalPort(), version, "GET", path);
- final CountDownLatch replyLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertTrue(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertThat(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"), is(true));
- assertThat(replyHeaders.get(HttpHeader.SERVER.asString()), is(notNullValue()));
- assertThat(replyHeaders.get(HttpHeader.X_POWERED_BY.asString()), is(notNullValue()));
- replyLatch.countDown();
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithQueryString() throws Exception
- {
- final String path = "/foo";
- final String query = "p=1";
- final String uri = path + "?" + query;
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- assertEquals("GET", httpRequest.getMethod());
- assertEquals(path, target);
- assertEquals(path, httpRequest.getRequestURI());
- assertEquals(query, httpRequest.getQueryString());
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", uri);
- final CountDownLatch replyLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertTrue(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithCookies() throws Exception
- {
- final String path = "/foo";
- final String uri = path;
- final String cookie1 = "cookie1";
- final String cookie2 = "cookie2";
- final String cookie1Value = "cookie 1 value";
- final String cookie2Value = "cookie 2 value";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.addCookie(new Cookie(cookie1, cookie1Value));
- httpResponse.addCookie(new Cookie(cookie2, cookie2Value));
- assertThat("method is GET", httpRequest.getMethod(), is("GET"));
- assertThat("target is /foo", target, is(path));
- assertThat("requestUri is /foo", httpRequest.getRequestURI(), is(path));
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", uri);
- final CountDownLatch replyLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertThat("isClose is true", replyInfo.isClose(), is(true));
- Fields replyHeaders = replyInfo.getHeaders();
- assertThat("response code is 200 OK", replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue()
- .contains("200"), is(true));
- assertThat(replyInfo.getHeaders().get("Set-Cookie").getValues().get(0), is(cookie1 + "=\"" + cookie1Value +
- "\";Version=1"));
- assertThat(replyInfo.getHeaders().get("Set-Cookie").getValues().get(1), is(cookie2 + "=\"" + cookie2Value +
- "\";Version=1"));
- replyLatch.countDown();
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testHEAD() throws Exception
- {
- final String path = "/foo";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- assertEquals("HEAD", httpRequest.getMethod());
- assertEquals(path, target);
- assertEquals(path, httpRequest.getRequestURI());
- httpResponse.getWriter().write("body that shouldn't be sent on a HEAD request");
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "HEAD", path);
- final CountDownLatch replyLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertTrue(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- fail("HEAD request shouldn't send any data");
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPOSTWithDelayedContentBody() throws Exception
- {
- final String path = "/foo";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- // don't read the request body, reply immediately
- request.setHandled(true);
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "POST", path);
- headers.put("content-type", "application/x-www-form-urlencoded");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertTrue(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
- });
- stream.data(new StringDataInfo("a", false));
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- stream.data(new StringDataInfo("b", true));
- }
-
- @Test
- public void testPOSTWithParameters() throws Exception
- {
- final String path = "/foo";
- final String data = "a=1&b=2";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- assertEquals("POST", httpRequest.getMethod());
- assertEquals("1", httpRequest.getParameter("a"));
- assertEquals("2", httpRequest.getParameter("b"));
- assertNotNull(httpRequest.getRemoteHost());
- assertNotNull(httpRequest.getRemotePort());
- assertNotNull(httpRequest.getRemoteAddr());
- assertNotNull(httpRequest.getLocalPort());
- assertNotNull(httpRequest.getLocalName());
- assertNotNull(httpRequest.getLocalAddr());
- assertNotNull(httpRequest.getServerPort());
- assertNotNull(httpRequest.getServerName());
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "POST", path);
- headers.put("content-type", "application/x-www-form-urlencoded");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertTrue(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
- });
- stream.data(new StringDataInfo(data, true));
-
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPOSTWithParametersInTwoFramesTwoReads() throws Exception
- {
- final String path = "/foo";
- final String data1 = "a=1&";
- final String data2 = "b=2";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- assertEquals("POST", httpRequest.getMethod());
- assertEquals("1", httpRequest.getParameter("a"));
- assertEquals("2", httpRequest.getParameter("b"));
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "POST", path);
- headers.put("content-type", "application/x-www-form-urlencoded");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertTrue(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
- });
- // Sleep between the data frames so that they will be read in 2 reads
- stream.data(new StringDataInfo(data1, false));
- Thread.sleep(1000);
- stream.data(new StringDataInfo(data2, true));
-
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPOSTWithParametersInTwoFramesOneRead() throws Exception
- {
- final String path = "/foo";
- final String data1 = "a=1&";
- final String data2 = "b=2";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- assertEquals("POST", httpRequest.getMethod());
- assertEquals("1", httpRequest.getParameter("a"));
- assertEquals("2", httpRequest.getParameter("b"));
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "POST", path);
- headers.put("content-type", "application/x-www-form-urlencoded");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertTrue(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.toString(), replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
- });
-
- // Send the data frames consecutively, so the server reads both frames in one read
- stream.data(new StringDataInfo(data1, false));
- stream.data(new StringDataInfo(data2, true));
-
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithSmallResponseContent() throws Exception
- {
- final String data = "0123456789ABCDEF";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.setStatus(HttpServletResponse.SC_OK);
- ServletOutputStream output = httpResponse.getOutputStream();
- output.write(data.getBytes(StandardCharsets.UTF_8));
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- assertTrue(dataInfo.isClose());
- assertEquals(data, dataInfo.asString(StandardCharsets.UTF_8, true));
- dataLatch.countDown();
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithOneByteResponseContent() throws Exception
- {
- final char data = 'x';
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.setStatus(HttpServletResponse.SC_OK);
- ServletOutputStream output = httpResponse.getOutputStream();
- output.write(data);
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- assertTrue(dataInfo.isClose());
- byte[] bytes = dataInfo.asBytes(true);
- assertEquals(1, bytes.length);
- assertEquals(data, bytes[0]);
- dataLatch.countDown();
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithSmallResponseContentInTwoChunks() throws Exception
- {
- final String data1 = "0123456789ABCDEF";
- final String data2 = "FEDCBA9876543210";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.setStatus(HttpServletResponse.SC_OK);
- ServletOutputStream output = httpResponse.getOutputStream();
- output.write(data1.getBytes(StandardCharsets.UTF_8));
- output.flush();
- output.write(data2.getBytes(StandardCharsets.UTF_8));
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(2);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger replyFrames = new AtomicInteger();
- private final AtomicInteger dataFrames = new AtomicInteger();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertEquals(1, replyFrames.incrementAndGet());
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- int data = dataFrames.incrementAndGet();
- assertTrue(data >= 1 && data <= 2);
- if (data == 1)
- assertEquals(data1, dataInfo.asString(StandardCharsets.UTF_8, true));
- else
- assertEquals(data2, dataInfo.asString(StandardCharsets.UTF_8, true));
- dataLatch.countDown();
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithBigResponseContentInOneWrite() throws Exception
- {
- final byte[] data = new byte[128 * 1024];
- Arrays.fill(data, (byte)'x');
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.setStatus(HttpServletResponse.SC_OK);
- ServletOutputStream output = httpResponse.getOutputStream();
- output.write(data);
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger contentBytes = new AtomicInteger();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- contentBytes.addAndGet(dataInfo.asByteBuffer(true).remaining());
- if (dataInfo.isClose())
- {
- assertEquals(data.length, contentBytes.get());
- dataLatch.countDown();
- }
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithBigResponseContentInMultipleWrites() throws Exception
- {
- final byte[] data = new byte[4 * 1024];
- Arrays.fill(data, (byte)'x');
- final int writeTimes = 16;
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.setStatus(HttpServletResponse.SC_OK);
- ServletOutputStream output = httpResponse.getOutputStream();
- for (int i = 0; i < writeTimes; i++)
- {
- output.write(data);
- }
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger contentBytes = new AtomicInteger();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- contentBytes.addAndGet(dataInfo.asByteBuffer(true).remaining());
- if (dataInfo.isClose())
- {
- assertEquals(data.length * writeTimes, contentBytes.get());
- dataLatch.countDown();
- }
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithBigResponseContentInTwoWrites() throws Exception
- {
- final byte[] data = new byte[128 * 1024];
- Arrays.fill(data, (byte)'y');
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.setStatus(HttpServletResponse.SC_OK);
- ServletOutputStream output = httpResponse.getOutputStream();
- output.write(data);
- output.write(data);
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger contentBytes = new AtomicInteger();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- contentBytes.addAndGet(dataInfo.asByteBuffer(true).remaining());
- if (dataInfo.isClose())
- {
- assertEquals(2 * data.length, contentBytes.get());
- dataLatch.countDown();
- }
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithOutputStreamFlushedAndClosed() throws Exception
- {
- final String data = "0123456789ABCDEF";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.setStatus(HttpServletResponse.SC_OK);
- ServletOutputStream output = httpResponse.getOutputStream();
- output.write(data.getBytes(StandardCharsets.UTF_8));
- output.flush();
- output.close();
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- ByteBuffer byteBuffer = dataInfo.asByteBuffer(true);
- while (byteBuffer.hasRemaining())
- buffer.write(byteBuffer.get());
- if (dataInfo.isClose())
- {
- assertEquals(data, new String(buffer.toByteArray(), StandardCharsets.UTF_8));
- dataLatch.countDown();
- }
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithResponseResetBuffer() throws Exception
- {
- final String data1 = "0123456789ABCDEF";
- final String data2 = "FEDCBA9876543210";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.setStatus(HttpServletResponse.SC_OK);
- ServletOutputStream output = httpResponse.getOutputStream();
- // Write some
- output.write(data1.getBytes(StandardCharsets.UTF_8));
- // But then change your mind and reset the buffer
- httpResponse.resetBuffer();
- output.write(data2.getBytes(StandardCharsets.UTF_8));
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- ByteBuffer byteBuffer = dataInfo.asByteBuffer(true);
- while (byteBuffer.hasRemaining())
- buffer.write(byteBuffer.get());
- if (dataInfo.isClose())
- {
- assertEquals(data2, new String(buffer.toByteArray(), StandardCharsets.UTF_8));
- dataLatch.countDown();
- }
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithRedirect() throws Exception
- {
- final String suffix = "/redirect";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- String location = httpResponse.encodeRedirectURL(String.format("%s://%s:%d%s",
- request.getScheme(), request.getLocalAddr(), request.getLocalPort(), target + suffix));
- httpResponse.sendRedirect(location);
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger replies = new AtomicInteger();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertEquals(1, replies.incrementAndGet());
- assertTrue(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("302"));
- assertTrue(replyHeaders.get("location").getValue().endsWith(suffix));
- replyLatch.countDown();
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithSendError() throws Exception
- {
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger replies = new AtomicInteger();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertEquals(1, replies.incrementAndGet());
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("404"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- if (dataInfo.isClose())
- dataLatch.countDown();
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithException() throws Exception
- {
- StdErrLog log = StdErrLog.getLogger(HttpChannel.class);
- log.setHideStacks(true);
-
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- throw new NullPointerException("thrown_explicitly_by_the_test");
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch latch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger replies = new AtomicInteger();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertEquals(1, replies.incrementAndGet());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("500"));
- replyLatch.countDown();
- if (replyInfo.isClose())
- latch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- if (dataInfo.isClose())
- latch.countDown();
- }
- });
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(latch.await(5, TimeUnit.SECONDS));
-
- log.setHideStacks(false);
- }
-
- @Test
- public void testGETWithSmallResponseContentChunked() throws Exception
- {
- final String pangram1 = "the quick brown fox jumps over the lazy dog";
- final String pangram2 = "qualche vago ione tipo zolfo, bromo, sodio";
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- httpResponse.setHeader("Transfer-Encoding", "chunked");
- ServletOutputStream output = httpResponse.getOutputStream();
- output.write(pangram1.getBytes(StandardCharsets.UTF_8));
- httpResponse.setHeader("EXTRA", "X");
- output.flush();
- output.write(pangram2.getBytes(StandardCharsets.UTF_8));
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(2);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger replyFrames = new AtomicInteger();
- private final AtomicInteger dataFrames = new AtomicInteger();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertEquals(1, replyFrames.incrementAndGet());
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- assertTrue(replyHeaders.get("extra").getValue().contains("X"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- int count = dataFrames.incrementAndGet();
- if (count == 1)
- {
- Assert.assertFalse(dataInfo.isClose());
- assertEquals(pangram1, dataInfo.asString(StandardCharsets.UTF_8, true));
- }
- else if (count == 2)
- {
- assertTrue(dataInfo.isClose());
- assertEquals(pangram2, dataInfo.asString(StandardCharsets.UTF_8, true));
- }
- dataLatch.countDown();
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithMediumContentAsBufferByPassed() throws Exception
- {
- final byte[] data = new byte[2048];
-
- final CountDownLatch handlerLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- request.getResponse().getHttpOutput().sendContent(ByteBuffer.wrap(data));
- handlerLatch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger replyFrames = new AtomicInteger();
- private final AtomicInteger contentLength = new AtomicInteger();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertEquals(1, replyFrames.incrementAndGet());
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- contentLength.addAndGet(dataInfo.asBytes(true).length);
- if (dataInfo.isClose())
- {
- Assert.assertEquals(data.length, contentLength.get());
- dataLatch.countDown();
- }
- }
- });
- assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETWithMultipleMediumContentByPassed() throws Exception
- {
- final byte[] data = new byte[2048];
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- // The sequence of write/flush/write/write below triggers a condition where
- // HttpGenerator._bypass is set to true on the second write(), and the
- // third write causes an infinite spin loop on the third write().
- request.setHandled(true);
- OutputStream output = httpResponse.getOutputStream();
- output.write(data);
- output.flush();
- output.write(data);
- output.write(data);
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- final AtomicInteger contentLength = new AtomicInteger();
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.available());
- contentLength.addAndGet(dataInfo.length());
- if (dataInfo.isClose())
- dataLatch.countDown();
- }
- });
- assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- assertEquals(3 * data.length, contentLength.get());
- }
-
- @Test
- public void testPOSTThenSuspendRequestThenReadOneChunkThenComplete() throws Exception
- {
- final byte[] data = new byte[2000];
- final CountDownLatch latch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- final AsyncContext asyncContext = request.startAsync();
- new Thread()
- {
- @Override
- public void run()
- {
- try
- {
- readRequestData(request, data.length);
- asyncContext.complete();
- latch.countDown();
- }
- catch (IOException x)
- {
- x.printStackTrace();
- }
- }
- }.start();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "POST", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
- });
- stream.data(new BytesDataInfo(data, true));
-
- assertTrue(latch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPOSTThenSuspendExpire() throws Exception
- {
- final CountDownLatch dispatchedAgainAfterExpire = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- if (request.getAttribute(SUSPENDED_ATTRIBUTE) == Boolean.TRUE)
- {
- dispatchedAgainAfterExpire.countDown();
- }
- else
- {
- AsyncContext asyncContext = request.startAsync();
- asyncContext.setTimeout(1000);
- asyncContext.addListener(new AsyncListenerAdapter());
- request.setAttribute(SUSPENDED_ATTRIBUTE, Boolean.TRUE);
- }
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "POST", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, true, (byte)0), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
- });
-
- assertTrue("Not dispatched again after expire", dispatchedAgainAfterExpire.await(5,
- TimeUnit.SECONDS));
- assertTrue("Reply not sent", replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPOSTThenSuspendExpireWithRequestData() throws Exception
- {
- final byte[] data = new byte[2000];
- final CountDownLatch dispatchedAgainAfterExpire = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- if (request.getAttribute(SUSPENDED_ATTRIBUTE) == Boolean.TRUE)
- {
- dispatchedAgainAfterExpire.countDown();
- }
- else
- {
- readRequestData(request, data.length);
- AsyncContext asyncContext = request.startAsync();
- asyncContext.setTimeout(1000);
- asyncContext.addListener(new AsyncListenerAdapter());
- request.setAttribute(SUSPENDED_ATTRIBUTE, Boolean.TRUE);
- }
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "POST", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
- });
- stream.data(new BytesDataInfo(data, true));
-
- assertTrue("Not dispatched again after expire", dispatchedAgainAfterExpire.await(5,
- TimeUnit.SECONDS));
- assertTrue("Reply not sent", replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- private void readRequestData(Request request, int expectedDataLength) throws IOException
- {
- InputStream input = request.getInputStream();
- byte[] buffer = new byte[512];
- int read = 0;
- while (read < expectedDataLength)
- read += input.read(buffer);
- }
-
- @Test
- public void testPOSTThenSuspendRequestThenReadTwoChunksThenComplete() throws Exception
- {
- final byte[] data = new byte[2000];
- final CountDownLatch latch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- final AsyncContext asyncContext = request.startAsync();
- new Thread()
- {
- @Override
- public void run()
- {
- try
- {
- InputStream input = request.getInputStream();
- byte[] buffer = new byte[512];
- int read = 0;
- while (read < 2 * data.length)
- read += input.read(buffer);
- asyncContext.complete();
- latch.countDown();
- }
- catch (IOException x)
- {
- x.printStackTrace();
- }
- }
- }.start();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "POST", "/foo");
- final CountDownLatch replyLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- replyLatch.countDown();
- }
- });
- stream.data(new BytesDataInfo(data, false));
- stream.data(new BytesDataInfo(data, true));
-
- assertTrue(latch.await(5, TimeUnit.SECONDS));
- assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPOSTThenSuspendRequestThenResumeThenRespond() throws Exception
- {
- final byte[] data = new byte[1000];
- final CountDownLatch latch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- if (request.getAttribute(SUSPENDED_ATTRIBUTE) == Boolean.TRUE)
- {
- OutputStream output = httpResponse.getOutputStream();
- output.write(data);
- }
- else
- {
- final AsyncContext asyncContext = request.startAsync();
- request.setAttribute(SUSPENDED_ATTRIBUTE, Boolean.TRUE);
- InputStream input = request.getInputStream();
- byte[] buffer = new byte[256];
- int read = 0;
- while (read < data.length)
- read += input.read(buffer);
- new Thread()
- {
- @Override
- public void run()
- {
- try
- {
- TimeUnit.SECONDS.sleep(1);
- asyncContext.dispatch();
- latch.countDown();
- }
- catch (InterruptedException x)
- {
- x.printStackTrace();
- }
- }
- }.start();
- }
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "POST", "/foo");
- final CountDownLatch responseLatch = new CountDownLatch(2);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- responseLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- if (dataInfo.isClose())
- responseLatch.countDown();
- }
- });
- stream.data(new BytesDataInfo(data, true));
-
- assertTrue(latch.await(5, TimeUnit.SECONDS));
- assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPOSTThenResponseWithoutReadingContent() throws Exception
- {
- final byte[] data = new byte[1000];
- final CountDownLatch latch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- latch.countDown();
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "POST", "/foo");
- final CountDownLatch responseLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields replyHeaders = replyInfo.getHeaders();
- assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"));
- responseLatch.countDown();
- }
- });
- stream.data(new BytesDataInfo(data, false));
- stream.data(new BytesDataInfo(5, TimeUnit.SECONDS, data, true));
-
- assertTrue(latch.await(5, TimeUnit.SECONDS));
- assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testIdleTimeout() throws Exception
- {
- final int idleTimeout = 500;
- final CountDownLatch timeoutReceivedLatch = new CountDownLatch(1);
-
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- try
- {
- Thread.sleep(2 * idleTimeout);
- }
- catch (InterruptedException e)
- {
- throw new RuntimeException(e);
- }
- request.setHandled(true);
- }
- }, 30000), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/");
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, true, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- assertThat("we got a TimeoutException", x, instanceOf(TimeoutException.class));
- timeoutReceivedLatch.countDown();
- }
- });
- stream.setIdleTimeout(idleTimeout);
-
- assertThat("idle timeout hit", timeoutReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testIdleTimeoutSetOnConnectionOnly() throws Exception
- {
- final int idleTimeout = 500;
- final CountDownLatch timeoutReceivedLatch = new CountDownLatch(1);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- try
- {
- Thread.sleep(2 * idleTimeout);
- }
- catch (InterruptedException e)
- {
- throw new RuntimeException(e);
- }
- request.setHandled(true);
- }
- }, idleTimeout), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/");
- session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, true, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- assertThat("we got a TimeoutException", x, instanceOf(TimeoutException.class));
- timeoutReceivedLatch.countDown();
- }
- });
-
- assertThat("idle timeout hit", timeoutReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testSingleStreamIdleTimeout() throws Exception
- {
- final int idleTimeout = 500;
- final CountDownLatch timeoutReceivedLatch = new CountDownLatch(1);
- final CountDownLatch replyReceivedLatch = new CountDownLatch(3);
- Session session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- if ("true".equals(request.getHeader("slow")))
- {
- try
- {
- Thread.sleep(2 * idleTimeout);
- }
- catch (InterruptedException e)
- {
- throw new RuntimeException(e);
- }
- }
- request.setHandled(true);
- }
- }, idleTimeout), null);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/");
- Fields slowHeaders = SPDYTestUtils.createHeaders("localhost", connector.getPort(), version, "GET", "/");
- slowHeaders.add("slow", "true");
- sendSingleRequestThatIsNotExpectedToTimeout(replyReceivedLatch, session, headers);
- session.syn(new SynInfo(5, TimeUnit.SECONDS, slowHeaders, true, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onFailure(Stream stream, Throwable x)
- {
- assertThat("we got a TimeoutException", x, instanceOf(TimeoutException.class));
- timeoutReceivedLatch.countDown();
- }
- });
- Thread.sleep(idleTimeout / 2);
- sendSingleRequestThatIsNotExpectedToTimeout(replyReceivedLatch, session, headers);
- Thread.sleep(idleTimeout / 2);
- sendSingleRequestThatIsNotExpectedToTimeout(replyReceivedLatch, session, headers);
- assertThat("idle timeout hit", timeoutReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("received replies on 3 non idle requests", replyReceivedLatch.await(5, TimeUnit.SECONDS),
- is(true));
- }
-
- private void sendSingleRequestThatIsNotExpectedToTimeout(final CountDownLatch replyReceivedLatch, Session session, Fields headers) throws ExecutionException, InterruptedException, TimeoutException
- {
- session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, true, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- replyReceivedLatch.countDown();
- }
- });
- }
-
- private class AsyncListenerAdapter implements AsyncListener
- {
- @Override
- public void onStartAsync(AsyncEvent event) throws IOException
- {
- }
-
- @Override
- public void onComplete(AsyncEvent event) throws IOException
- {
- }
-
- @Override
- public void onTimeout(AsyncEvent event) throws IOException
- {
- event.getAsyncContext().dispatch();
- }
-
- @Override
- public void onError(AsyncEvent event) throws IOException
- {
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SimpleHTTPBenchmarkTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SimpleHTTPBenchmarkTest.java
deleted file mode 100644
index 76740d6afc..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/SimpleHTTPBenchmarkTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.http;
-
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.hamcrest.CoreMatchers;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-@Ignore("So far only used for testing performance tweaks. So no need to run it in a build")
-public class SimpleHTTPBenchmarkTest extends AbstractHTTPSPDYTest
-{
- private static final Logger LOG = Log.getLogger(SimpleHTTPBenchmarkTest.class);
- private final int dataSize = 4096 * 100;
- private Session session;
- private int requestCount = 100;
-
- public SimpleHTTPBenchmarkTest(short version)
- {
- super(version);
- }
-
- @Before
- public void setUp() throws Exception
- {
- final byte[] data = new byte[dataSize];
- new Random().nextBytes(data);
- session = startClient(version, startHTTPServer(version, new AbstractHandler()
- {
- @Override
- public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
- throws IOException, ServletException
- {
- request.setHandled(true);
- assertEquals("GET", httpRequest.getMethod());
- assertThat("accept-encoding is set to gzip, even if client didn't set it",
- httpRequest.getHeader("accept-encoding"), containsString("gzip"));
- assertThat(httpRequest.getHeader("host"), is("localhost:" + connector.getLocalPort()));
- httpResponse.getOutputStream().write(data);
- }
- }, 0), null);
- }
-
- @Test
- public void testRunBenchmark() throws Exception
- {
- long overallStart = System.nanoTime();
- int iterations = 20;
- for (int j = 0; j < iterations; j++)
- {
- long start = System.nanoTime();
- for (int i = 0; i < requestCount; i++)
- sendGetRequestWithData();
- long timeElapsed = System.nanoTime() - start;
- LOG.info("Requests with {}b response took: {}ms", dataSize, timeElapsed / 1000 / 1000);
- }
- long timeElapsedOverall = (System.nanoTime() - overallStart) / 1000 / 1000;
- LOG.info("Time elapsed overall: {}ms avg: {}ms", timeElapsedOverall, timeElapsedOverall / iterations);
- }
-
- private void sendGetRequest() throws Exception
- {
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final String path = "/foo";
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getLocalPort(), version, "GET", path);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertTrue(replyInfo.isClose());
- Fields replyHeaders = replyInfo.getHeaders();
- assertThat(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"), CoreMatchers.is(true));
- assertThat(replyHeaders.get(HttpHeader.SERVER.asString()), CoreMatchers.is(notNullValue()));
- assertThat(replyHeaders.get(HttpHeader.X_POWERED_BY.asString()), CoreMatchers.is(notNullValue()));
- replyLatch.countDown();
- }
- });
-
- assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- private void sendGetRequestWithData() throws Exception
- {
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- final String path = "/foo";
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", connector.getLocalPort(), version, "GET", path);
- session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields replyHeaders = replyInfo.getHeaders();
- assertThat(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version)).getValue().contains("200"), CoreMatchers.is(true));
- assertThat(replyHeaders.get(HttpHeader.SERVER.asString()), CoreMatchers.is(notNullValue()));
- assertThat(replyHeaders.get(HttpHeader.X_POWERED_BY.asString()), CoreMatchers.is(notNullValue()));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.available());
- if (dataInfo.isClose())
- dataLatch.countDown();
- }
- });
-
- assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPToSPDYTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPToSPDYTest.java
deleted file mode 100644
index c1a3fa7084..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPToSPDYTest.java
+++ /dev/null
@@ -1,408 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.util.StringContentProvider;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.spdy.api.BytesDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
-import org.eclipse.jetty.spdy.server.SPDYServerConnector;
-import org.eclipse.jetty.toolchain.test.TestTracker;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-@RunWith(Parameterized.class)
-public class ProxyHTTPToSPDYTest
-{
- @Parameterized.Parameters
- public static Collection<Short[]> parameters()
- {
- return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
- }
-
- @Rule
- public final TestTracker tracker = new TestTracker();
- private final short version;
- private HttpClient httpClient;
- private HttpClient httpClient2;
- private SPDYClient.Factory factory;
- private Server server;
- private Server proxy;
- private ServerConnector proxyConnector;
-
- public ProxyHTTPToSPDYTest(short version)
- {
- this.version = version;
- }
-
- protected InetSocketAddress startServer(ServerSessionFrameListener listener) throws Exception
- {
- server = new Server();
- SPDYServerConnector serverConnector = new SPDYServerConnector(server, listener);
- serverConnector.addConnectionFactory(new SPDYServerConnectionFactory(version, listener));
- serverConnector.setPort(0);
- server.addConnector(serverConnector);
- server.start();
- return new InetSocketAddress("localhost", serverConnector.getLocalPort());
- }
-
- protected InetSocketAddress startProxy(InetSocketAddress address) throws Exception
- {
- proxy = new Server();
- ProxyEngineSelector proxyEngineSelector = new ProxyEngineSelector();
- SPDYProxyEngine spdyProxyEngine = new SPDYProxyEngine(factory);
- proxyEngineSelector.putProxyEngine("spdy/" + version, spdyProxyEngine);
- proxyEngineSelector.putProxyServerInfo("localhost", new ProxyEngineSelector.ProxyServerInfo("spdy/" + version, address.getHostName(), address.getPort()));
- proxyConnector = new HTTPSPDYProxyServerConnector(proxy, proxyEngineSelector);
- proxyConnector.setPort(9999);
- proxy.addConnector(proxyConnector);
- proxy.start();
- return new InetSocketAddress("localhost", proxyConnector.getLocalPort());
- }
-
- @Before
- public void init() throws Exception
- {
- factory = new SPDYClient.Factory();
- factory.start();
- httpClient = new HttpClient();
- httpClient.start();
- httpClient2 = new HttpClient();
- httpClient2.start();
- }
-
- @After
- public void destroy() throws Exception
- {
- httpClient.stop();
- httpClient2.stop();
- if (server != null)
- {
- server.stop();
- server.join();
- }
- if (proxy != null)
- {
- proxy.stop();
- proxy.join();
- }
- factory.stop();
- }
-
- @Test
- public void testClosingClientDoesNotCloseServer() throws Exception
- {
- final CountDownLatch closeLatch = new CountDownLatch(1);
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Fields responseHeaders = new Fields();
- responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
- stream.reply(new ReplyInfo(responseHeaders, true), new Callback.Adapter());
- return null;
- }
-
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- closeLatch.countDown();
- }
- }));
-
- Request request = httpClient.newRequest("localhost", proxyAddress.getPort()).method("GET");
- request.header("Connection", "close");
- ContentResponse response = request.send();
-
- assertThat("response status is 200 OK", response.getStatus(), is(200));
-
- // Must not close, other clients may still be connected
- Assert.assertFalse(closeLatch.await(1, TimeUnit.SECONDS));
- }
-
- @Test
- public void testGETThenNoContentFromTwoClients() throws Exception
- {
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Assert.assertTrue(synInfo.isClose());
- Fields requestHeaders = synInfo.getHeaders();
- Assert.assertNotNull(requestHeaders.get("via"));
-
- Fields responseHeaders = new Fields();
- responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
- ReplyInfo replyInfo = new ReplyInfo(responseHeaders, true);
- stream.reply(replyInfo, new Callback.Adapter());
- return null;
- }
- }));
-
- ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET)
- .send();
- assertThat("response code is 200 OK", response.getStatus(), is(200));
-
- // Perform another request with another client
- ContentResponse response2 = httpClient2.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET)
- .send();
- assertThat("response2 code is 200 OK", response2.getStatus(), is(200));
- }
-
- @Test
- public void testHEADRequest() throws Exception
- {
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Assert.assertTrue(synInfo.isClose());
- Fields requestHeaders = synInfo.getHeaders();
- Assert.assertNotNull(requestHeaders.get("via"));
-
- Fields responseHeaders = new Fields();
- responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
- ReplyInfo replyInfo = new ReplyInfo(responseHeaders, true);
- stream.reply(replyInfo, new Callback.Adapter());
-
- return null;
- }
- }));
- ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.HEAD).send();
- assertThat("response code is 200 OK", response.getStatus(), is(200));
- }
-
- @Test
- public void testGETThenSmallResponseContent() throws Exception
- {
- final byte[] data = "0123456789ABCDEF".getBytes(StandardCharsets.UTF_8);
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Assert.assertTrue(synInfo.isClose());
- Fields requestHeaders = synInfo.getHeaders();
- Assert.assertNotNull(requestHeaders.get("via"));
-
- Fields responseHeaders = new Fields();
- responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
- responseHeaders.put("content-length", String.valueOf(data.length));
-
- ReplyInfo replyInfo = new ReplyInfo(responseHeaders, false);
- stream.reply(replyInfo, new Callback.Adapter());
- stream.data(new BytesDataInfo(data, true), new Callback.Adapter());
-
- return null;
- }
- }));
-
- ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET)
- .send();
- assertThat("response code is 200 OK", response.getStatus(), is(200));
- assertThat(Arrays.equals(response.getContent(), data), is(true));
-
- // Perform another request so that we are sure we reset the states of parsers and generators
- ContentResponse response2 = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET)
- .send();
- assertThat("response2 code is 200 OK", response2.getStatus(), is(200));
- assertThat(Arrays.equals(response2.getContent(), data), is(true));
- }
-
- @Test
- public void testPOSTWithSmallRequestContentThenRedirect() throws Exception
- {
- final String data = "0123456789ABCDEF";
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- {
- Fields headers = new Fields();
- headers.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- headers.put(HTTPSPDYHeader.STATUS.name(version), "303 See Other");
- headers.put(HttpHeader.LOCATION.asString(),"http://other.location");
- stream.reply(new ReplyInfo(headers, true), new Callback.Adapter());
- }
- }
- };
- }
- }));
-
- ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.POST).content(new
- StringContentProvider(data)).followRedirects(false).send();
- assertThat("response code is 303", response.getStatus(), is(303));
-
- // Perform another request so that we are sure we reset the states of parsers and generators
- ContentResponse response2 = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod
- .POST).content(new StringContentProvider(data)).followRedirects(false).send();
- assertThat("response2 code is 303", response2.getStatus(), is(303));
- }
-
- @Test
- public void testPOSTWithSmallRequestContentThenSmallResponseContent() throws Exception
- {
- String dataString = "0123456789ABCDEF";
- final byte[] data = dataString.getBytes(StandardCharsets.UTF_8);
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- {
- Fields responseHeaders = new Fields();
- responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
- responseHeaders.put("content-length", String.valueOf(data.length));
- ReplyInfo replyInfo = new ReplyInfo(responseHeaders, false);
- stream.reply(replyInfo, new Callback.Adapter());
- stream.data(new BytesDataInfo(data, true), new Callback.Adapter());
- }
- }
- };
- }
- }));
-
- ContentResponse response = httpClient.POST("http://localhost:" + proxyAddress.getPort() + "/").content(new
- StringContentProvider(dataString)).send();
- assertThat("response status is 200 OK", response.getStatus(), is(200));
- assertThat("response content matches expected dataString", response.getContentAsString(), is(dataString));
-
- // Perform another request so that we are sure we reset the states of parsers and generators
- response = httpClient.POST("http://localhost:" + proxyAddress.getPort() + "/").content(new
- StringContentProvider(dataString)).send();
- assertThat("response status is 200 OK", response.getStatus(), is(200));
- assertThat("response content matches expected dataString", response.getContentAsString(), is(dataString));
- }
-
- @Test
- public void testGETThenSPDYPushIsIgnored() throws Exception
- {
- final byte[] data = "0123456789ABCDEF".getBytes(StandardCharsets.UTF_8);
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Fields responseHeaders = new Fields();
- responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
-
- Fields pushHeaders = new Fields();
- pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/push");
- stream.push(new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Promise.Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream pushStream)
- {
- pushStream.data(new BytesDataInfo(data, true), new Callback.Adapter());
- }
- });
-
- stream.reply(new ReplyInfo(responseHeaders, true), new Callback.Adapter());
- return null;
- }
- }));
-
- ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET).send();
- assertThat("response code is 200 OK", response.getStatus(), is(200));
- }
-
- @Test
- public void testGETThenReset() throws Exception
- {
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Assert.assertTrue(synInfo.isClose());
- Fields requestHeaders = synInfo.getHeaders();
- Assert.assertNotNull(requestHeaders.get("via"));
-
- stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new Callback.Adapter());
-
- return null;
- }
- }));
-
- ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET).send();
- assertThat("response code is 502 Gateway Error", response.getStatus(), is(502));
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPLoadTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPLoadTest.java
deleted file mode 100644
index a50f1607d9..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPLoadTest.java
+++ /dev/null
@@ -1,319 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.NegotiatingServerConnectionFactory;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.handler.DefaultHandler;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
-import org.eclipse.jetty.toolchain.test.TestTracker;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import static junit.framework.Assert.fail;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.junit.Assert.assertThat;
-
-@Ignore
-@RunWith(value = Parameterized.class)
-public abstract class ProxySPDYToHTTPLoadTest
-{
- private static final Logger LOG = Log.getLogger(ProxySPDYToHTTPLoadTest.class);
-
- @Parameterized.Parameters
- public static Collection<Short[]> parameters()
- {
- return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
- }
-
- @Rule
- public final TestTracker tracker = new TestTracker();
- private final short version;
- private final NegotiatingServerConnectionFactory negotiator;
- private final String server1String = "server1";
- private final String server2String = "server2";
- private SPDYClient.Factory factory;
- private Server server1;
- private Server server2;
- private Server proxy;
- private ServerConnector proxyConnector;
- private SslContextFactory sslContextFactory = SPDYTestUtils.newSslContextFactory();
-
- public ProxySPDYToHTTPLoadTest(short version, NegotiatingServerConnectionFactory negotiator)
- {
- this.version = version;
- this.negotiator = negotiator;
- }
-
- @Before
- public void init() throws Exception
- {
- // change the ports if you want to trace the network traffic
- server1 = startServer(new TestServerHandler(server1String, null), 0);
- server2 = startServer(new TestServerHandler(server2String, null), 0);
- factory = new SPDYClient.Factory(sslContextFactory);
- factory.start();
- }
-
- @After
- public void destroy() throws Exception
- {
- stopServer(server1);
- stopServer(server2);
- if (proxy != null)
- {
- proxy.stop();
- proxy.join();
- }
- factory.stop();
- }
-
- private void stopServer(Server server) throws Exception
- {
- if (server != null)
- {
- server.stop();
- server.join();
- }
- }
-
- protected Server startServer(Handler handler, int port) throws Exception
- {
- QueuedThreadPool threadPool = new QueuedThreadPool(256);
- threadPool.setName("upstreamServerQTP");
- Server server = new Server(threadPool);
- ServerConnector connector = new ServerConnector(server);
- connector.setPort(port);
- server.setHandler(handler);
- server.addConnector(connector);
- server.start();
- return server;
- }
-
- private InetSocketAddress getServerAddress(Server server)
- {
- return new InetSocketAddress("localhost", ((ServerConnector)server.getConnectors()[0]).getLocalPort());
- }
-
- protected InetSocketAddress startProxy(InetSocketAddress server1, InetSocketAddress server2,
- long proxyConnectorTimeout, long proxyEngineTimeout) throws Exception
- {
- QueuedThreadPool threadPool = new QueuedThreadPool(256);
- threadPool.setName("proxyQTP");
- proxy = new Server(threadPool);
- ProxyEngineSelector proxyEngineSelector = new ProxyEngineSelector();
- HttpClient httpClient = new HttpClient();
- httpClient.start();
- httpClient.setIdleTimeout(proxyEngineTimeout);
- HTTPProxyEngine httpProxyEngine = new HTTPProxyEngine(httpClient);
- proxyEngineSelector.putProxyEngine("http/1.1", httpProxyEngine);
-
- proxyEngineSelector.putProxyServerInfo("localhost", new ProxyEngineSelector.ProxyServerInfo("http/1.1",
- server1.getHostName(), server1.getPort()));
- // server2 will be available at two different ProxyServerInfos with different hosts
- proxyEngineSelector.putProxyServerInfo("127.0.0.1", new ProxyEngineSelector.ProxyServerInfo("http/1.1",
- server2.getHostName(), server2.getPort()));
- proxyEngineSelector.putProxyServerInfo("127.0.0.2", new ProxyEngineSelector.ProxyServerInfo("http/1.1",
- server2.getHostName(), server2.getPort()));
-
- proxyConnector = new HTTPSPDYProxyServerConnector(proxy, sslContextFactory, new HttpConfiguration(), proxyEngineSelector, negotiator);
- proxyConnector.setPort(0);
- proxyConnector.setIdleTimeout(proxyConnectorTimeout);
- proxy.addConnector(proxyConnector);
- proxy.start();
- return new InetSocketAddress("localhost", proxyConnector.getLocalPort());
- }
-
- @Test
- public void testSimpleLoadTest() throws Exception
- {
- final InetSocketAddress proxyAddress = startProxy(getServerAddress(server1), getServerAddress(server2), 30000,
- 30000);
-
- final int requestsPerClient = 50;
-
- ExecutorService executorService = Executors.newFixedThreadPool(3);
-
- Runnable client1 = createClientRunnable(proxyAddress, requestsPerClient, server1String, "localhost");
- Runnable client2 = createClientRunnable(proxyAddress, requestsPerClient, server2String, "127.0.0.1");
- Runnable client3 = createClientRunnable(proxyAddress, requestsPerClient, server2String, "127.0.0.2");
-
- List<Future> futures = new ArrayList<>();
-
- futures.add(executorService.submit(client1));
- futures.add(executorService.submit(client2));
- futures.add(executorService.submit(client3));
-
- for (Future future : futures)
- {
- future.get(60, TimeUnit.SECONDS);
- }
- }
-
- private Runnable createClientRunnable(final InetSocketAddress proxyAddress, final int requestsPerClient,
- final String serverIdentificationString, final String serverHost)
- {
- Runnable client = new Runnable()
- {
- @Override
- public void run()
- {
- try
- {
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
- for (int i = 0; i < requestsPerClient; i++)
- {
- sendSingleClientRequest(proxyAddress, client, serverIdentificationString, serverHost);
- }
- }
- catch (InterruptedException | ExecutionException | TimeoutException e)
- {
- e.printStackTrace();
- fail();
- }
- }
- };
- return client;
- }
-
- private void sendSingleClientRequest(InetSocketAddress proxyAddress, Session client, final String serverIdentificationString, String serverHost) throws ExecutionException, InterruptedException, TimeoutException
- {
- final String data = UUID.randomUUID().toString();
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
-
- Fields headers = SPDYTestUtils.createHeaders(serverHost, proxyAddress.getPort(), version, "POST", "/");
-
- Stream stream = client.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
- {
- private final ByteArrayOutputStream result = new ByteArrayOutputStream();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- LOG.debug("Got reply: {}", replyInfo);
- Fields headers = replyInfo.getHeaders();
- assertThat("response comes from the given server", headers.get(serverIdentificationString),
- is(notNullValue()));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- result.write(dataInfo.asBytes(true), 0, dataInfo.length());
- if (dataInfo.isClose())
- {
- LOG.debug("Got last dataFrame: {}", dataInfo);
- assertThat("received data matches send data", result.toString(), is(data));
- dataLatch.countDown();
- }
- }
- });
-
- stream.data(new StringDataInfo(data, true), new Callback.Adapter());
-
- assertThat("reply has been received", replyLatch.await(15, TimeUnit.SECONDS), is(true));
- assertThat("data has been received", dataLatch.await(15, TimeUnit.SECONDS), is(true));
- LOG.debug("Successfully received response");
- }
-
- private class TestServerHandler extends DefaultHandler
- {
- private final String responseHeader;
- private final byte[] responseData;
-
- private TestServerHandler(String responseHeader, byte[] responseData)
- {
- this.responseHeader = responseHeader;
- this.responseData = responseData;
- }
-
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request,
- HttpServletResponse response) throws IOException, ServletException
- {
- assertThat("Via Header is set", baseRequest.getHeader("X-Forwarded-For"), is(notNullValue()));
- assertThat("X-Forwarded-For Header is set", baseRequest.getHeader("X-Forwarded-For"),
- is(notNullValue()));
- assertThat("X-Forwarded-Host Header is set", baseRequest.getHeader("X-Forwarded-Host"),
- is(notNullValue()));
- assertThat("X-Forwarded-Proto Header is set", baseRequest.getHeader("X-Forwarded-Proto"),
- is(notNullValue()));
- assertThat("X-Forwarded-Server Header is set", baseRequest.getHeader("X-Forwarded-Server"),
- is(notNullValue()));
- baseRequest.setHandled(true);
-
- IO.copy(request.getInputStream(), response.getOutputStream());
-
- if (responseHeader != null)
- response.addHeader(responseHeader, "bar");
- if (responseData != null)
- response.getOutputStream().write(responseData);
- }
- }
-
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPTest.java
deleted file mode 100644
index d12938309d..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPTest.java
+++ /dev/null
@@ -1,545 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HttpChannel;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.handler.DefaultHandler;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.PingInfo;
-import org.eclipse.jetty.spdy.api.PingResultInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
-import org.eclipse.jetty.toolchain.test.TestTracker;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.StdErrLog;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertThat;
-
-@RunWith(value = Parameterized.class)
-public abstract class ProxySPDYToHTTPTest
-{
- @Parameterized.Parameters
- public static Collection<Short[]> parameters()
- {
- return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
- }
-
- @Rule
- public final TestTracker tracker = new TestTracker();
- private final short version;
- private SPDYClient.Factory factory;
- private Server server;
- private Server proxy;
- private ServerConnector proxyConnector;
- private SslContextFactory sslContextFactory = SPDYTestUtils.newSslContextFactory();
-
- public ProxySPDYToHTTPTest(short version)
- {
- this.version = version;
- }
-
- protected InetSocketAddress startServer(Handler handler) throws Exception
- {
- server = new Server();
- ServerConnector connector = new ServerConnector(server);
- server.setHandler(handler);
- server.addConnector(connector);
- server.start();
- return new InetSocketAddress("localhost", connector.getLocalPort());
- }
-
- protected InetSocketAddress startProxy(InetSocketAddress address, long proxyConnectorTimeout, long proxyEngineTimeout) throws Exception
- {
- proxy = new Server();
- ProxyEngineSelector proxyEngineSelector = new ProxyEngineSelector();
- HttpClient httpClient = new HttpClient();
- httpClient.start();
- httpClient.setIdleTimeout(proxyEngineTimeout);
- HTTPProxyEngine httpProxyEngine = new HTTPProxyEngine(httpClient);
- proxyEngineSelector.putProxyEngine("http/1.1", httpProxyEngine);
- proxyEngineSelector.putProxyServerInfo("localhost", new ProxyEngineSelector.ProxyServerInfo("http/1.1", address.getHostName(), address.getPort()));
- proxyConnector = new HTTPSPDYProxyServerConnector(proxy, sslContextFactory, proxyEngineSelector);
- proxyConnector.setPort(0);
- proxyConnector.setIdleTimeout(proxyConnectorTimeout);
- proxy.addConnector(proxyConnector);
- proxy.start();
- return new InetSocketAddress("localhost", proxyConnector.getLocalPort());
- }
-
- @Before
- public void init() throws Exception
- {
- factory = new SPDYClient.Factory(sslContextFactory);
- factory.start();
- }
-
- @After
- public void destroy() throws Exception
- {
- if (server != null)
- {
- server.stop();
- server.join();
- }
- if (proxy != null)
- {
- proxy.stop();
- proxy.join();
- }
- factory.stop();
- ((StdErrLog)Log.getLogger(HttpChannel.class)).setHideStacks(false);
- }
-
- @Test
- public void testSYNThenREPLY() throws Exception
- {
- final String header = "foo";
-
- InetSocketAddress proxyAddress = startProxy(startServer(new TestServerHandler(header, null)), 30000, 30000);
-
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "GET", "/");
- headers.put(header, "bar");
- headers.put("connection", "close");
-
- client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields headers = replyInfo.getHeaders();
- assertThat("Version header is set", headers.get(HTTPSPDYHeader.VERSION.name(version)), is(notNullValue()));
- assertThat("Custom set header foo is set on response", headers.get(header), is(notNullValue()));
- assertThat("HOP headers like connection are removed before forwarding",
- headers.get("connection"), is(nullValue()));
- replyLatch.countDown();
- }
- });
-
- assertThat("Reply is send to SPDY client", replyLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testSYNThenREPLYAndDATA() throws Exception
- {
- final byte[] data = "0123456789ABCDEF".getBytes(StandardCharsets.UTF_8);
- final String header = "foo";
-
- InetSocketAddress proxyAddress = startProxy(startServer(new TestServerHandler(header, data)), 30000, 30000);
-
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "GET", "/");
- headers.put(header, "bar");
- headers.put("connection", "close");
-
- client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final ByteArrayOutputStream result = new ByteArrayOutputStream();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields headers = replyInfo.getHeaders();
- assertThat("Trailer header has been filtered by proxy", headers.get("trailer"),
- is(nullValue()));
- assertThat("custom header exists in response", headers.get(header), is(notNullValue()));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- result.write(dataInfo.asBytes(true), 0, dataInfo.length());
- if (dataInfo.isClose())
- {
- assertThat("received data matches send data", result.toByteArray(), is(data));
- dataLatch.countDown();
- }
- }
- });
-
- assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testHttpServerCommitsResponseTwice() throws Exception
- {
- final long timeout = 1000;
-
- InetSocketAddress proxyAddress = startProxy(startServer(new DefaultHandler()
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- response.addHeader("some response", "header");
- response.flushBuffer();
- try
- {
- Thread.sleep(timeout * 2);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
-
- }
- }), 30000, timeout);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch resetLatch = new CountDownLatch(1);
-
- Session client = factory.newSPDYClient(version).connect(proxyAddress, new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onRst(Session session, RstInfo rstInfo)
- {
- resetLatch.countDown();
- }
- });
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "GET", "/");
- headers.put("connection", "close");
-
- client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- replyLatch.countDown();
- }
- });
-
- assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("stream is reset", resetLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testHttpServerSendsRedirect() throws Exception
- {
- InetSocketAddress proxyAddress = startProxy(startServer(new DefaultHandler()
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- baseRequest.setHandled(true);
- response.setStatus(HttpServletResponse.SC_FOUND);
- response.setHeader("Location", "http://doesnot.exist");
- }
- }), 30000, 30000);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
-
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
- Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "GET", "/");
-
- client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- assertThat("Status code is 302", replyInfo.getHeaders().get(HTTPSPDYHeader.STATUS.name(version)).getValue(),
- is("302"));
- assertThat("Location header has been received", replyInfo.getHeaders().get("Location"), is(notNullValue()));
- replyLatch.countDown();
- }
- });
-
- assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testSYNWithRequestContentThenREPLYAndDATA() throws Exception
- {
- final String data = "0123456789ABCDEF";
- final String header = "foo";
-
- InetSocketAddress proxyAddress = startProxy(startServer(new TestServerHandler(header, null)), 30000, 30000);
-
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "POST", "/");
- headers.put(header, "bar");
- headers.put("connection", "close");
-
- Stream stream = client.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
- {
- private final ByteArrayOutputStream result = new ByteArrayOutputStream();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields headers = replyInfo.getHeaders();
- assertThat("custom header exists in response", headers.get(header), is(notNullValue()));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- result.write(dataInfo.asBytes(true), 0, dataInfo.length());
- if (dataInfo.isClose())
- {
- assertThat("received data matches send data", data, is(result.toString()));
- dataLatch.countDown();
- }
- }
- });
-
- stream.data(new StringDataInfo(data, true), new Callback.Adapter());
-
- assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testSYNWithSplitRequestContentThenREPLYAndDATA() throws Exception
- {
- final String data = "0123456789ABCDEF";
- final String data2 = "ABCDEF";
- final String header = "foo";
-
- InetSocketAddress proxyAddress = startProxy(startServer(new TestServerHandler(header, null)), 30000, 30000);
-
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "POST", "/");
- headers.put(header, "bar");
- headers.put("connection", "close");
-
- Stream stream = client.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
- {
- private final ByteArrayOutputStream result = new ByteArrayOutputStream();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields headers = replyInfo.getHeaders();
- assertThat("custom header exists in response", headers.get(header), is(notNullValue()));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- result.write(dataInfo.asBytes(true), 0, dataInfo.length());
- if (dataInfo.isClose())
- {
- assertThat("received data matches send data", result.toString(), is(data + data2));
- dataLatch.countDown();
- }
- }
- });
-
- stream.data(new StringDataInfo(data, false), new Callback.Adapter());
- stream.data(new StringDataInfo(data2, true), new Callback.Adapter());
-
- assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testClientTimeout() throws Exception
- {
- long timeout = 1000;
-
- InetSocketAddress proxyAddress = startProxy(startServer(new TestServerHandler(null, null)), timeout, 30000);
-
- final CountDownLatch goAwayLatch = new CountDownLatch(1);
-
- Session client = factory.newSPDYClient(version).connect(proxyAddress, new SessionFrameListener.Adapter()
- {
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayReceivedInfo)
- {
- goAwayLatch.countDown();
- }
- });
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "POST", "/");
- ((StdErrLog)Log.getLogger(HttpChannel.class)).setHideStacks(true);
- client.syn(new SynInfo(headers, false), null);
- assertThat("goAway has been received by proxy", goAwayLatch.await(2 * timeout, TimeUnit.MILLISECONDS),
- is(true));
- }
-
- @Test
- public void testServerTimeout() throws Exception
- {
- final int timeout = 1000;
- final String header = "foo";
-
- InetSocketAddress proxyAddress = startProxy(startServer(new DefaultHandler()
- {
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
- {
- try
- {
- Thread.sleep(2 * timeout);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- }
- }), 30000, timeout);
-
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "POST", "/");
- headers.put(header, "bar");
- headers.put("connection", "close");
-
- client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields headers = replyInfo.getHeaders();
- assertThat("status is 504", headers.get(HTTPSPDYHeader.STATUS.name(version)).getValue(), is("504"));
- replyLatch.countDown();
- }
-
- });
-
- assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testPING() throws Exception
- {
- // PING is per hop, and it does not carry the information to which server to ping to
- // We just verify that it works
-
- InetSocketAddress proxyAddress = startProxy(startServer(null), 30000, 30000);
- proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version));
-
- final CountDownLatch pingLatch = new CountDownLatch(1);
- Session client = factory.newSPDYClient(version).connect(proxyAddress, new SessionFrameListener.Adapter()
- {
- @Override
- public void onPing(Session session, PingResultInfo pingInfo)
- {
- pingLatch.countDown();
- }
- });
-
- client.ping(new PingInfo(5, TimeUnit.SECONDS));
-
- Assert.assertTrue(pingLatch.await(5, TimeUnit.SECONDS));
- }
-
- private class TestServerHandler extends DefaultHandler
- {
- private final String responseHeader;
- private final byte[] responseData;
-
- private TestServerHandler(String responseHeader, byte[] responseData)
- {
- this.responseHeader = responseHeader;
- this.responseData = responseData;
- }
-
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request,
- HttpServletResponse response) throws IOException, ServletException
- {
- assertThat("Via Header is set", baseRequest.getHeader("X-Forwarded-For"), is(notNullValue()));
- assertThat("X-Forwarded-For Header is set", baseRequest.getHeader("X-Forwarded-For"),
- is(notNullValue()));
- assertThat("X-Forwarded-Host Header is set", baseRequest.getHeader("X-Forwarded-Host"),
- is(notNullValue()));
- assertThat("X-Forwarded-Proto Header is set", baseRequest.getHeader("X-Forwarded-Proto"),
- is(notNullValue()));
- assertThat("X-Forwarded-Server Header is set", baseRequest.getHeader("X-Forwarded-Server"),
- is(notNullValue()));
- baseRequest.setHandled(true);
- BufferedReader bufferedReader = request.getReader();
- int read;
- while ((read = bufferedReader.read()) != -1)
- response.getOutputStream().write(read);
-
- // add some hop header to be removed on the proxy
- response.addHeader("Trailer", "bla");
- if (responseHeader != null)
- response.addHeader(responseHeader, "bar");
- if (responseData != null)
- response.getOutputStream().write(responseData);
- }
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYLoadTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYLoadTest.java
deleted file mode 100644
index 6f1a596342..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYLoadTest.java
+++ /dev/null
@@ -1,275 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.io.ByteArrayOutputStream;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
-import org.eclipse.jetty.spdy.server.SPDYServerConnector;
-import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
-import org.eclipse.jetty.toolchain.test.TestTracker;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import static junit.framework.Assert.fail;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-@RunWith(value = Parameterized.class)
-public abstract class ProxySPDYToSPDYLoadTest
-{
- @Parameterized.Parameters
- public static Collection<Short[]> parameters()
- {
- return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
- }
-
- @Rule
- public final TestTracker tracker = new TestTracker();
- private final short version;
- private static final String UUID_HEADER_NAME = "uuidHeader";
- private static final String SERVER_ID_HEADER = "serverId";
- private SPDYClient.Factory factory;
- private Server server;
- private Server proxy;
- private ServerConnector proxyConnector;
- private SslContextFactory sslContextFactory = SPDYTestUtils.newSslContextFactory();
-
- public ProxySPDYToSPDYLoadTest(short version)
- {
- this.version = version;
- }
-
- protected InetSocketAddress startServer(ServerSessionFrameListener listener) throws Exception
- {
- server = new Server();
- SPDYServerConnector serverConnector = new SPDYServerConnector(server, sslContextFactory, listener);
- serverConnector.addConnectionFactory(new SPDYServerConnectionFactory(version, listener));
- serverConnector.setPort(0);
- server.addConnector(serverConnector);
- server.start();
- return new InetSocketAddress("localhost", serverConnector.getLocalPort());
- }
-
- protected InetSocketAddress startProxy(InetSocketAddress server1, InetSocketAddress server2) throws Exception
- {
- proxy = new Server();
- ProxyEngineSelector proxyEngineSelector = new ProxyEngineSelector();
-
- SPDYProxyEngine spdyProxyEngine = new SPDYProxyEngine(factory);
- proxyEngineSelector.putProxyEngine("spdy/" + version, spdyProxyEngine);
-
- proxyEngineSelector.putProxyServerInfo("localhost", new ProxyEngineSelector.ProxyServerInfo("spdy/" + version,
- "localhost", server1.getPort()));
- // server2 will be available at two different ProxyServerInfos with different hosts
- proxyEngineSelector.putProxyServerInfo("127.0.0.1", new ProxyEngineSelector.ProxyServerInfo("spdy/" + version,
- "127.0.0.1", server2.getPort()));
- // ProxyServerInfo is mapped to 127.0.0.2 in the proxyEngineSelector. However to be able to connect the
- // ProxyServerInfo contains 127.0.0.1 as target host
- proxyEngineSelector.putProxyServerInfo("127.0.0.2", new ProxyEngineSelector.ProxyServerInfo("spdy/" + version,
- "127.0.0.1", server2.getPort()));
-
- proxyConnector = new HTTPSPDYProxyServerConnector(proxy, sslContextFactory, proxyEngineSelector);
- proxyConnector.setPort(0);
- proxy.addConnector(proxyConnector);
- proxy.start();
- return new InetSocketAddress("localhost", proxyConnector.getLocalPort());
- }
-
- @Before
- public void init() throws Exception
- {
- factory = new SPDYClient.Factory(sslContextFactory);
- factory.start();
- }
-
- @After
- public void destroy() throws Exception
- {
- server.stop();
- server.join();
- proxy.stop();
- proxy.join();
- factory.stop();
- }
-
- @Test
- public void testSimpleLoadTest() throws Exception
- {
- String server1String = "server1";
- String server2String = "server2";
-
- InetSocketAddress server1 = startServer(new TestServerFrameListener(server1String));
- InetSocketAddress server2 = startServer(new TestServerFrameListener(server2String));
- final InetSocketAddress proxyAddress = startProxy(server1, server2);
-
- final int requestsPerClient = 50;
-
- ExecutorService executorService = Executors.newFixedThreadPool(3);
-
- Runnable client1 = createClientRunnable(proxyAddress, requestsPerClient, server1String, "localhost");
- Runnable client2 = createClientRunnable(proxyAddress, requestsPerClient, server2String, "127.0.0.1");
- Runnable client3 = createClientRunnable(proxyAddress, requestsPerClient, server2String, "127.0.0.2");
-
- List<Future> futures = new ArrayList<>();
-
- futures.add(executorService.submit(client1));
- futures.add(executorService.submit(client2));
- futures.add(executorService.submit(client3));
-
- for (Future future : futures)
- {
- future.get(60, TimeUnit.SECONDS);
- }
- }
-
- private Runnable createClientRunnable(final InetSocketAddress proxyAddress, final int requestsPerClient,
- final String serverIdentificationString, final String serverHost)
- {
- Runnable client = new Runnable()
- {
- @Override
- public void run()
- {
- try
- {
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
- for (int i = 0; i < requestsPerClient; i++)
- {
- sendSingleClientRequest(proxyAddress, client, serverIdentificationString, serverHost);
- }
- }
- catch (InterruptedException | ExecutionException | TimeoutException e)
- {
- fail();
- e.printStackTrace();
- }
- }
- };
- return client;
- }
-
- private void sendSingleClientRequest(InetSocketAddress proxyAddress, Session client, final String serverIdentificationString, String serverHost) throws ExecutionException, InterruptedException, TimeoutException
- {
- final String uuid = UUID.randomUUID().toString();
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
-
- Fields headers = SPDYTestUtils.createHeaders(serverHost, proxyAddress.getPort(), version, "POST", "/");
- headers.add(UUID_HEADER_NAME, uuid);
-
- Stream stream = client.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
- {
- private final ByteArrayOutputStream result = new ByteArrayOutputStream();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields headers = replyInfo.getHeaders();
- assertThat("uuid matches expected uuid", headers.get(UUID_HEADER_NAME).getValue(), is(uuid));
- assertThat("response comes from the given server", headers.get(SERVER_ID_HEADER).getValue(),
- is(serverIdentificationString));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- result.write(dataInfo.asBytes(true), 0, dataInfo.length());
- if (dataInfo.isClose())
- {
- assertThat("received data matches send data", uuid, is(result.toString()));
- dataLatch.countDown();
- }
- }
- });
-
- stream.data(new StringDataInfo(uuid, true), new Callback.Adapter());
-
- assertThat("reply has been received", replyLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("data has been received", dataLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- private class TestServerFrameListener extends ServerSessionFrameListener.Adapter
- {
- private String serverId;
-
- private TestServerFrameListener(String serverId)
- {
- this.serverId = serverId;
- }
-
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Fields requestHeaders = synInfo.getHeaders();
- Assert.assertNotNull(requestHeaders.get("via"));
- Fields.Field uuidHeader = requestHeaders.get(UUID_HEADER_NAME);
- Assert.assertNotNull(uuidHeader);
-
- Fields responseHeaders = new Fields();
- responseHeaders.put(UUID_HEADER_NAME, uuidHeader.getValue());
- responseHeaders.put(SERVER_ID_HEADER, serverId);
- stream.reply(new ReplyInfo(responseHeaders, false), new Callback.Adapter());
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- stream.data(dataInfo, new Callback.Adapter());
- }
- };
- }
- }
-
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYTest.java
deleted file mode 100644
index a74d54b7f6..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYTest.java
+++ /dev/null
@@ -1,553 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import java.io.ByteArrayOutputStream;
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.spdy.api.BytesDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.PingInfo;
-import org.eclipse.jetty.spdy.api.PingResultInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
-import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
-import org.eclipse.jetty.spdy.server.SPDYServerConnector;
-import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
-import org.eclipse.jetty.toolchain.test.TestTracker;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-@RunWith(value = Parameterized.class)
-public abstract class ProxySPDYToSPDYTest
-{
- @Parameterized.Parameters
- public static Collection<Short[]> parameters()
- {
- return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
- }
-
- @Rule
- public final TestTracker tracker = new TestTracker();
- private final short version;
- private SPDYClient.Factory factory;
- private Server server;
- private Server proxy;
- private ServerConnector proxyConnector;
- private SslContextFactory sslContextFactory = SPDYTestUtils.newSslContextFactory();
-
- public ProxySPDYToSPDYTest(short version)
- {
- this.version = version;
- }
-
- protected InetSocketAddress startServer(ServerSessionFrameListener listener) throws Exception
- {
- server = new Server();
- SPDYServerConnector serverConnector = new SPDYServerConnector(server, sslContextFactory, listener);
- serverConnector.addConnectionFactory(new SPDYServerConnectionFactory(version, listener));
- serverConnector.setPort(0);
- server.addConnector(serverConnector);
- server.start();
- return new InetSocketAddress("localhost", serverConnector.getLocalPort());
- }
-
- protected InetSocketAddress startProxy(InetSocketAddress address) throws Exception
- {
- proxy = new Server();
- ProxyEngineSelector proxyEngineSelector = new ProxyEngineSelector();
- SPDYProxyEngine spdyProxyEngine = new SPDYProxyEngine(factory);
- proxyEngineSelector.putProxyEngine("spdy/" + version, spdyProxyEngine);
- proxyEngineSelector.putProxyServerInfo("localhost", new ProxyEngineSelector.ProxyServerInfo("spdy/" + version, address.getHostName(), address.getPort()));
- proxyConnector = new HTTPSPDYProxyServerConnector(proxy, sslContextFactory, proxyEngineSelector);
- proxyConnector.setPort(0);
- proxy.addConnector(proxyConnector);
- proxy.start();
- return new InetSocketAddress("localhost", proxyConnector.getLocalPort());
- }
-
- @Before
- public void init() throws Exception
- {
- factory = new SPDYClient.Factory(sslContextFactory);
- factory.start();
- }
-
- @After
- public void destroy() throws Exception
- {
- if (server != null)
- {
- server.stop();
- server.join();
- }
- if (proxy != null)
- {
- proxy.stop();
- proxy.join();
- }
- factory.stop();
- }
-
- @Test
- public void testSYNThenREPLY() throws Exception
- {
- final String header = "foo";
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Fields requestHeaders = synInfo.getHeaders();
- Assert.assertNotNull(requestHeaders.get("via"));
- Assert.assertNotNull(requestHeaders.get(header));
-
- Fields responseHeaders = new Fields();
- responseHeaders.put(header, "baz");
- stream.reply(new ReplyInfo(responseHeaders, true), new Callback.Adapter());
- return null;
- }
- }));
- proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version));
-
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "GET", "/");
- headers.put(header, "bar");
- client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields headers = replyInfo.getHeaders();
- Assert.assertNotNull(headers.get(header));
- replyLatch.countDown();
- }
- });
-
- Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
-
- client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
- }
-@Test
- public void testSYNThenRSTFromUpstreamServer() throws Exception
- {
- final String header = "foo";
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Fields requestHeaders = synInfo.getHeaders();
- Assert.assertNotNull(requestHeaders.get("via"));
- Assert.assertNotNull(requestHeaders.get(header));
- stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new Callback.Adapter());
- return null;
- }
- }));
- proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version));
-
- final CountDownLatch resetLatch = new CountDownLatch(1);
- Session client = factory.newSPDYClient(version).connect(proxyAddress, new SessionFrameListener.Adapter()
- {
- @Override
- public void onRst(Session session, RstInfo rstInfo)
- {
- resetLatch.countDown();
- }
- });
-
- Fields headers = SPDYTestUtils.createHeaders("localhost", proxyAddress.getPort(), version, "GET", "/");
- headers.put(header, "bar");
- client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter());
-
- assertThat("reset is received by client", resetLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testSYNThenREPLYAndDATA() throws Exception
- {
- final byte[] data = "0123456789ABCDEF".getBytes(StandardCharsets.UTF_8);
- final String header = "foo";
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Fields requestHeaders = synInfo.getHeaders();
- Assert.assertNotNull(requestHeaders.get("via"));
- Assert.assertNotNull(requestHeaders.get(header));
-
- Fields responseHeaders = new Fields();
- responseHeaders.put(header, "baz");
- stream.reply(new ReplyInfo(responseHeaders, false), new Callback.Adapter());
- stream.data(new BytesDataInfo(data, true), new Callback.Adapter());
- return null;
- }
- }));
- proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version));
-
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- Fields headers = new Fields();
- headers.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + proxyAddress.getPort());
- headers.put(header, "bar");
- client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- private final ByteArrayOutputStream result = new ByteArrayOutputStream();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields headers = replyInfo.getHeaders();
- Assert.assertNotNull(headers.get(header));
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- result.write(dataInfo.asBytes(true), 0, dataInfo.length());
- if (dataInfo.isClose())
- {
- Assert.assertArrayEquals(data, result.toByteArray());
- dataLatch.countDown();
- }
- }
- });
-
- Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
-
- client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testSYNThenSPDYPushIsReceived() throws Exception
- {
- final byte[] data = "0123456789ABCDEF".getBytes(StandardCharsets.UTF_8);
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Fields responseHeaders = new Fields();
- responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
- stream.reply(new ReplyInfo(responseHeaders, false), new Callback.Adapter());
-
- Fields pushHeaders = new Fields();
- pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/push");
- stream.push(new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Promise.Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream pushStream)
- {
- pushStream.data(new BytesDataInfo(data, true), new Callback.Adapter());
- }
- });
-
- stream.data(new BytesDataInfo(data, true), new Callback.Adapter());
-
- return null;
- }
- }));
- proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version));
-
- final CountDownLatch pushSynLatch = new CountDownLatch(1);
- final CountDownLatch pushDataLatch = new CountDownLatch(1);
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
-
- Fields headers = new Fields();
- headers.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + proxyAddress.getPort());
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- pushSynLatch.countDown();
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- dataLatch.countDown();
- }
- });
-
- Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(pushSynLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(pushDataLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
-
- client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testSYNThenSPDYNestedPushIsReceived() throws Exception
- {
- final byte[] data = "0123456789ABCDEF".getBytes(StandardCharsets.UTF_8);
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Fields responseHeaders = new Fields();
- responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
- responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
- stream.reply(new ReplyInfo(responseHeaders, false), new Callback.Adapter());
-
- final Fields pushHeaders = new Fields();
- pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/push");
- stream.push(new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Promise.Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream pushStream)
- {
- pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/nestedpush");
- pushStream.push(new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream pushStream)
- {
- pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/anothernestedpush");
- pushStream.push(new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream pushStream)
- {
- pushStream.data(new BytesDataInfo(data, true), new Callback.Adapter());
- }
- });
- pushStream.data(new BytesDataInfo(data, true), new Callback.Adapter());
- }
- });
- pushStream.data(new BytesDataInfo(data, true), new Callback.Adapter());
- }
- });
-
- stream.data(new BytesDataInfo(data, true), new Callback.Adapter());
-
- return null;
- }
- }));
- proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version));
-
- final CountDownLatch pushSynLatch = new CountDownLatch(3);
- final CountDownLatch pushDataLatch = new CountDownLatch(3);
- Session client = factory.newSPDYClient(version).connect(proxyAddress, null);
-
- Fields headers = new Fields();
- headers.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + proxyAddress.getPort());
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- client.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
- {
- // onPush for 1st push stream
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- pushSynLatch.countDown();
- return new StreamFrameListener.Adapter()
- {
- // onPush for 2nd nested push stream
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- pushSynLatch.countDown();
- return new Adapter()
- {
- // onPush for 3rd nested push stream
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- pushSynLatch.countDown();
- return new Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- pushDataLatch.countDown();
- }
- };
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- dataLatch.countDown();
- }
- });
-
- Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(pushSynLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(pushDataLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
-
- client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testPING() throws Exception
- {
- // PING is per hop, and it does not carry the information to which server to ping to
- // We just verify that it works
-
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()));
- proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version));
-
- final CountDownLatch pingLatch = new CountDownLatch(1);
- Session client = factory.newSPDYClient(version).connect(proxyAddress, new SessionFrameListener.Adapter()
- {
- @Override
- public void onPing(Session session, PingResultInfo pingInfo)
- {
- pingLatch.countDown();
- }
- });
-
- client.ping(new PingInfo(5, TimeUnit.SECONDS));
-
- Assert.assertTrue(pingLatch.await(5, TimeUnit.SECONDS));
-
- client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testSYNThenReset() throws Exception
- {
- InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Assert.assertTrue(synInfo.isClose());
- Fields requestHeaders = synInfo.getHeaders();
- Assert.assertNotNull(requestHeaders.get("via"));
-
- stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new Callback.Adapter());
-
- return null;
- }
- }));
- proxyConnector.addConnectionFactory(proxyConnector.getConnectionFactory("spdy/" + version));
-
- final CountDownLatch resetLatch = new CountDownLatch(1);
- Session client = factory.newSPDYClient(version).connect(proxyAddress, new SessionFrameListener.Adapter()
- {
- @Override
- public void onRst(Session session, RstInfo rstInfo)
- {
- resetLatch.countDown();
- }
- });
-
- Fields headers = new Fields();
- headers.put(HTTPSPDYHeader.HOST.name(version), "localhost:" + proxyAddress.getPort());
- client.syn(new SynInfo(headers, true), null);
-
- Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
-
- client.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/resources/big_script.js b/jetty-spdy/spdy-http-server/src/test/resources/big_script.js
deleted file mode 100644
index 37202fd211..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/resources/big_script.js
+++ /dev/null
@@ -1,791 +0,0 @@
-//----------------------------------------------------------------------
-//
-// Silly / Pointless Javascript to test GZIP compression.
-//
-//----------------------------------------------------------------------
-
-var LOGO = {
- dat: [
- 0x50, 0x89, 0x47, 0x4e, 0x0a, 0x0d, 0x0a, 0x1a, 0x00, 0x00, 0x0d, 0x00, 0x48, 0x49, 0x52, 0x44,
- 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x78, 0x00, 0x06, 0x08, 0x00, 0x00, 0x2a, 0x00, 0x21, 0x96,
- 0x00, 0x0f, 0x00, 0x00, 0x73, 0x04, 0x49, 0x42, 0x08, 0x54, 0x08, 0x08, 0x7c, 0x08, 0x64, 0x08,
- 0x00, 0x88, 0x00, 0x00, 0x70, 0x09, 0x59, 0x48, 0x00, 0x73, 0x04, 0x00, 0x00, 0x27, 0x04, 0x00,
- 0x01, 0x27, 0x4f, 0xd9, 0x80, 0x1d, 0x00, 0x00, 0x19, 0x00, 0x45, 0x74, 0x74, 0x58, 0x6f, 0x53,
- 0x74, 0x66, 0x61, 0x77, 0x65, 0x72, 0x77, 0x00, 0x77, 0x77, 0x69, 0x2e, 0x6b, 0x6e, 0x63, 0x73,
- 0x70, 0x61, 0x2e, 0x65, 0x72, 0x6f, 0x9b, 0x67, 0x3c, 0xee, 0x00, 0x1a, 0x20, 0x00, 0x49, 0x00,
- 0x41, 0x44, 0x78, 0x54, 0xed, 0x9c, 0x79, 0x9d, 0x1c, 0xd8, 0x95, 0x55, 0x3f, 0xff, 0xfb, 0xa7,
- 0xb2, 0xdd, 0x24, 0xef, 0x24, 0x81, 0x81, 0x2c, 0x20, 0x40, 0xd5, 0x91, 0x8b, 0xb0, 0x3f, 0xbb,
- 0x1d, 0x04, 0x54, 0x1c, 0x46, 0x74, 0x17, 0x18, 0xd1, 0x98, 0x19, 0xd1, 0x05, 0x11, 0x37, 0xf4,
- 0xe2, 0x8f, 0xcc, 0xb8, 0x28, 0x8c, 0x82, 0x02, 0x22, 0x8c, 0xe0, 0xe8, 0xe2, 0x86, 0x02, 0x88,
- 0x8e, 0xa2, 0x08, 0xe8, 0x42, 0x42, 0x4b, 0x08, 0xc2, 0xc8, 0x12, 0x12, 0xf6, 0x42, 0x7d, 0x90,
- 0xf7, 0x7d, 0x3e, 0xee, 0x47, 0xf3, 0x77, 0x75, 0xeb, 0x6a, 0xdf, 0x7e, 0xee, 0xea, 0xab, 0x7b,
- 0xdc, 0x93, 0xf3, 0xcf, 0xd0, 0xf0, 0xa9, 0x55, 0x53, 0xae, 0x6f, 0x5d, 0x3d, 0xd5, 0x9e, 0xf7,
- 0xee, 0x7b, 0x8a, 0xf9, 0xe2, 0xaa, 0x38, 0x70, 0x0e, 0x1c, 0xc3, 0x87, 0x99, 0x2e, 0x2f, 0xb4,
- 0xe1, 0xc0, 0x38, 0x70, 0x8e, 0x1c, 0x11, 0x83, 0x80, 0xe7, 0x0e, 0x1d, 0xc3, 0x87, 0x48, 0xe1,
- 0xe7, 0x01, 0x1d, 0x80, 0x87, 0x0e, 0xe1, 0xc3, 0x01, 0x48, 0x80, 0xe7, 0x0e, 0x1d, 0xc3, 0x87,
- 0x48, 0xe1, 0xe7, 0x01, 0x1d, 0x80, 0x87, 0x0e, 0xe1, 0xc3, 0x01, 0x48, 0x80, 0xe7, 0x0e, 0x1d,
- 0xc3, 0x87, 0x48, 0xe1, 0xe7, 0x01, 0x1d, 0x80, 0x87, 0x0e, 0xe1, 0xc3, 0x01, 0x48, 0x80, 0xe7,
- 0x0e, 0x1d, 0xc3, 0x87, 0x48, 0xe1, 0xe7, 0x01, 0x1d, 0x80, 0x87, 0x0e, 0xe1, 0xc3, 0x01, 0x48,
- 0x80, 0xe7, 0x0e, 0x1d, 0xc3, 0x87, 0x48, 0xe1, 0xe7, 0x01, 0x1d, 0x80, 0x87, 0x0e, 0xe1, 0xc3,
- 0x01, 0x48, 0x80, 0xe7, 0x0e, 0x1d, 0xc3, 0x87, 0x48, 0xe1, 0x96, 0x81, 0x2f, 0xb4, 0x44, 0x40,
- 0x2c, 0x3a, 0xe9, 0x98, 0xa7, 0x55, 0xe1, 0x3a, 0x38, 0x70, 0x8e, 0x1c, 0x42, 0x26, 0xf0, 0xd2,
- 0x22, 0x4b, 0x16, 0x32, 0x0c, 0xb8, 0x02, 0xb8, 0xde, 0x38, 0xc9, 0x82, 0xe0, 0x4e, 0x80, 0xbf,
- 0xa9, 0x4f, 0xbf, 0x6a, 0x7b, 0x05, 0x88, 0xb1, 0x6c, 0xc8, 0xc3, 0xe0, 0xfb, 0xc0, 0xd1, 0x81,
- 0xcd, 0x86, 0x81, 0xe5, 0xc0, 0xe5, 0xab, 0xdf, 0x02, 0xea, 0xb6, 0xc3, 0x0e, 0x1c, 0xa3, 0x87,
- 0x44, 0x6e, 0x12, 0x64, 0x29, 0x70, 0x41, 0xf0, 0x7a, 0x60, 0xaf, 0xc2, 0x01, 0x77, 0x80, 0xf3,
- 0x55, 0x9b, 0x21, 0xf5, 0xf6, 0x0b, 0x81, 0xba, 0x81, 0xc7, 0x54, 0x5b, 0x77, 0xf5, 0xbf, 0x09,
- 0xd9, 0xeb, 0xed, 0xb7, 0x45, 0x80, 0x0b, 0x24, 0x04, 0x2c, 0x5b, 0x66, 0xec, 0x35, 0x28, 0xf1,
- 0xd7, 0xf0, 0xba, 0xaa, 0xb6, 0xd5, 0x11, 0x61, 0x23, 0x79, 0x27, 0xf0, 0x76, 0xdb, 0x5e, 0x81,
- 0x27, 0x3c, 0xc3, 0xfc, 0x6c, 0x14, 0x1c, 0x3b, 0xc7, 0x0e, 0x10, 0xa0, 0x23, 0x91, 0x67, 0x81,
- 0x91, 0x81, 0x9e, 0x75, 0x13, 0xaa, 0x4b, 0x38, 0x17, 0x55, 0xb2, 0x5b, 0x05, 0xd7, 0xa3, 0x9c,
- 0x0b, 0xaa, 0x7e, 0x93, 0x8d, 0x31, 0xe0, 0x39, 0x48, 0x2b, 0xf9, 0xc7, 0x9c, 0x02, 0xbc, 0x0b,
- 0xb6, 0xdb, 0x62, 0xd1, 0xe3, 0xa7, 0xdb, 0x66, 0x8b, 0x76, 0x03, 0xb4, 0xa5, 0x37, 0xdb, 0x64,
- 0x70, 0xe1, 0x06, 0x38, 0x2d, 0xcb, 0xef, 0xd4, 0x01, 0x0c, 0x01, 0x86, 0x8b, 0xf7, 0xab, 0x48,
- 0x7b, 0x25, 0x81, 0x43, 0x0d, 0x5f, 0x5e, 0xc2, 0x34, 0x84, 0x80, 0xe6, 0x50, 0x3f, 0x20, 0xfa,
- 0x98, 0x19, 0xfa, 0xfd, 0xd7, 0xc4, 0x0c, 0x9c, 0x96, 0x55, 0x92, 0x3c, 0x0b, 0x43, 0x3d, 0xe5,
- 0xcc, 0x33, 0x8c, 0x1a, 0x0e, 0x65, 0xab, 0x30, 0x31, 0xb4, 0x4d, 0xb9, 0xd6, 0x98, 0xb6, 0x6e,
- 0xf3, 0xef, 0x9f, 0x6a, 0xba, 0xb2, 0xfc, 0xb7, 0xc7, 0xa3, 0xc8, 0x88, 0x55, 0x04, 0x62, 0xdd,
- 0xa8, 0xd4, 0xe1, 0xc3, 0xd4, 0x70, 0x71, 0x40, 0xee, 0x7a, 0xd2, 0x82, 0xb0, 0xf6, 0x30, 0x8c,
- 0x58, 0x6b, 0x36, 0xb2, 0x55, 0x72, 0x81, 0x4f, 0xfd, 0x4d, 0x88, 0xe5, 0x34, 0xee, 0x69, 0xbc,
- 0x63, 0x38, 0xd6, 0xf6, 0x16, 0xf4, 0xd8, 0xd8, 0xb6, 0x57, 0x38, 0x77, 0xa8, 0x50, 0x78, 0x72,
- 0x56, 0x2c, 0xb0, 0x1d, 0xb4, 0x88, 0xa7, 0x03, 0xb6, 0x95, 0x1e, 0xa7, 0xe5, 0x97, 0x9f, 0x9a,
- 0x33, 0x0f, 0x73, 0x6a, 0xba, 0xdb, 0x9f, 0x02, 0x79, 0x3c, 0x7f, 0xb7, 0x34, 0xd7, 0x06, 0xa3,
- 0x39, 0xe3, 0xbf, 0xdb, 0xdd, 0x71, 0x76, 0x94, 0x9f, 0x2e, 0x66, 0xd8, 0xe0, 0xd4, 0xaf, 0x95,
- 0x70, 0xf4, 0xab, 0xeb, 0xfe, 0x7d, 0x87, 0x5d, 0xce, 0x03, 0x3b, 0x01, 0x8e, 0x1c, 0xe4, 0x66,
- 0xff, 0x5a, 0xa7, 0xc6, 0x6d, 0x0e, 0x8b, 0xe3, 0xdb, 0x53, 0xfd, 0x07, 0x02, 0xe5, 0xfc, 0x70,
- 0xbd, 0xc2, 0x07, 0x7e, 0x53, 0xbc, 0xab, 0x55, 0xc4, 0x39, 0xea, 0x6b, 0xa7, 0xb1, 0x89, 0xc0,
- 0xf6, 0x8b, 0x1d, 0xfa, 0xa7, 0x70, 0x56, 0xaa, 0xf8, 0x74, 0xb0, 0x95, 0x82, 0x1d, 0x15, 0x3e,
- 0x24, 0x2f, 0xc0, 0x0a, 0x73, 0x31, 0xfb, 0xcc, 0x65, 0xff, 0xe4, 0x4f, 0xbb, 0xc2, 0x1a, 0x96,
- 0x1a, 0x37, 0xe0, 0x25, 0xcf, 0x80, 0x69, 0x1a, 0x77, 0xfe, 0xdd, 0xcf, 0x78, 0x13, 0xf2, 0x16,
- 0x32, 0xc0, 0x46, 0xe3, 0x0e, 0x1d, 0x23, 0x87, 0x22, 0x21, 0x38, 0x72, 0x49, 0x70, 0x7b, 0x69,
- 0x46, 0x68, 0xc4, 0xf8, 0x64, 0xe4, 0x94, 0x03, 0xb7, 0x7b, 0xb3, 0xf5, 0x27, 0xa2, 0x6f, 0xe0,
- 0xb6, 0x2b, 0x45, 0x77, 0xef, 0x7b, 0xc7, 0xab, 0x83, 0xde, 0x72, 0x3b, 0xdf, 0x3c, 0xb0, 0x15,
- 0x3c, 0xb7, 0x09, 0xd1, 0xd8, 0x8a, 0xc0, 0x76, 0x47, 0x01, 0x63, 0x34, 0xd6, 0x4e, 0xc1, 0xb8,
- 0x16, 0x97, 0x3a, 0x44, 0x8f, 0x25, 0x37, 0x19, 0xe5, 0x1a, 0xd2, 0xac, 0xb1, 0x87, 0xc2, 0x2d,
- 0x21, 0xcc, 0x6f, 0x66, 0xde, 0xfb, 0xb2, 0xbc, 0x2b, 0xb8, 0xbb, 0xf0, 0xa8, 0x97, 0x1e, 0xea,
- 0x46, 0xa3, 0x0e, 0x1d, 0xa3, 0x87, 0x3e, 0x36, 0x2f, 0x8d, 0xfb, 0x1a, 0x43, 0xa1, 0x19, 0x5a,
- 0x22, 0xdf, 0x4e, 0x89, 0xfd, 0x70, 0xbe, 0xfa, 0xae, 0xf0, 0xcd, 0x1b, 0xeb, 0xda, 0xef, 0x0d,
- 0x66, 0xfa, 0x13, 0xa2, 0xb1, 0x14, 0x07, 0x3d, 0x74, 0x1c, 0xa7, 0xc0, 0x37, 0x9b, 0xd2, 0xff,
- 0xc0, 0xfc, 0x38, 0x08, 0xcc, 0x0f, 0x6e, 0x37, 0x87, 0xd4, 0x1c, 0x88, 0x1c, 0x03, 0xda, 0x52,
- 0x63, 0x3e, 0x96, 0x44, 0x7f, 0x64, 0xe4, 0xea, 0xd8, 0x2c, 0x27, 0x9b, 0x4c, 0x1f, 0x9f, 0x6e,
- 0xd8, 0x6b, 0x01, 0xe4, 0x88, 0x83, 0x0d, 0x1c, 0x0e, 0x5c, 0x07, 0x9c, 0xff, 0x46, 0x0a, 0x54,
- 0xc2, 0x6c, 0x32, 0x5b, 0x67, 0xf1, 0x46, 0x53, 0x64, 0x44, 0x5e, 0x08, 0xe1, 0xe2, 0x62, 0xdf,
- 0xe9, 0x7e, 0x37, 0x5b, 0x08, 0xf0, 0x15, 0xf0, 0x8d, 0x55, 0x9e, 0x84, 0x8e, 0x1c, 0x22, 0x30,
- 0x1e, 0x32, 0x48, 0xf8, 0xbb, 0x69, 0xe0, 0x45, 0x43, 0xaa, 0x8d, 0x93, 0xff, 0x46, 0x57, 0x77,
- 0x67, 0x8e, 0x03, 0x3a, 0x8e, 0x03, 0xc0, 0x15, 0x9b, 0x7f, 0x37, 0xb2, 0x4f, 0x77, 0x79, 0x9e,
- 0x08, 0xc1, 0x1a, 0xe3, 0xee, 0xe0, 0x27, 0x44, 0xd9, 0x29, 0xe5, 0xaf, 0x75, 0x4b, 0x1e, 0x50,
- 0x8e, 0x09, 0x98, 0x9e, 0xc2, 0x61, 0xb3, 0x34, 0xc1, 0x23, 0xdd, 0xae, 0xda, 0xca, 0x03, 0x17,
- 0x6a, 0x37, 0xaa, 0x91, 0x35, 0xee, 0x34, 0x6a, 0x30, 0x4a, 0x3c, 0xfc, 0xfc, 0xc2, 0x3f, 0xa8,
- 0x7e, 0x14, 0xe7, 0x06, 0x07, 0x80, 0x88, 0x85, 0x1b, 0xfc, 0x59, 0xf0, 0x3a, 0xcc, 0x30, 0xde,
- 0x88, 0x17, 0xa7, 0xc8, 0xf5, 0x55, 0x8d, 0x5b, 0xb1, 0x3e, 0xcc, 0x88, 0x8b, 0xc2, 0x8c, 0xf8,
- 0xf4, 0x6a, 0xab, 0xb9, 0x7a, 0xf0, 0xf5, 0xe0, 0xf2, 0x22, 0x55, 0x5e, 0x6c, 0xdd, 0xae, 0xd1,
- 0xff, 0x63, 0x9f, 0xe4, 0xb2, 0xf0, 0x01, 0x88, 0xef, 0x78, 0x56, 0xb8, 0x4f, 0x0e, 0xa0, 0x98,
- 0xb5, 0xfa, 0xe8, 0xe8, 0x1b, 0xf7, 0xe6, 0x55, 0xeb, 0x7f, 0x17, 0xb6, 0xfa, 0x37, 0xb5, 0xad,
- 0x69, 0xc3, 0x04, 0x2d, 0x22, 0x2d, 0x80, 0x33, 0xa5, 0x09, 0x1b, 0x6d, 0xe7, 0xe1, 0x4f, 0x15,
- 0xb2, 0x05, 0x21, 0x9f, 0x47, 0x1d, 0x70, 0x14, 0x67, 0xc0, 0x30, 0x8f, 0xe7, 0xdf, 0xe7, 0x99,
- 0x70, 0x1c, 0x44, 0x62, 0x38, 0xe4, 0x6a, 0xe0, 0x3a, 0xec, 0xf0, 0x5f, 0xc1, 0x3a, 0x8b, 0x37,
- 0x39, 0xc8, 0xce, 0x06, 0x13, 0x7d, 0x9d, 0x76, 0x89, 0x6f, 0x80, 0xf3, 0x52, 0xdb, 0xeb, 0xb0,
- 0x8f, 0xd8, 0x91, 0x10, 0xc0, 0x61, 0xfc, 0x27, 0xae, 0xfb, 0x6c, 0x39, 0x89, 0xf0, 0x00, 0x50,
- 0x74, 0xcf, 0xf9, 0xe6, 0xae, 0xd3, 0xef, 0x80, 0x04, 0xdb, 0x65, 0xdc, 0xde, 0xca, 0x5d, 0x73,
- 0x7e, 0x05, 0x23, 0xbb, 0x6f, 0x60, 0x70, 0x1b, 0xa2, 0x47, 0xf8, 0x93, 0x39, 0xb0, 0xb6, 0x02,
- 0x7e, 0x1f, 0xa2, 0x7e, 0xe6, 0x29, 0xcb, 0x7f, 0xbb, 0xbf, 0xe0, 0x55, 0xe1, 0xb4, 0x3b, 0x66,
- 0x05, 0x1e, 0x7e, 0x60, 0x01, 0xd0, 0x53, 0xaf, 0x35, 0xd5, 0x8d, 0x46, 0x18, 0x1e, 0x13, 0xfc,
- 0xf7, 0xbe, 0x3d, 0xa1, 0x3e, 0x63, 0xdc, 0xfe, 0xec, 0x1b, 0xce, 0x1c, 0x81, 0xa4, 0x67, 0xcf,
- 0x99, 0x71, 0x9b, 0xc5, 0xdb, 0x4a, 0xf1, 0x59, 0x3f, 0x9e, 0xf4, 0x93, 0x02, 0x15, 0x30, 0xeb,
- 0x9a, 0x66, 0xe6, 0xb5, 0x00, 0x38, 0x02, 0xb8, 0x5b, 0x18, 0x38, 0xda, 0x4c, 0x7f, 0xb3, 0x0b,
- 0x26, 0x86, 0x8d, 0x1d, 0x46, 0x46, 0x37, 0xbf, 0x6a, 0xa9, 0x85, 0x4f, 0x2f, 0xc3, 0xd7, 0xaf,
- 0xd7, 0xde, 0xf4, 0x37, 0x2a, 0x12, 0x75, 0x5d, 0xaa, 0xab, 0x26, 0x76, 0x89, 0x3a, 0xf4, 0x8f,
- 0x70, 0x1c, 0x19, 0x3a, 0x56, 0xd0, 0x82, 0x47, 0x32, 0x22, 0x38, 0x0e, 0xb4, 0xae, 0xca, 0x7d,
- 0x2c, 0xf0, 0xf3, 0x86, 0x58, 0xaf, 0x99, 0xd2, 0x4f, 0x67, 0x02, 0x70, 0x8d, 0xd8, 0x07, 0x7e,
- 0x79, 0x47, 0xda, 0x04, 0x81, 0x9e, 0xaf, 0xed, 0x89, 0x1d, 0xa5, 0xc9, 0x8b, 0xda, 0xf3, 0x3b,
- 0xb2, 0x9c, 0xf0, 0x38, 0x1e, 0xde, 0x60, 0xd3, 0x81, 0x13, 0xf5, 0x11, 0x87, 0xf5, 0xf0, 0x77,
- 0x84, 0xc9, 0x9e, 0x99, 0x79, 0x49, 0x73, 0xd3, 0x3c, 0x5d, 0xbb, 0xb2, 0xce, 0xfc, 0x17, 0x4d,
- 0x71, 0x11, 0xd8, 0x35, 0x71, 0x1d, 0x8b, 0x14, 0x5c, 0x56, 0xdf, 0xe5, 0xed, 0x77, 0xc9, 0xa1,
- 0xa3, 0x46, 0x7a, 0x2b, 0xdc, 0x0a, 0x2d, 0xbb, 0x59, 0x50, 0x37, 0x78, 0x9f, 0xf0, 0xec, 0x55,
- 0xba, 0x7d, 0x7b, 0x1e, 0x7a, 0x6b, 0xfc, 0x0b, 0x6b, 0x6c, 0x5e, 0xc0, 0x5e, 0x17, 0x8f, 0x31,
- 0xb1, 0x9a, 0x05, 0x99, 0x76, 0x5d, 0x6d, 0xc0, 0x84, 0x43, 0x67, 0xc3, 0x1d, 0x9b, 0xe6, 0x09,
- 0xe1, 0xfb, 0x67, 0xe5, 0x23, 0x02, 0x55, 0xc1, 0xba, 0xaa, 0xa8, 0xde, 0x28, 0xd1, 0xe2, 0x67,
- 0x48, 0x1b, 0x9d, 0x9d, 0xfc, 0xce, 0x3c, 0xef, 0x46, 0xe3, 0x73, 0xf7, 0x64, 0x44, 0xbe, 0x14,
- 0x29, 0x42, 0x0c, 0xa7, 0x1a, 0xcb, 0xbe, 0x75, 0xfb, 0x10, 0x6a, 0x77, 0xb3, 0xf4, 0x70, 0x19,
- 0xa6, 0xc0, 0xbd, 0x9f, 0xc2, 0x9c, 0x7b, 0x93, 0xbf, 0x03, 0xa3, 0x69, 0xbe, 0x73, 0x2a, 0x8e,
- 0x0d, 0xfc, 0xb5, 0x30, 0x71, 0xb4, 0x88, 0xc6, 0xe7, 0x2c, 0x4c, 0x8c, 0x8c, 0xf6, 0x73, 0x7e,
- 0x5f, 0x43, 0xf2, 0xb8, 0x77, 0xc5, 0x75, 0x55, 0x85, 0x57, 0xdf, 0xc3, 0xaf, 0x5f, 0x1b, 0xbd,
- 0xf6, 0x37, 0x0b, 0x91, 0xd1, 0x3e, 0xa8, 0x77, 0xb6, 0xea, 0x27, 0x44, 0x61, 0x09, 0x01, 0xc5,
- 0x47, 0x17, 0xc7, 0x82, 0xb6, 0x96, 0x9f, 0xa7, 0x25, 0x92, 0x78, 0x6b, 0xbc, 0x00, 0x49, 0x6a,
- 0xbe, 0x9e, 0xc0, 0xee, 0x4a, 0xdd, 0xfc, 0x23, 0x68, 0x1c, 0xcf, 0x04, 0xf3, 0x72, 0xcd, 0xbf,
- 0x59, 0xca, 0xde, 0xf8, 0x1b, 0x05, 0x25, 0x1d, 0x7f, 0x0b, 0xf2, 0xa7, 0x37, 0xb3, 0x23, 0x34,
- 0x34, 0x9c, 0xec, 0xcc, 0x7a, 0x6f, 0x33, 0xb6, 0x57, 0x4f, 0x45, 0xc1, 0x1c, 0x5e, 0x23, 0x03,
- 0x42, 0x22, 0x10, 0xa8, 0xb5, 0xc6, 0xe7, 0x09, 0x5f, 0x62, 0x57, 0xed, 0xda, 0xee, 0x08, 0x12,
- 0xf7, 0x3f, 0x61, 0x52, 0x51, 0xe9, 0xec, 0x23, 0xcb, 0x6d, 0x77, 0x29, 0x0a, 0x6e, 0x7e, 0x8c,
- 0xc0, 0x73, 0x89, 0x0d, 0x12, 0x4e, 0xad, 0x83, 0xf0, 0x11, 0xf8, 0x59, 0x82, 0x46, 0xc2, 0x36,
- 0x2f, 0xcf, 0x48, 0x2d, 0xfc, 0x37, 0x24, 0x5c, 0x76, 0x10, 0xd3, 0x3f, 0xc3, 0x7e, 0x89, 0xde,
- 0x6c, 0x57, 0x51, 0xdc, 0x50, 0x9d, 0xba, 0xa6, 0x8e, 0xf5, 0x17, 0x52, 0xfc, 0x0d, 0x89, 0x3b,
- 0x14, 0xc8, 0x15, 0x7c, 0x5e, 0xdf, 0x3c, 0x3b, 0xc2, 0x4b, 0x8e, 0x65, 0x71, 0x89, 0xf7, 0x99,
- 0x04, 0x8e, 0x03, 0xbc, 0x0a, 0x9f, 0xf1, 0xde, 0x32, 0x43, 0x38, 0x5c, 0xd9, 0x26, 0x77, 0x3b,
- 0xc6, 0xcb, 0x70, 0xbe, 0xc5, 0x0e, 0x54, 0x8f, 0x63, 0x75, 0xc3, 0x85, 0x04, 0x2f, 0xa8, 0x4e,
- 0xde, 0xc7, 0x37, 0xb7, 0x85, 0xf6, 0x98, 0x3b, 0x37, 0x77, 0xb7, 0x22, 0x96, 0xc6, 0x0e, 0x03,
- 0x60, 0x25, 0x28, 0x59, 0x11, 0xc0, 0xff, 0x9d, 0x3a, 0xb5, 0x16, 0x02, 0x36, 0x91, 0x65, 0x7c,
- 0x8f, 0x37, 0xc8, 0xee, 0xd1, 0x30, 0x16, 0x70, 0xba, 0xcc, 0x02, 0xbe, 0x82, 0x6b, 0xe5, 0x4f,
- 0xb5, 0x13, 0x47, 0x94, 0x08, 0x3b, 0x44, 0x09, 0x4c, 0x2a, 0x94, 0x77, 0x07, 0xd6, 0x74, 0xeb,
- 0xf7, 0x83, 0x6a, 0x77, 0xba, 0xe4, 0xab, 0x59, 0x67, 0xe1, 0x91, 0x70, 0x47, 0x17, 0x02, 0x22,
- 0x27, 0x65, 0x73, 0x3f, 0x7b, 0x58, 0x84, 0xa2, 0xdd, 0xc7, 0xe5, 0x79, 0xc1, 0x3b, 0xbb, 0x32,
- 0xe0, 0x05, 0xa6, 0xeb, 0x75, 0xec, 0x94, 0x16, 0x07, 0x6f, 0x29, 0xed, 0x7d, 0x70, 0x53, 0x82,
- 0xc4, 0x54, 0x03, 0x96, 0x27, 0x2e, 0x88, 0x98, 0x31, 0xc0, 0xd9, 0xa7, 0x80, 0xc8, 0xb4, 0x0e,
- 0x3b, 0x67, 0xe7, 0x81, 0x1b, 0x8c, 0x32, 0x0d, 0xe8, 0x0d, 0x6d, 0x28, 0x58, 0xd8, 0xeb, 0xff,
- 0xc1, 0x1a, 0x14, 0xe4, 0x33, 0x93, 0x94, 0xe6, 0x67, 0xb6, 0x64, 0x74, 0x60, 0x98, 0xa3, 0xb8,
- 0x6f, 0x34, 0xf1, 0x8f, 0x4c, 0xe8, 0xf4, 0xa8, 0x8d, 0xa9, 0x2f, 0x67, 0x9b, 0xf0, 0x93, 0x76,
- 0xc9, 0x4e, 0x47, 0x57, 0x53, 0x93, 0x6e, 0x5c, 0xae, 0x57, 0x31, 0x07, 0x2d, 0xb5, 0xfb, 0xc3,
- 0x27, 0xc7, 0xe4, 0x13, 0xee, 0xf9, 0x7e, 0xa6, 0x05, 0x76, 0x4d, 0x13, 0xa5, 0x7f, 0x2f, 0xaa,
- 0xb0, 0x55, 0x36, 0x77, 0xf7, 0xbe, 0x16, 0xa1, 0x77, 0x7b, 0xea, 0x6e, 0x5b, 0x67, 0xf2, 0x70,
- 0x41, 0xf7, 0x6d, 0x55, 0xf3, 0xc8, 0x2b, 0x6d, 0xba, 0x0b, 0x54, 0x3c, 0x0c, 0x97, 0xf1, 0x7c,
- 0xb3, 0x7c, 0x30, 0xb5, 0x05, 0x0a, 0xd7, 0x65, 0xc0, 0x96, 0x9b, 0x0d, 0x42, 0x97, 0xc8, 0x42,
- 0xbc, 0x5a, 0x59, 0x9e, 0xe0, 0x06, 0x3b, 0x0f, 0x9c, 0x73, 0xb8, 0xba, 0x6c, 0xe6, 0x41, 0xf5,
- 0xb9, 0xb1, 0xb2, 0x3f, 0x7c, 0xf6, 0x86, 0xc0, 0x58, 0xbd, 0x75, 0x17, 0xe9, 0x22, 0x53, 0x48,
- 0x16, 0x0e, 0xf6, 0x05, 0xad, 0xe0, 0xdb, 0xf1, 0xcb, 0x5e, 0x52, 0xdf, 0x0e, 0x44, 0x5e, 0x25,
- 0x63, 0x88, 0x30, 0x06, 0xb4, 0xa4, 0xc7, 0x61, 0x45, 0x59, 0x4a, 0x3a, 0x45, 0xbb, 0x8c, 0xe4,
- 0x9a, 0x06, 0x43, 0x78, 0x43, 0xe9, 0x38, 0x06, 0xf0, 0xc3, 0xb7, 0xd2, 0x82, 0x57, 0x30, 0xaa,
- 0x55, 0xe0, 0x9a, 0x22, 0x4d, 0xe3, 0xd5, 0xbd, 0x3f, 0x44, 0x52, 0xb0, 0x77, 0x55, 0x48, 0x88,
- 0x38, 0x06, 0x5f, 0x11, 0x79, 0x0d, 0xf4, 0x43, 0x2b, 0x00, 0x16, 0x92, 0x11, 0xea, 0xc3, 0x91,
- 0x25, 0xf0, 0x18, 0xf7, 0x7c, 0xa2, 0xaa, 0x3f, 0x47, 0x5c, 0x70, 0x2b, 0x60, 0x12, 0x01, 0xfa,
- 0x01, 0xee, 0xd7, 0x96, 0xf4, 0xb1, 0xb3, 0xe6, 0x8d, 0xfe, 0x0f, 0x2b, 0x4b, 0x6d, 0x3c, 0xb4,
- 0xb7, 0xae, 0xdf, 0x00, 0x18, 0xda, 0x84, 0x29, 0x35, 0xf1, 0xf6, 0x53, 0x15, 0xfa, 0xdc, 0x6e,
- 0x59, 0x10, 0x54, 0xea, 0x5e, 0xcd, 0x6c, 0x22, 0xe0, 0x39, 0x1f, 0xf2, 0x90, 0xab, 0x0d, 0x87,
- 0xad, 0xcb, 0x45, 0x47, 0x6b, 0xbf, 0x20, 0xdb, 0xdb, 0x5e, 0x03, 0xb7, 0x07, 0x18, 0xd2, 0x5e,
- 0xab, 0xc0, 0x56, 0xfd, 0xf7, 0x7f, 0x40, 0xcb, 0xc4, 0xa4, 0xb1, 0x61, 0xc4, 0xe0, 0xc0, 0x25,
- 0x78, 0x19, 0xf2, 0x21, 0x36, 0xf1, 0xaa, 0x2f, 0xf4, 0x01, 0xc8, 0x8b, 0xc0, 0xab, 0xe0, 0x02,
- 0xc0, 0xd7, 0x55, 0x03, 0x1f, 0x32, 0x91, 0x11, 0x00, 0xb7, 0x0c, 0xff, 0xcf, 0x9c, 0x1a, 0x20,
- 0x1b, 0x27, 0xbf, 0xf3, 0x77, 0x73, 0x9e, 0x47, 0x86, 0x83, 0xb3, 0x84, 0x98, 0xe2, 0x34, 0x39,
- 0x68, 0xc3, 0x13, 0xc3, 0xf3, 0xc0, 0xbf, 0xa2, 0x14, 0xe7, 0xf1, 0xe0, 0x4f, 0x3a, 0x2d, 0xdb,
- 0x77, 0x22, 0xef, 0x00, 0x53, 0xc4, 0xb2, 0xf2, 0x16, 0xc1, 0x79, 0x11, 0xaa, 0x8f, 0x32, 0x3e,
- 0x81, 0xd0, 0xf2, 0x22, 0xe0, 0x0e, 0xc0, 0xe3, 0xb0, 0x5b, 0x79, 0xd3, 0x16, 0xed, 0x2b, 0x91,
- 0xf5, 0x54, 0xa1, 0x27, 0x98, 0xeb, 0x5c, 0x02, 0x5c, 0x09, 0xaf, 0x86, 0x91, 0xd0, 0x36, 0x61,
- 0xc8, 0x89, 0x55, 0xbb, 0xd1, 0x35, 0x5e, 0xb4, 0x32, 0xb1, 0xdb, 0xdb, 0xdb, 0x4b, 0x5b, 0x63,
- 0xcb, 0x84, 0x26, 0x27, 0x8d, 0x1b, 0x68, 0xfe, 0x5f, 0x4b, 0xb3, 0xb8, 0x67, 0xf7, 0x7d, 0x55,
- 0x82, 0xb2, 0x13, 0xbd, 0x49, 0xf0, 0xd6, 0x0e, 0xef, 0x62, 0x5b, 0x67, 0x59, 0xfb, 0x17, 0xdb,
- 0xd8, 0x18, 0x4d, 0xcc, 0xbb, 0xfa, 0x61, 0xab, 0xb5, 0xbc, 0xf6, 0x29, 0xaf, 0x10, 0x6d, 0x34,
- 0x0a, 0xa7, 0x50, 0x7f, 0xfb, 0xd5, 0xb0, 0x53, 0x59, 0xfb, 0xce, 0x8a, 0x25, 0x37, 0xad, 0x3e,
- 0xe5, 0xaa, 0x9b, 0xae, 0x4c, 0x88, 0xbe, 0x04, 0x4f, 0x81, 0x79, 0x8f, 0xa5, 0x3f, 0x6f, 0x15,
- 0x31, 0xc4, 0xb8, 0x15, 0xe8, 0x18, 0x91, 0x13, 0x80, 0x07, 0x54, 0xeb, 0x30, 0x35, 0x20, 0xcd,
- 0x33, 0x22, 0x07, 0x81, 0xdf, 0x8b, 0x14, 0x19, 0xe7, 0xa6, 0x3b, 0x4b, 0xca, 0x0b, 0x2e, 0xa2,
- 0x1d, 0x7b, 0x73, 0xb1, 0x74, 0x6c, 0xa2, 0x28, 0xfa, 0x23, 0x30, 0x46, 0xaf, 0x04, 0x8a, 0x38,
- 0x26, 0x4d, 0x7f, 0x00, 0x91, 0x14, 0x86, 0x0f, 0x9d, 0x1d, 0x11, 0x1f, 0x15, 0x39, 0x0f, 0xb8,
- 0x55, 0xbb, 0x86, 0xd3, 0x3f, 0x00, 0x91, 0x16, 0xaa, 0xe9, 0x25, 0xfa, 0xfe, 0xdf, 0x00, 0x9f,
- 0xb3, 0xaf, 0x1d, 0x78, 0x45, 0xe0, 0xfe, 0xcc, 0x78, 0xb7, 0x7e, 0x9f, 0xe0, 0x9a, 0xd7, 0x7b,
- 0xbb, 0xe2, 0x1f, 0x67, 0xd4, 0x9f, 0xb0, 0xc6, 0xe0, 0xcc, 0x61, 0x6f, 0x6f, 0x01, 0x51, 0xe9,
- 0xff, 0x88, 0xf2, 0xa8, 0x6b, 0x95, 0xb1, 0xea, 0x78, 0xa7, 0x37, 0x85, 0x34, 0x42, 0xf4, 0x6c,
- 0x76, 0x0b, 0x6e, 0x7a, 0x01, 0x5f, 0x8a, 0xcc, 0x56, 0xfe, 0xfa, 0xc7, 0x57, 0xe8, 0x26, 0x44,
- 0x95, 0xe3, 0x4c, 0x35, 0x35, 0x8b, 0x7a, 0xaa, 0xf1, 0x5f, 0x32, 0x5a, 0xf2, 0x22, 0xc0, 0x8f,
- 0xec, 0x8b, 0xce, 0xff, 0x8e, 0x37, 0x3c, 0x36, 0xbc, 0x47, 0x44, 0x50, 0x26, 0xbe, 0x43, 0x22,
- 0xff, 0x7d, 0x4d, 0xf6, 0x38, 0x12, 0xf1, 0xdf, 0xc2, 0x2d, 0x86, 0xb1, 0xa5, 0x2b, 0xb1, 0x3c,
- 0x22, 0x27, 0x61, 0x94, 0x3b, 0x14, 0xc7, 0xb5, 0x28, 0x0f, 0x85, 0xdd, 0xe0, 0x16, 0x01, 0xd2,
- 0xb9, 0x8e, 0xfb, 0x01, 0x4b, 0x25, 0x7c, 0x4b, 0xf4, 0xb8, 0x44, 0x41, 0xc2, 0x2e, 0xf3, 0xbe,
- 0xd1, 0x2d, 0x27, 0x8a, 0x31, 0xf0, 0xe2, 0x28, 0x00, 0x24, 0x9e, 0x3f, 0x30, 0xb0, 0xaf, 0xcc,
- 0xf5, 0xb7, 0x52, 0xf3, 0x72, 0x50, 0xa1, 0x70, 0xfe, 0xaa, 0x82, 0xa1, 0x69, 0xbd, 0x6b, 0x78,
- 0x6b, 0x7f, 0x17, 0xb6, 0x39, 0x23, 0x1c, 0xf8, 0x9b, 0xf0, 0x27, 0x44, 0x00, 0x19, 0x21, 0x1b,
- 0x0b, 0xe8, 0x1f, 0x4b, 0x8f, 0x86, 0xde, 0x15, 0xb9, 0x7a, 0xa9, 0xd9, 0xae, 0x9c, 0xca, 0x5d,
- 0xbf, 0xef, 0xe8, 0x1b, 0xcc, 0xb5, 0x6a, 0x30, 0x9e, 0x30, 0xe1, 0xb7, 0x57, 0x9b, 0xcb, 0x7c,
- 0x16, 0xe8, 0x31, 0x4e, 0x0e, 0xbc, 0x4f, 0xf3, 0x72, 0xbb, 0xb5, 0x3c, 0x10, 0xaf, 0x54, 0xc2,
- 0xe9, 0x11, 0x53, 0xc0, 0xfa, 0x7f, 0xf0, 0x39, 0xb8, 0xae, 0x4c, 0xef, 0x13, 0x6e, 0x19, 0x4e,
- 0xe5, 0x96, 0x21, 0xb8, 0x5a, 0x19, 0x9f, 0x6a, 0x33, 0xaf, 0x02, 0x8e, 0x72, 0xbb, 0x86, 0xca,
- 0x02, 0xbe, 0xfa, 0x1b, 0x95, 0x95, 0x05, 0x3d, 0xe4, 0x76, 0x5e, 0x22, 0x15, 0xac, 0xc7, 0xaf,
- 0x57, 0xfb, 0x72, 0x22, 0xb0, 0x3e, 0x2f, 0x05, 0x08, 0x3c, 0x94, 0xc0, 0x0c, 0xb6, 0x3b, 0x7f,
- 0xba, 0xa1, 0x3e, 0x2f, 0xdd, 0xb2, 0x3d, 0xfc, 0xc8, 0xe8, 0xe2, 0x48, 0x88, 0x35, 0xf0, 0xf5,
- 0x51, 0xc6, 0x5f, 0x66, 0x02, 0xf1, 0xce, 0xf0, 0xad, 0x31, 0x38, 0x5c, 0x71, 0xa6, 0x0c, 0xe7,
- 0xcb, 0x3d, 0x7b, 0xbc, 0x2b, 0x5c, 0x3b, 0xd3, 0x76, 0xcc, 0x7e, 0x8c, 0xad, 0xb1, 0x95, 0x9f,
- 0x1a, 0xfb, 0x8a, 0xf7, 0x86, 0x6d, 0x8c, 0x88, 0xe7, 0xc1, 0x8e, 0xf4, 0xcf, 0x68, 0x49, 0x70,
- 0xa4, 0xc2, 0xa4, 0x9e, 0xbd, 0xc4, 0xc5, 0xdb, 0x8b, 0x72, 0xf9, 0x17, 0xfb, 0x8f, 0x21, 0xc8,
- 0x8c, 0xad, 0xb5, 0x6f, 0x9f, 0x7a, 0x4e, 0x8e, 0xd5, 0xf0, 0xf0, 0xab, 0x9b, 0xf9, 0xd7, 0x0f,
- 0x01, 0x22, 0x1d, 0x18, 0x56, 0xfd, 0xba, 0x9b, 0x0a, 0xb9, 0xe7, 0x5f, 0x16, 0xbb, 0x5f, 0x7b,
- 0x8a, 0x8b, 0x5c, 0x2e, 0xe8, 0xdf, 0x22, 0x5c, 0x6f, 0xa3, 0x31, 0x67, 0x58, 0x04, 0x63, 0x9e,
- 0xfe, 0x3c, 0x16, 0xec, 0xfa, 0xfe, 0x8e, 0xea, 0xdf, 0x2a, 0x9f, 0xa8, 0x1f, 0x67, 0x0f, 0xea,
- 0xe0, 0x3b, 0x36, 0x06, 0x83, 0x0d, 0x90, 0x26, 0xfa, 0x85, 0x0f, 0xff, 0xe7, 0x6b, 0xc3, 0x5c,
- 0x3d, 0xc9, 0xbc, 0xcf, 0x08, 0x10, 0x0a, 0x03, 0xcd, 0x5e, 0x2f, 0xd3, 0x72, 0x11, 0xad, 0xbe,
- 0x57, 0x02, 0xda, 0x1d, 0x27, 0xce, 0xb5, 0x26, 0xb9, 0x31, 0x79, 0xad, 0x6e, 0x9d, 0xf2, 0x35,
- 0x8f, 0x0a, 0xce, 0xec, 0xef, 0x71, 0x1c, 0xb6, 0x6f, 0x77, 0x64, 0x8d, 0x1e, 0x44, 0x3c, 0x0b,
- 0x17, 0x8a, 0x2a, 0x2a, 0xf4, 0xdf, 0xc6, 0x0b, 0xf0, 0xb4, 0x69, 0xd5, 0x1c, 0xf6, 0x25, 0x5f,
- 0x1a, 0xce, 0xb5, 0x91, 0x2a, 0x32, 0x45, 0xb5, 0xf8, 0x06, 0x83, 0x72, 0xeb, 0xef, 0xe0, 0xc2,
- 0xcc, 0xb3, 0x87, 0xf5, 0x33, 0xb7, 0x70, 0xcd, 0xb2, 0x69, 0x83, 0xbb, 0x06, 0x25, 0x4d, 0xab,
- 0x05, 0x1d, 0x1a, 0x6a, 0x34, 0x5c, 0xfc, 0xd6, 0x15, 0x73, 0xb7, 0x7a, 0x78, 0x33, 0xda, 0x6d,
- 0x7c, 0x46, 0x4c, 0xed, 0x06, 0x47, 0x39, 0x6e, 0x08, 0x6a, 0x5f, 0xa6, 0xd0, 0xe9, 0x1a, 0x7d,
- 0xdb, 0x54, 0x2c, 0x5a, 0x74, 0xc4, 0x69, 0x79, 0x45, 0xbb, 0x53, 0xe0, 0x25, 0x09, 0xff, 0x00,
- 0xea, 0x1c, 0x01, 0x94, 0x81, 0x2b, 0x98, 0x5f, 0x37, 0xb2, 0x4f, 0x77, 0xc7, 0x9e, 0x24, 0x1b,
- 0x58, 0x39, 0xd3, 0x0d, 0xe8, 0x21, 0x7a, 0xc0, 0x63, 0xc4, 0xb0, 0xcf, 0x80, 0x51, 0x32, 0x23,
- 0xb5, 0x1f, 0xb8, 0xc0, 0x28, 0xd1, 0x05, 0xd6, 0x9e, 0x18, 0x3e, 0x08, 0x1b, 0x2c, 0xf7, 0x81,
- 0xd3, 0xe2, 0x04, 0xbd, 0x6f, 0x38, 0x0b, 0x64, 0x9c, 0xcf, 0x9c, 0x38, 0x4e, 0xaf, 0xdf, 0x6b,
- 0x9d, 0x6f, 0x78, 0x2f, 0x02, 0xc2, 0x1c, 0x6f, 0xc2, 0xd5, 0x47, 0xad, 0xf0, 0x75, 0xc9, 0xc2,
- 0xb9, 0xc3, 0x42, 0x6c, 0x38, 0x6b, 0x78, 0x1e, 0x10, 0x18, 0xf7, 0x90, 0x90, 0x3b, 0xde, 0x9c,
- 0x4c, 0x81, 0x4c, 0x58, 0x4a, 0x64, 0xc6, 0x5b, 0xf3, 0xb8, 0x59, 0x8d, 0xff, 0x3f, 0x95, 0x54,
- 0xad, 0xc3, 0x8b, 0xca, 0xbc, 0xc6, 0x1b, 0xdb, 0x75, 0x54, 0x31, 0x63, 0xa3, 0xa7, 0x02, 0x3c,
- 0x75, 0x3d, 0xd6, 0x58, 0xf3, 0xb8, 0xb9, 0x8d, 0xb1, 0x4f, 0x4f, 0xc9, 0x04, 0x31, 0x00, 0x24,
- 0x19, 0x2f, 0x83, 0x5f, 0x60, 0x04, 0xf4, 0x74, 0x8d, 0xfb, 0x35, 0x2a, 0x3e, 0x0e, 0x6f, 0x81,
- 0xb3, 0xda, 0x7b, 0x16, 0xa3, 0x31, 0x6f, 0xdf, 0x6a, 0xaa, 0xdc, 0x7f, 0xf5, 0xb1, 0xd5, 0x60,
- 0xdb, 0x01, 0x40, 0x51, 0x5d, 0x4a, 0x61, 0x80, 0x3e, 0x2c, 0x86, 0x01, 0x87, 0x93, 0x17, 0x99,
- 0x58, 0x60, 0x99, 0xda, 0x77, 0x67, 0x14, 0x70, 0xc1, 0x98, 0xb8, 0x4b, 0x73, 0x2a, 0xc4, 0xc5,
- 0xfe, 0x36, 0xc2, 0x74, 0x66, 0x50, 0xbe, 0x9a, 0xcb, 0x18, 0xd2, 0x1c, 0x7c, 0x2a, 0xe8, 0xff,
- 0xfc, 0x21, 0xd8, 0xe2, 0x55, 0xa1, 0x37, 0xeb, 0x58, 0xdb, 0xe4, 0x5e, 0x9f, 0xa8, 0xba, 0xe7,
- 0xcf, 0x82, 0x13, 0x72, 0x9f, 0xae, 0x96, 0x0f, 0x1d, 0x97, 0xb6, 0x69, 0x8b, 0x4d, 0xb7, 0x79,
- 0xd7, 0x4b, 0x96, 0x76, 0xe7, 0x7f, 0x86, 0xd9, 0x03, 0xaf, 0xab, 0x6a, 0x10, 0x33, 0x01, 0x27,
- 0x75, 0x78, 0x11, 0x42, 0x67, 0x84, 0xf3, 0x3b, 0xb4, 0x3c, 0xd0, 0x33, 0x6f, 0xae, 0x7e, 0x06,
- 0xc1, 0x50, 0xd0, 0xde, 0xed, 0x7a, 0xd7, 0x3d, 0xe0, 0x55, 0x0d, 0x77, 0x1c, 0x94, 0x86, 0xac,
- 0x07, 0x35, 0x31, 0xdc, 0x38, 0x4c, 0x96, 0x7c, 0x01, 0x79, 0x95, 0x86, 0x83, 0x0b, 0x0a, 0x61,
- 0x7d, 0x55, 0xa8, 0xd5, 0x28, 0xd1, 0x10, 0x81, 0x4a, 0x55, 0x0c, 0x02, 0xf1, 0x13, 0x5f, 0x85,
- 0x3f, 0x5f, 0x85, 0xaa, 0x1d, 0x6f, 0x36, 0x69, 0x9f, 0xf4, 0x17, 0x36, 0x6d, 0x8d, 0xbe, 0xe1,
- 0x86, 0xe3, 0x96, 0xc6, 0x9c, 0x5c, 0x26, 0xdc, 0x69, 0x1c, 0x5d, 0x5a, 0xd1, 0xc1, 0xc2, 0x10,
- 0xb2, 0xcf, 0x75, 0x95, 0xd1, 0xd9, 0x54, 0x65, 0x8e, 0xb1, 0x58, 0xa5, 0xee, 0xdd, 0xa5, 0xb5,
- 0xa3, 0xed, 0x32, 0x3a, 0x32, 0x4c, 0xb4, 0x5c, 0x4a, 0xa5, 0x4f, 0x89, 0xd5, 0xeb, 0x62, 0xce,
- 0xcf, 0x96, 0x46, 0x0d, 0xe5, 0xe8, 0x7c, 0x72, 0xfd, 0x21, 0x49, 0x06, 0xde, 0x0e, 0x45, 0x5c,
- 0xf0, 0x72, 0xf8, 0x23, 0x3d, 0xa6, 0x41, 0x9b, 0xb0, 0x72, 0xc6, 0x1a, 0xa5, 0x5a, 0xe1, 0x62,
- 0xa3, 0x83, 0xdb, 0x4a, 0x9f, 0x47, 0x25, 0x96, 0xf8, 0x63, 0x59, 0x19, 0x38, 0xb5, 0x5f, 0x4f,
- 0xea, 0x4f, 0xe1, 0x05, 0xa8, 0x53, 0x54, 0x42, 0x19, 0x79, 0xd1, 0xc8, 0x19, 0x1d, 0x99, 0xee,
- 0xc4, 0x31, 0x16, 0xb8, 0x33, 0x6c, 0xe6, 0xf0, 0x2d, 0x51, 0x74, 0x7c, 0x74, 0x62, 0xe7, 0xae,
- 0x0b, 0x4c, 0x71, 0x4b, 0x8d, 0x1c, 0x34, 0x21, 0xc6, 0xef, 0x16, 0x39, 0xcb, 0x1c, 0x41, 0x63,
- 0x05, 0x9b, 0xaf, 0x2a, 0x3e, 0x61, 0x5f, 0x05, 0xbb, 0x75, 0x4b, 0x94, 0x96, 0x7c, 0x19, 0xdb,
- 0x4e, 0xc1, 0xf9, 0x9d, 0x67, 0x50, 0xc7, 0x20, 0xd3, 0x00, 0x8d, 0x7b, 0x1c, 0x90, 0xb9, 0x7c,
- 0xc0, 0xa7, 0xb7, 0x2f, 0x22, 0x07, 0x7b, 0xbf, 0xdb, 0x80, 0xd8, 0x2a, 0xa1, 0x6b, 0xc9, 0x4e,
- 0xd5, 0xc1, 0x24, 0x06, 0xab, 0x07, 0x72, 0x61, 0x90, 0x58, 0xfc, 0xc2, 0xf3, 0x6f, 0x30, 0x09,
- 0xa4, 0xa4, 0x54, 0x80, 0xc6, 0xe6, 0x3a, 0x23, 0x6b, 0x18, 0x12, 0xba, 0x13, 0x7f, 0xdd, 0x71,
- 0xf6, 0xd4, 0xb6, 0x48, 0x9b, 0xa3, 0xdd, 0xff, 0xf0, 0x7f, 0x46, 0x8f, 0x67, 0x87, 0xd9, 0x85,
- 0xcd, 0x43, 0xed, 0xfe, 0xe6, 0xf6, 0x25, 0x95, 0x75, 0xc1, 0x4b, 0xd9, 0x75, 0x54, 0x85, 0x77,
- 0xad, 0xc3, 0xff, 0xce, 0xbc, 0x42, 0x8a, 0xb8, 0x0c, 0x88, 0xeb, 0xc1, 0x00, 0x0c, 0xdc, 0x70,
- 0x8c, 0x90, 0x77, 0xf1, 0x4f, 0x7c, 0x3e, 0xf4, 0x54, 0x2d, 0xae, 0xd5, 0xbe, 0x01, 0x7e, 0xf6,
- 0xd5, 0x7c, 0x6a, 0xe7, 0x1c, 0x95, 0x2d, 0x0c, 0xbb, 0xdb, 0x55, 0x5d, 0x56, 0x77, 0xfc, 0x38,
- 0xf8, 0x7d, 0xb6, 0x8a, 0x62, 0xd4, 0x26, 0xef, 0x92, 0x03, 0xd5, 0x83, 0xe7, 0xb0, 0x6d, 0x80,
- 0xff, 0xcc, 0xec, 0xa6, 0xc3, 0x80, 0x2a, 0x21, 0x02, 0x5b, 0xa1, 0x0c, 0xfe, 0xc2, 0x26, 0x65,
- 0x0a, 0xb5, 0x1d, 0x6f, 0x70, 0x7d, 0xfe, 0x8d, 0xb4, 0xc6, 0xff, 0x08, 0xca, 0x1a, 0xb5, 0x4a,
- 0x52, 0x31, 0xd4, 0x71, 0xc6, 0xcf, 0xe5, 0x3e, 0xdf, 0x15, 0x7c, 0xb3, 0xf0, 0xfa, 0x59, 0x2c,
- 0x7d, 0xc3, 0x27, 0xc7, 0x46, 0xf6, 0x65, 0xd6, 0x7a, 0x0f, 0xf7, 0xfe, 0xc3, 0x6c, 0xeb, 0x9d,
- 0xa2, 0x2a, 0x73, 0x1d, 0x2d, 0xf0, 0xb1, 0xb1, 0xff, 0x31, 0xf0, 0x9b, 0x35, 0x3e, 0x02, 0x44,
- 0x53, 0x70, 0x72, 0x54, 0x8f, 0xb0, 0x92, 0x0a, 0x45, 0x83, 0xb2, 0xea, 0x35, 0xb7, 0x72, 0x5e,
- 0x9b, 0xf0, 0x4e, 0x89, 0x10, 0x92, 0x0e, 0x93, 0xdc, 0xf8, 0x87, 0xd2, 0x0b, 0x6c, 0x3f, 0x4c,
- 0x82, 0xd5, 0x52, 0x02, 0x03, 0x30, 0x0d, 0x3a, 0x86, 0x01, 0x88, 0x40, 0xa5, 0x2a, 0x92, 0x04,
- 0x7f, 0x32, 0xa1, 0x33, 0x78, 0xd5, 0xd6, 0x03, 0xbc, 0x8c, 0xec, 0x6b, 0x75, 0xbe, 0x43, 0x99,
- 0x18, 0x32, 0xc2, 0xd7, 0x34, 0x75, 0xb0, 0x86, 0x45, 0x48, 0xf9, 0x4a, 0xd5, 0x13, 0x4b, 0x1c,
- 0xf1, 0x39, 0x4c, 0x69, 0x30, 0x8b, 0xe1, 0x33, 0x62, 0xdc, 0x62, 0x52, 0x9c, 0x0a, 0xc2, 0x44,
- 0x60, 0xcf, 0x9d, 0xa9, 0xe4, 0x19, 0xb9, 0x3c, 0xba, 0x8f, 0x00, 0x25, 0xd9, 0x6f, 0x47, 0xd8,
- 0xee, 0xb0, 0x3f, 0x06, 0xd5, 0x56, 0x71, 0xf5, 0x8a, 0xc7, 0x05, 0xc8, 0xec, 0xc0, 0xec, 0x7a,
- 0x16, 0xdd, 0x1c, 0x95, 0x99, 0xfc, 0xae, 0xaa, 0x74, 0x4e, 0x84, 0x92, 0x79, 0x18, 0x44, 0x82,
- 0x24, 0x64, 0x9a, 0xf0, 0xf6, 0xd2, 0xb3, 0xe1, 0xb4, 0xb3, 0x35, 0x0f, 0x09, 0xeb, 0xad, 0x36,
- 0xb0, 0x2a, 0x73, 0x6b, 0xaf, 0xe0, 0x78, 0xf5, 0x02, 0x0a, 0xcd, 0x0c, 0x62, 0xf0, 0xb9, 0x94,
- 0x42, 0x6c, 0xb5, 0xb2, 0x07, 0x6f, 0x87, 0x0a, 0x0a, 0xb4, 0x8a, 0x63, 0xb9, 0x21, 0x86, 0xd3,
- 0x0f, 0x67, 0xf9, 0x8a, 0x03, 0xef, 0xf0, 0x81, 0x6f, 0xfc, 0x25, 0x93, 0x1d, 0x60, 0x1c, 0x03,
- 0xda, 0x52, 0x63, 0x3e, 0xd6, 0x44, 0x29, 0x78, 0x2a, 0xac, 0x66, 0xd7, 0x9d, 0xbd, 0x41, 0xa9,
- 0xb9, 0xef, 0x09, 0x2e, 0x3d, 0xc0, 0xe5, 0x79, 0x9b, 0x3b, 0x12, 0x22, 0x46, 0x80, 0x07, 0x25,
- 0x8d, 0x6f, 0x0e, 0x4a, 0xb4, 0x36, 0x64, 0xec, 0xa6, 0x1c, 0x17, 0x62, 0xe2, 0x67, 0xee, 0x73,
- 0xc2, 0x36, 0xcb, 0xcf, 0x5e, 0x53, 0x54, 0x7e, 0x94, 0x24, 0x95, 0x80, 0x1d, 0x5e, 0xe9, 0xde,
- 0x99, 0x1d, 0xd9, 0xc4, 0xf5, 0x7f, 0x6c, 0xf0, 0x9e, 0x67, 0x6d, 0xef, 0x67, 0xea, 0x4f, 0x45,
- 0x97, 0x81, 0x0a, 0x7b, 0x30, 0x28, 0x4d, 0xa5, 0xd6, 0x98, 0xe1, 0x9e, 0xa3, 0x6d, 0xf8, 0x5b,
- 0x00, 0xc0, 0xa8, 0x55, 0x4d, 0x1a, 0x4d, 0x69, 0xfc, 0xe4, 0x79, 0x3d, 0x3f, 0xc6, 0xa7, 0xb9,
- 0xb1, 0xea, 0x1e, 0x37, 0xc1, 0xd1, 0x86, 0xa5, 0xef, 0xaf, 0xcf, 0xcd, 0xf1, 0x77, 0xa7, 0x6c,
- 0x1a, 0x9d, 0xc7, 0xd0, 0xc9, 0x0e, 0x77, 0x30, 0xd9, 0x96, 0xaf, 0xea, 0xde, 0x3f, 0xcf, 0xd2,
- 0xab, 0x95, 0x25, 0x2a, 0xd6, 0xa2, 0xa7, 0x46, 0xc6, 0x2f, 0x15, 0x99, 0x04, 0x2f, 0x92, 0x6d,
- 0x7a, 0xbc, 0x55, 0xa1, 0xeb, 0x1f, 0x8c, 0xab, 0x82, 0x78, 0x8f, 0xcb, 0x3b, 0xec, 0x02, 0xbd,
- 0xbf, 0x30, 0xda, 0x18, 0x8f, 0x2d, 0x27, 0xc4, 0x0a, 0xb6, 0x1b, 0x47, 0x12, 0xae, 0x73, 0x16,
- 0x56, 0x9f, 0xea, 0xa9, 0x4a, 0xc6, 0x37, 0xc7, 0x02, 0x42, 0xf6, 0xf0, 0xfd, 0x4d, 0x0c, 0xec,
- 0xc6, 0x4e, 0x5a, 0xfe, 0x5f, 0x55, 0x60, 0xac, 0x4c, 0xef, 0x11, 0x7c, 0x5a, 0xd7, 0x07, 0x25,
- 0x07, 0xb7, 0xfd, 0xed, 0x51, 0xb6, 0x83, 0x92, 0x30, 0xd5, 0x21, 0xe5, 0xaf, 0xec, 0x6d, 0xff,
- 0x04, 0xb2, 0xb1, 0xac, 0x62, 0x2d, 0xcd, 0x7c, 0xde, 0xed, 0xb2, 0xbc, 0x42, 0xb8, 0xff, 0x61,
- 0x59, 0xd7, 0xf7, 0x5a, 0x5d, 0xda, 0x2f, 0x80, 0xed, 0xae, 0xa6, 0xe1, 0x91, 0x8d, 0x09, 0x64,
- 0xf7, 0x56, 0x8d, 0x7a, 0xdd, 0xc8, 0xfb, 0x5b, 0x7f, 0xb9, 0x8e, 0x47, 0xa7, 0x3b, 0x30, 0x77,
- 0x42, 0xc2, 0x7c, 0x4c, 0x5e, 0x4f, 0xd4, 0xd9, 0x5d, 0xef, 0xbf, 0x4c, 0x7e, 0x12, 0x23, 0x91,
- 0x6a, 0x9c, 0xa1, 0xb8, 0x2a, 0xef, 0x73, 0x28, 0xe7, 0x77, 0xb7, 0xe8, 0x8f, 0x14, 0x9d, 0x31,
- 0x04, 0xb8, 0x97, 0xf0, 0xb9, 0xdd, 0xef, 0x01, 0x3d, 0x6b, 0x1e, 0xcc, 0x35, 0x9a, 0xac, 0xfe,
- 0xe9, 0x2c, 0xb3, 0xca, 0xf8, 0x27, 0x56, 0xd0, 0xb9, 0x53, 0x74, 0x09, 0x4d, 0xae, 0x5c, 0x8b,
- 0xbc, 0xc4, 0x4b, 0xdb, 0x75, 0x55, 0x51, 0x57, 0x68, 0x51, 0x69, 0x74, 0x8d, 0xa7, 0xcf, 0x24,
- 0x5d, 0xc5, 0xf6, 0x79, 0xaf, 0xc6, 0xae, 0x45, 0x5d, 0x44, 0x80, 0x12, 0x0a, 0x7d, 0x27, 0x37,
- 0x1c, 0x93, 0x8c, 0x0c, 0x1b, 0x7e, 0x39, 0x24, 0x4d, 0x58, 0xa1, 0xe4, 0x98, 0x61, 0x10, 0xf2,
- 0xfa, 0xe7, 0x52, 0x37, 0x80, 0xa8, 0x60, 0x35, 0x7c, 0x8a, 0x49, 0xa3, 0x44, 0x23, 0x20, 0xb5,
- 0x18, 0x9a, 0xe6, 0x51, 0x16, 0x75, 0xdf, 0x46, 0x57, 0x00, 0xea, 0xaf, 0x86, 0xe1, 0xa6, 0x68,
- 0x84, 0x62, 0xb7, 0x7b, 0xf3, 0xf5, 0x3b, 0x3f, 0x14, 0xed, 0x5f, 0xed, 0x13, 0xd1, 0x94, 0x9f,
- 0xc7, 0x16, 0x0b, 0x18, 0xa5, 0x1d, 0xf7, 0x27, 0xad, 0xe6, 0x5f, 0x39, 0x2d, 0x48, 0xd9, 0x24,
- 0x9a, 0x50, 0xfe, 0x70, 0x6a, 0xd7, 0xbb, 0x75, 0x77, 0x98, 0x3e, 0x3b, 0x6c, 0xfc, 0xa3, 0xa1,
- 0xe4, 0x9d, 0x35, 0x3e, 0x02, 0x42, 0xc7, 0xf0, 0xfa, 0x5b, 0x10, 0xd9, 0x1c, 0x94, 0x44, 0x7c,
- 0x9f, 0x55, 0x60, 0xa8, 0x26, 0x6f, 0x64, 0x9e, 0xcd, 0x65, 0x62, 0xf6, 0x07, 0x24, 0x35, 0xe7,
- 0x72, 0x52, 0x1a, 0xb0, 0x6f, 0x0d, 0x8b, 0xa5, 0xbf, 0x6b, 0x94, 0xe6, 0x27, 0xb6, 0xcf, 0x4d,
- 0x72, 0x30, 0x59, 0xbc, 0xd4, 0x57, 0x4b, 0xb5, 0xbf, 0x59, 0x71, 0x2c, 0x7c, 0x8a, 0x69, 0xa3,
- 0x79, 0x86, 0x32, 0x99, 0x6b, 0xa6, 0x83, 0x4f, 0x48, 0xd7, 0xbe, 0xdc, 0xd2, 0x29, 0x04, 0x73,
- 0x72, 0xaf, 0x37, 0x4c, 0x09, 0x30, 0x33, 0xdf, 0x60, 0xb6, 0x9e, 0x6f, 0x8f, 0x77, 0x1f, 0x33,
- 0x5e, 0x8a, 0x75, 0x1e, 0x6b, 0xc0, 0xed, 0x81, 0xcf, 0xc5, 0xf0, 0xc3, 0xf0, 0x95, 0xd3, 0x3b,
- 0x47, 0x42, 0xe6, 0x29, 0xb4, 0xef, 0x6f, 0x12, 0x63, 0x3d, 0x98, 0xa3, 0x4f, 0x81, 0xc3, 0xfc,
- 0xb3, 0xf4, 0x35, 0xb7, 0x2c, 0xa7, 0x0e, 0xeb, 0xe3, 0xdc, 0xc0, 0xdd, 0x75, 0x2b, 0x76, 0x9e,
- 0xbe, 0x0a, 0x0d, 0x82, 0x54, 0xcd, 0xab, 0x01, 0x5b, 0x58, 0x6a, 0xd8, 0xbb, 0x75, 0x4e, 0x2a,
- 0xd0, 0x2f, 0x58, 0xce, 0x8b, 0x59, 0x2c, 0x9c, 0xab, 0x01, 0xc9, 0x6e, 0x1b, 0xc1, 0x12, 0xa2,
- 0xb6, 0x80, 0x07, 0x25, 0x8c, 0xad, 0xc1, 0x7e, 0x08, 0x4c, 0x54, 0xfa, 0x8d, 0x7c, 0x95, 0x81,
- 0x47, 0xe5, 0xe6, 0x4f, 0x04, 0xd0, 0xf2, 0x29, 0xb0, 0x86, 0xa2, 0x1a, 0xca, 0x82, 0xd0, 0x19,
- 0xda, 0xd3, 0x1c, 0x33, 0xb8, 0x61, 0x93, 0xf2, 0x1f, 0x02, 0xd9, 0x5d, 0xc8, 0x43, 0xdd, 0xd5,
- 0x7c, 0x07, 0x34, 0xac, 0x54, 0x3f, 0xcb, 0x2c, 0x5e, 0x59, 0xb7, 0x43, 0x73, 0xa8, 0x23, 0xf0,
- 0x7a, 0xd3, 0xde, 0x58, 0xb1, 0x1d, 0x89, 0xf3, 0x26, 0x92, 0x88, 0xb4, 0x10, 0x7c, 0x19, 0x5f,
- 0x94, 0xbb, 0xe5, 0x12, 0xae, 0xde, 0xcb, 0xaa, 0x71, 0x1a, 0xe2, 0xee, 0xe0, 0x9c, 0x8a, 0x36,
- 0xdc, 0xef, 0x16, 0x21, 0x04, 0xe6, 0xc9, 0xc3, 0xc0, 0x52, 0x55, 0xf7, 0x53, 0xf5, 0x9c, 0xf5,
- 0x44, 0x53, 0x8f, 0x7e, 0x22, 0xa7, 0xa4, 0x06, 0x80, 0x92, 0x17, 0xb5, 0x54, 0x58, 0x50, 0xe1,
- 0x4e, 0xfb, 0x10, 0x6f, 0xb0, 0x15, 0x64, 0x86, 0xce, 0xbc, 0xe5, 0x80, 0xd9, 0x6b, 0xc4, 0x0d,
- 0x8d, 0xce, 0x42, 0x36, 0xf0, 0x02, 0xed, 0xbe, 0xe1, 0xfd, 0xdd, 0xce, 0x55, 0x22, 0x7d, 0xfd,
- 0x7b, 0x05, 0xf0, 0x53, 0x22, 0x49, 0x48, 0x36, 0xf0, 0x72, 0x1a, 0x79, 0x39, 0x2c, 0x0d, 0x58,
- 0x5e, 0x13, 0x7e, 0xc2, 0xf9, 0xf8, 0x81, 0x89, 0x68, 0x7b, 0x1a, 0xc5, 0xef, 0xa1, 0xce, 0x01,
- 0xb9, 0x20, 0x67, 0x96, 0x58, 0x01, 0x7c, 0x07, 0x55, 0x5b, 0x55, 0x77, 0xa6, 0x38, 0x92, 0xfc,
- 0x59, 0xb6, 0x60, 0x12, 0x5f, 0x98, 0x01, 0xc1, 0x98, 0xdb, 0x7d, 0xff, 0x6f, 0x7a, 0xc5, 0x9e,
- 0xa4, 0xd1, 0x1e, 0xa2, 0x3a, 0xe0, 0x27, 0xd9, 0x18, 0x6d, 0x7f, 0xa8, 0xc1, 0x39, 0x3a, 0x52,
- 0x4c, 0x72, 0x7a, 0x08, 0xef, 0xb9, 0xa8, 0x73, 0x35, 0x31, 0x7c, 0xfb, 0x30, 0x2a, 0x98, 0x3f,
- 0xb2, 0xc0, 0x51, 0xa5, 0xb7, 0xce, 0xf1, 0xc8, 0x54, 0xf8, 0xec, 0x69, 0x28, 0x74, 0x53, 0x22,
- 0x75, 0x09, 0xeb, 0x85, 0x24, 0x44, 0x97, 0x83, 0x09, 0xb8, 0x49, 0x78, 0x53, 0x34, 0xcc, 0xdb,
- 0x22, 0x76, 0xf6, 0xd6, 0xc2, 0x15, 0xc7, 0x61, 0xaa, 0x27, 0xf7, 0x14, 0x1a, 0xb7, 0xad, 0xf6,
- 0xc0, 0x20, 0xaa, 0xb0, 0x33, 0xa8, 0x64, 0x7e, 0xe7, 0x69, 0x2d, 0x6b, 0xf8, 0x64, 0xee, 0xaf,
- 0xb0, 0x2d, 0x2f, 0xae, 0xba, 0xb2, 0x52, 0xa4, 0xba, 0x4f, 0xc9, 0x7e, 0x68, 0xc1, 0x49, 0xd9,
- 0x92, 0xdb, 0x5f, 0x83, 0xb9, 0xb3, 0xc6, 0x7a, 0xeb, 0x44, 0x3d, 0x63, 0x6b, 0x01, 0x00, 0xf9,
- 0x58, 0x09, 0x72, 0x22, 0x70, 0x15, 0x30, 0x1d, 0x4e, 0xb2, 0x97, 0x53, 0xc8, 0x89, 0x85, 0x5f,
- 0xd0, 0x1b, 0x00, 0x88, 0xf0, 0xc3, 0x86, 0x2c, 0x21, 0x07, 0xe9, 0x2c, 0x24, 0x8c, 0x94, 0x90,
- 0x31, 0xb1, 0x7b, 0xff, 0xf6, 0xdf, 0xf9, 0xd8, 0x4b, 0xdc, 0x7d, 0xaa, 0x18, 0xe7, 0x37, 0xd3,
- 0x48, 0xa5, 0x04, 0x28, 0xc0, 0x5d, 0xf9, 0x0b, 0xb0, 0x96, 0x97, 0x3a, 0x7c, 0xf7, 0x21, 0x57,
- 0xac, 0x9c, 0x98, 0x34, 0xb9, 0xfa, 0xb0, 0x49, 0x79, 0x5e, 0x86, 0xad, 0x29, 0x25, 0x31, 0x03,
- 0xdf, 0x1b, 0xd9, 0xbb, 0xcb, 0x4c, 0x8a, 0x8f, 0xbd, 0x58, 0x31, 0xc7, 0x0c, 0x02, 0x0e, 0xa5,
- 0xd5, 0x8e, 0x23, 0xce, 0x0e, 0x24, 0xd7, 0xd3, 0x01, 0x25, 0xf0, 0xf8, 0x1c, 0xae, 0x86, 0x4f,
- 0xad, 0xb2, 0xf4, 0xf1, 0xe3, 0xcc, 0x8d, 0xec, 0xae, 0x01, 0xc7, 0xa8, 0x8c, 0x5e, 0xe0, 0xe4,
- 0x0c, 0x5a, 0x0e, 0x48, 0xa3, 0x56, 0x2d, 0xa1, 0x31, 0x62, 0x56, 0x1c, 0x48, 0x7e, 0x4d, 0x46,
- 0x26, 0x10, 0x65, 0x1d, 0x45, 0x38, 0x1f, 0xbe, 0x7e, 0x5e, 0x70, 0x26, 0x5f, 0x13, 0xa7, 0xf1,
- 0x8b, 0xc8, 0x0c, 0xc8, 0x98, 0xbc, 0xbd, 0x7e, 0x17, 0xce, 0xad, 0x3c, 0x27, 0xd9, 0x35, 0x8a,
- 0xfd, 0x47, 0x83, 0x34, 0x43, 0x00, 0x1b, 0x19, 0xbf, 0xf3, 0xed, 0xf7, 0xae, 0x48, 0x65, 0xcc,
- 0x34, 0x3a, 0x62, 0x5a, 0x30, 0x45, 0xb5, 0x84, 0x55, 0x56, 0x21, 0x7b, 0xb9, 0xad, 0xc6, 0xbc,
- 0x16, 0x8e, 0xb0, 0x63, 0x94, 0x5a, 0xb7, 0xbf, 0x4f, 0x00, 0x23, 0x07, 0x2f, 0x1f, 0x40, 0x37,
- 0xc4, 0xf0, 0x88, 0x7a, 0xe6, 0x37, 0x89, 0xfd, 0xbb, 0xfd, 0x48, 0x88, 0x70, 0x3b, 0x69, 0x5a,
- 0x46, 0xdb, 0xbb, 0x75, 0x06, 0xc7, 0xff, 0x39, 0xd2, 0x9b, 0x79, 0x3c, 0x0e, 0xa5, 0xdd, 0x64,
- 0x80, 0x12, 0x25, 0x09, 0x3f, 0x07, 0x0c, 0x0e, 0xc7, 0xaf, 0x2d, 0x9e, 0xc1, 0xc9, 0x34, 0x6a,
- 0xf9, 0xba, 0x89, 0x99, 0x91, 0x2f, 0xc6, 0xc2, 0x77, 0xe8, 0x92, 0xd5, 0x05, 0x01, 0x3e, 0x18,
- 0x2f, 0x8b, 0xd1, 0x4c, 0x46, 0x00, 0x13, 0xe1, 0x28, 0x99, 0x34, 0xd2, 0x9f, 0xf5, 0xb7, 0x27,
- 0xf1, 0x89, 0xe6, 0x91, 0x9e, 0x8a, 0x78, 0x42, 0x64, 0xde, 0xd8, 0x50, 0xc0, 0x70, 0xfb, 0x9b,
- 0xad, 0x95, 0x11, 0xc1, 0x3f, 0xa7, 0x1c, 0xfc, 0x28, 0xe8, 0xad, 0x25, 0x5b, 0x13, 0xb5, 0x0b,
- 0xb8, 0x48, 0xa4, 0x25, 0xec, 0xfc, 0xc9, 0x0d, 0x29, 0xc0, 0x47, 0x86, 0xcf, 0xf4, 0xe6, 0x74,
- 0x55, 0x09, 0x6d, 0x3e, 0xef, 0xc4, 0xdb, 0x49, 0xe7, 0x01, 0xf9, 0x81, 0x0e, 0x15, 0x0d, 0x3d,
- 0xd7, 0x28, 0x4c, 0x34, 0x39, 0x39, 0x98, 0xec, 0x0e, 0xd2, 0x02, 0x5b, 0x8f, 0x0c, 0x8e, 0xed,
- 0xa7, 0xdc, 0x36, 0x48, 0x71, 0x72, 0xef, 0x7a, 0xfc, 0x9f, 0x92, 0xfb, 0x00, 0x4a, 0xea, 0x2e,
- 0xf3, 0xcc, 0xe0, 0x87, 0x89, 0x2a, 0xc0, 0x2d, 0xe3, 0xf7, 0x2d, 0x8e, 0xc2, 0xd6, 0xe7, 0xfe,
- 0xec, 0x7a, 0x48, 0xc5, 0x6e, 0x0e, 0xbe, 0x07, 0xe8, 0x97, 0x0d, 0x24, 0xd1, 0xa0, 0xa2, 0x9e,
- 0x05, 0x19, 0x5e, 0x18, 0xfa, 0x5f, 0xd6, 0xd0, 0x7c, 0x21, 0x8f, 0xf9, 0xc9, 0xc3, 0x5c, 0x24,
- 0xf8, 0x5f, 0x6f, 0xe4, 0xb8, 0xfa, 0xab, 0xe7, 0xa2, 0x81, 0x33, 0x03, 0x97, 0x80, 0xdb, 0x7c,
- 0xd0, 0xcd, 0x05, 0x33, 0x84, 0xec, 0x27, 0x9f, 0x0a, 0xb5, 0x9d, 0xcf, 0x7c, 0x34, 0x03, 0xe0,
- 0x1c, 0x43, 0xc1, 0x65, 0x3f, 0x01, 0x9d, 0x1a, 0x7c, 0x9f, 0xf7, 0xc6, 0xed, 0x39, 0x52, 0x8e,
- 0xf0, 0x0f, 0xa3, 0x74, 0x2d, 0xce, 0x93, 0x22, 0x75, 0xf0, 0x6d, 0x06, 0xfd, 0x54, 0xec, 0x1a,
- 0x31, 0xc8, 0xe5, 0x21, 0xcb, 0xbf, 0xac, 0x88, 0xcb, 0x30, 0x3a, 0xf0, 0x3d, 0xe6, 0x65, 0x79,
- 0x54, 0x69, 0xa1, 0x80, 0x56, 0x52, 0xda, 0x7a, 0x76, 0xef, 0xfb, 0x27, 0xc3, 0x92, 0x53, 0xca,
- 0x19, 0x29, 0x73, 0x81, 0x1a, 0x96, 0xc8, 0x51, 0x10, 0x0b, 0x10, 0x93, 0x37, 0xb5, 0xb0, 0xe6,
- 0xe4, 0x80, 0xdb, 0xe0, 0x91, 0x6b, 0x8c, 0x1c, 0x7e, 0x8e, 0x51, 0x6f, 0xee, 0xd5, 0x87, 0x0a,
- 0x18, 0x7f, 0x50, 0x98, 0x3d, 0x9f, 0x92, 0x7b, 0xd5, 0x83, 0xeb, 0x30, 0x6d, 0x80, 0x40, 0x64,
- 0xa9, 0x57, 0x15, 0x80, 0x5a, 0x4e, 0x7e, 0x98, 0x96, 0x4a, 0x8e, 0xc3, 0xfe, 0x4d, 0x6d, 0x02,
- 0x1f, 0x5b, 0x6b, 0x99, 0x2f, 0x2d, 0x8a, 0x71, 0x60, 0x13, 0xc4, 0x38, 0x00, 0x82, 0x9a, 0xc3,
- 0x02, 0x0a, 0x36, 0x0c, 0xb0, 0x12, 0x67, 0x86, 0x63, 0x85, 0x34, 0x87, 0x7d, 0x67, 0x47, 0xc7,
- 0x73, 0xa3, 0x8f, 0x7b, 0x3e, 0xf8, 0x6d, 0x5b, 0x37, 0x4c, 0x29, 0xf6, 0x83, 0x2b, 0xd1, 0xf3,
- 0xaa, 0x4f, 0xec, 0x6a, 0xad, 0xba, 0x49, 0x1a, 0x4e, 0x61, 0xb1, 0xb0, 0x6f, 0x05, 0xe4, 0x44,
- 0x7c, 0x30, 0x36, 0x0a, 0x28, 0x4d, 0x60, 0xc0, 0xba, 0xb5, 0xcc, 0x5d, 0x5d, 0xbb, 0x60, 0x12,
- 0x5f, 0x00, 0x3f, 0xa7, 0xf0, 0xaf, 0x34, 0x62, 0xdf, 0xdb, 0xff, 0x34, 0xde, 0x19, 0x27, 0x11,
- 0x78, 0x01, 0xc2, 0x4d, 0xe8, 0xd1, 0x9e, 0xca, 0xff, 0x02, 0x2d, 0xbd, 0xf9, 0x10, 0x0b, 0xdd,
- 0x1a, 0xdc, 0xac, 0x77, 0x64, 0x88, 0xb5, 0xeb, 0xba, 0xb7, 0xc0, 0xb7, 0x2d, 0xcf, 0x0e, 0x4a,
- 0xa3, 0x56, 0x43, 0xd1, 0xb2, 0x92, 0x6e, 0x03, 0x2a, 0x1f, 0x9b, 0x4c, 0x5d, 0x65, 0x61, 0x80,
- 0x41, 0x17, 0x86, 0x01, 0xcb, 0xc0, 0xcc, 0x73, 0xda, 0x9c, 0x9e, 0x5e, 0x93, 0x90, 0x11, 0xcf,
- 0xc3, 0x0c, 0x95, 0x34, 0x83, 0x00, 0x02, 0xad, 0xcd, 0x1c, 0x23, 0xca, 0x90, 0xd1, 0x63, 0xd9,
- 0xee, 0x50, 0x05, 0x28, 0xf2, 0xe6, 0x77, 0x4c, 0x1a, 0x94, 0xac, 0xed, 0x48, 0x62, 0xf6, 0xbb,
- 0x76, 0xf8, 0x85, 0xe0, 0x4f, 0x3a, 0x2c, 0x19, 0xd8, 0xf1, 0x09, 0xc4, 0x36, 0x58, 0xdb, 0xaa,
- 0x30, 0x0d, 0xf1, 0x65, 0xe0, 0x43, 0xa3, 0x7e, 0x50, 0x17, 0x05, 0x99, 0x87, 0xc4, 0x03, 0x84,
- 0x83, 0x92, 0xd6, 0x67, 0x01, 0x20, 0x63, 0x78, 0x8a, 0xb4, 0xf7, 0xde, 0x75, 0x54, 0x85, 0x47,
- 0x2f, 0xc3, 0x37, 0xc1, 0xaa, 0xa8, 0xde, 0xc9, 0x88, 0x86, 0xe0, 0xe4, 0xaa, 0x9d, 0x35, 0xba,
- 0x49, 0xd1, 0x44, 0x1a, 0x5a, 0xc3, 0x62, 0xeb, 0xb6, 0x4f, 0x63, 0x7c, 0x3e, 0x8e, 0x4b, 0x2d,
- 0xb0, 0xd6, 0xd8, 0x2f, 0x3a, 0xbc, 0x80, 0x56, 0xbf, 0xc1, 0x14, 0x23, 0x4f, 0x12, 0x72, 0xfe,
- 0xed, 0x77, 0xd6, 0x52, 0x8b, 0x05, 0x3c, 0x7c, 0x0a, 0x1b, 0x04, 0x55, 0x21, 0x47, 0x1c, 0x16,
- 0x25, 0x60, 0x86, 0x01, 0xad, 0x09, 0x1b, 0xe6, 0x66, 0x88, 0x47, 0x66, 0x12, 0x2e, 0x5c, 0x5a,
- 0xd3, 0xe8, 0x3d, 0x76, 0xf4, 0x95, 0x4a, 0x3b, 0x4e, 0x8d, 0xb2, 0xc0, 0xca, 0x2a, 0xac, 0xbe,
- 0x10, 0xbb, 0x5f, 0x9e, 0xd7, 0x9f, 0x25, 0x80, 0x69, 0x1b, 0xff, 0xcf, 0xe5, 0x42, 0xde, 0xcc,
- 0xf0, 0xe3, 0x56, 0x85, 0x16, 0x53, 0x40, 0x60, 0x77, 0x55, 0xc8, 0x8b, 0xc0, 0x45, 0x80, 0xe7,
- 0x00, 0x0f, 0x0d, 0x63, 0x0e, 0x5f, 0xb3, 0xc0, 0x73, 0x78, 0xf7, 0xa3, 0x97, 0x87, 0xc5, 0x1f,
- 0x0e, 0x49, 0x93, 0x5e, 0x02, 0x50, 0x73, 0x70, 0xf2, 0xbf, 0xcd, 0x83, 0xa0, 0x81, 0x3f, 0x50,
- 0x25, 0xd5, 0xeb, 0x00, 0xb7, 0xb2, 0xa7, 0x35, 0x7f, 0x7c, 0x44, 0x73, 0xf0, 0x72, 0x44, 0x86,
- 0x69, 0x27, 0x8d, 0x20, 0x16, 0xf4, 0x15, 0x4d, 0x2e, 0x7e, 0xaf, 0xb2, 0x12, 0x81, 0xe6, 0x38,
- 0xe4, 0xb4, 0xb4, 0xd7, 0xa9, 0xfc, 0x5a, 0x1c, 0xe9, 0x3d, 0x7a, 0xc4, 0xf6, 0x91, 0x2c, 0x98,
- 0x00, 0x49, 0x3d, 0xce, 0x47, 0xc8, 0x8f, 0xbf, 0xc9, 0xed, 0xe7, 0x87, 0x1e, 0x75, 0x7d, 0xf6,
- 0xbb, 0x4e, 0x99, 0x52, 0xc0, 0xd2, 0x48, 0x25, 0xc4, 0xc5, 0x93, 0x97, 0xdb, 0x4b, 0x87, 0x33,
- 0xca, 0x64, 0x50, 0x0a, 0x30, 0xa6, 0x50, 0x94, 0xfe, 0x56, 0xa4, 0xbb, 0xc0, 0x24, 0x56, 0xb0,
- 0xd7, 0x55, 0x74, 0x0c, 0x90, 0x6d, 0xe7, 0x4a, 0x00, 0xa0, 0xee, 0x3c, 0x51, 0xdf, 0xf0, 0xec,
- 0x5b, 0xfc, 0xbf, 0xf1, 0xb9, 0xb4, 0x98, 0x00, 0xda, 0x55, 0x45, 0xa8, 0xf0, 0x02, 0xa8, 0xd6,
- 0xe0, 0xe4, 0x54, 0x4f, 0x5d, 0x75, 0xb1, 0xdc, 0xf2, 0x22, 0x80, 0xff, 0xeb, 0x13, 0xf7, 0xb1,
- 0x14, 0xed, 0x07, 0x24, 0xd1, 0xab, 0xe1, 0xc8, 0x53, 0x52, 0x60, 0x25, 0xc8, 0x89, 0xe0, 0x30,
- 0xd2, 0xa4, 0x61, 0xf6, 0x65, 0xc7, 0x3a, 0x19, 0x79, 0x2a, 0x35, 0x03, 0x22, 0x88, 0x65, 0x1f,
- 0x92, 0x65, 0x2d, 0xb1, 0x71, 0xc2, 0x04, 0x16, 0x96, 0x18, 0x2c, 0xa4, 0xd0, 0xc0, 0xdc, 0xac,
- 0x3d, 0xb7, 0x82, 0xb2, 0x3f, 0xc0, 0x1b, 0xff, 0xae, 0x5c, 0xb8, 0x63, 0xd2, 0xb3, 0xd0, 0x55,
- 0xfa, 0xb0, 0xf3, 0xd1, 0xc2, 0x55, 0xb5, 0x6a, 0x5d, 0x60, 0x3d, 0x94, 0xa4, 0x26, 0x6f, 0x5e,
- 0x8e, 0x01, 0xf8, 0xe1, 0xd4, 0x1a, 0x0c, 0xd7, 0x32, 0xcd, 0xf0, 0xdc, 0x70, 0x04, 0x61, 0x42,
- 0xd0, 0x81, 0xaf, 0x12, 0x04, 0x54, 0x76, 0x18, 0x3a, 0x57, 0x09, 0xbe, 0x5b, 0xa8, 0xf0, 0x72,
- 0xa8, 0xb6, 0x60, 0xe4, 0xc2, 0xb5, 0x01, 0x1b, 0x87, 0x91, 0x24, 0x5a, 0xbf, 0x07, 0x95, 0x1d,
- 0xac, 0x1c, 0xcf, 0x66, 0x8d, 0x38, 0x16, 0xf4, 0x0a, 0xe5, 0xd9, 0x58, 0x2f, 0x16, 0x6d, 0x04,
- 0x18, 0x9a, 0x06, 0x01, 0xdc, 0xff, 0x1c, 0xec, 0x23, 0x7c, 0x19, 0xfc, 0x6a, 0x73, 0x9e, 0xbb,
- 0x9c, 0x01, 0x40, 0x7c, 0xc1, 0x80, 0x5d, 0x46, 0x98, 0xe1, 0x92, 0x04, 0xe7, 0x32, 0xc4, 0x1d,
- 0xb8, 0x0e, 0x23, 0x4f, 0x41, 0xc5, 0x81, 0xba, 0xfb, 0x3f, 0xad, 0xb6, 0x94, 0x76, 0xdc, 0x9e,
- 0x0f, 0x9b, 0x33, 0xcf, 0xff, 0xed, 0xbf, 0xf3, 0xd1, 0xc1, 0x1f, 0x59, 0x54, 0xf0, 0xa7, 0x9d,
- 0x1d, 0x3c, 0x5f, 0x28, 0x33, 0x78, 0x9f, 0x85, 0x58, 0x8b, 0x6e, 0xad, 0x23, 0x17, 0x60, 0xc0,
- 0x10, 0x45, 0x16, 0xa0, 0xe4, 0x44, 0x7c, 0x2c, 0x94, 0x1d, 0x24, 0x5a, 0xbf, 0x00, 0x95, 0x17,
- 0x7c, 0x1c, 0x55, 0x40, 0x73, 0x63, 0x44, 0x0a, 0x74, 0xe4, 0xbc, 0xe0, 0xec, 0x7a, 0x11, 0xdd,
- 0x39, 0x2f, 0x24, 0xb8, 0x49, 0xd1, 0x4c, 0x1a, 0xba, 0x43, 0x22, 0x74, 0x0a, 0x32, 0x9a, 0xaf,
- 0x00, 0x0d, 0x66, 0xd3, 0x69, 0x65, 0x6a, 0x1f, 0x80, 0x41, 0xc5, 0xe1, 0xdc, 0xc8, 0x5f, 0xac,
- 0xa1, 0x80, 0x90, 0xee, 0x85, 0x78, 0x1f, 0x22, 0x7c, 0x1b, 0x69, 0xdb, 0x35, 0x87, 0x8c, 0xcb,
- 0x31, 0x69, 0x7c, 0xbf, 0x99, 0xa3, 0xe3, 0xf9, 0x1c, 0xce, 0x82, 0x3b, 0xd7, 0x2f, 0xa5, 0x83,
- 0xfa, 0xb9, 0x31, 0x62, 0xf2, 0x96, 0x85, 0xb2, 0x04, 0x94, 0x8c, 0x18, 0xff, 0xcd, 0x2a, 0x42,
- 0x0c, 0x02, 0xa9, 0x4f, 0xbd, 0x6a, 0xc0, 0x82, 0x9b, 0x4d, 0x25, 0x80, 0x87, 0x22, 0x5b, 0xe0,
- 0x6b, 0x77, 0xba, 0xa3, 0x40, 0xdd, 0x03, 0x9d, 0x19, 0x11, 0xbc, 0x0d, 0xc6, 0x89, 0x35, 0xd6,
- 0xa3, 0x88, 0xaf, 0x17, 0xad, 0x3d, 0xb0, 0x26, 0x42, 0x61, 0xb0, 0x72, 0x08, 0x9a, 0xdd, 0x42,
- 0x83, 0x92, 0x45, 0x37, 0x3a, 0x97, 0x93, 0x55, 0xb4, 0x38, 0xa3, 0x42, 0x2a, 0x62, 0xe2, 0x67,
- 0x4d, 0x1b, 0x98, 0xdb, 0x5d, 0xff, 0xd4, 0xfe, 0x02, 0x80, 0x81, 0x0c, 0xaa, 0x06, 0xa2, 0x96,
- 0xab, 0x20, 0xe4, 0x96, 0xeb, 0xe9, 0x1a, 0xae, 0xb2, 0xae, 0x0c, 0xbf, 0x42, 0xa4, 0xd6, 0x02,
- 0x16, 0x39, 0x4a, 0x9c, 0x73, 0x33, 0xb6, 0xcf, 0xf8, 0x48, 0x1e, 0xf9, 0xe7, 0xdf, 0xb3, 0xb4,
- 0xa1, 0x85, 0x23, 0x81, 0x62, 0xe0, 0x4b, 0xf2, 0x76, 0xb9, 0xc4, 0xf2, 0x61, 0x56, 0x7d, 0xba,
- 0x86, 0x01, 0x17, 0x86, 0x48, 0xe0, 0x14, 0x61, 0x07, 0xbf, 0x5c, 0x58, 0xd0, 0xe1, 0xfc, 0xb3,
- 0x56, 0x1b, 0xe7, 0x46, 0x9e, 0x15, 0x11, 0x19, 0x12, 0x39, 0x57, 0xf8, 0xdd, 0xe0, 0x84, 0xf8,
- 0x0c, 0x6e, 0x27, 0xd3, 0x9f, 0x22, 0xd5, 0x50, 0x71, 0x48, 0xa2, 0x8a, 0xe0, 0xe4, 0xa5, 0x85,
- 0x5a, 0xed, 0x00, 0x24, 0xb2, 0x7f, 0x9f, 0xa5, 0x41, 0xf5, 0xc1, 0xc9, 0x55, 0x47, 0xf1, 0xf5,
- 0x63, 0xb8, 0xc9, 0x8b, 0x17, 0x70, 0x63, 0xd5, 0xee, 0xef, 0xc9, 0x78, 0x47, 0xc1, 0x9d, 0x13,
- 0x00, 0xc4, 0xf2, 0x8d, 0xf6, 0x18, 0x7f, 0xe7, 0xcc, 0xab, 0x86, 0xcd, 0xa8, 0x1b, 0x13, 0xd1,
- 0x4c, 0x33, 0x96, 0x98, 0x81, 0xbc, 0x44, 0x1a, 0x0f, 0x91, 0x21, 0xab, 0x98, 0xaa, 0x92, 0x04,
- 0xaf, 0x32, 0x75, 0x1b, 0x26, 0xf0, 0xf5, 0x60, 0xe0, 0x16, 0x60, 0xfe, 0xb9, 0xf8, 0x78, 0x13,
- 0xb7, 0xd0, 0xb6, 0x9d, 0xc3, 0x00, 0x55, 0x46, 0x59, 0x5d, 0xf0, 0xe1, 0x38, 0x5a, 0xcb, 0x01,
- 0xec, 0xa2, 0x02, 0x31, 0xf5, 0x0c, 0xff, 0xae, 0xe2, 0xcd, 0xa3, 0x09, 0x70, 0x00, 0x7b, 0x78,
- 0x29, 0x86, 0x05, 0x86, 0x62, 0x18, 0x05, 0x84, 0x09, 0xaa, 0x58, 0x30, 0xff, 0x9d, 0x10, 0x2d,
- 0xb7, 0x79, 0xfb, 0xd7, 0x83, 0x92, 0x07, 0x6e, 0x6c, 0xde, 0x02, 0xf4, 0xb4, 0xa2, 0xb7, 0x01,
- 0xc8, 0x8b, 0x55, 0x14, 0x2e, 0xbd, 0x6f, 0xf4, 0x4b, 0x75, 0xc6, 0x00, 0x0e, 0x48, 0x1b, 0x56,
- 0x5e, 0x8d, 0xaf, 0x5d, 0x6f, 0xbd, 0x88, 0xc4, 0x0c, 0x2e, 0x04, 0xfa, 0x69, 0x06, 0x53, 0xd4,
- 0x50, 0x15, 0xb2, 0x40, 0x82, 0x51, 0x9a, 0xb2, 0x54, 0x73, 0x15, 0x55, 0xf2, 0x91, 0x3c, 0xd3,
- 0x92, 0x66, 0xf4, 0xf0, 0x92, 0xef, 0xf8, 0x97, 0x26, 0x7c, 0x1d, 0xfa, 0x93, 0xbf, 0x08, 0x0f,
- 0x9c, 0x30, 0x21, 0x62, 0xb5, 0x44, 0xab, 0xb4, 0x00, 0x8a, 0x85, 0x83, 0xfa, 0x1e, 0xbb, 0xc3,
- 0x54, 0x72, 0x80, 0x18, 0xca, 0xa7, 0xae, 0xe2, 0xf1, 0x48, 0x07, 0xfa, 0xd3, 0x43, 0x56, 0x11,
- 0x4a, 0x3b, 0x02, 0x31, 0x66, 0x0c, 0x7f, 0xe7, 0x4c, 0x9b, 0x7d, 0x94, 0xcc, 0x90, 0x46, 0x06,
- 0x36, 0x94, 0x70, 0x9a, 0x58, 0x59, 0x1e, 0xe0, 0x5e, 0x9b, 0x15, 0xe2, 0xae, 0x23, 0x1a, 0x52,
- 0xbe, 0xfd, 0xfb, 0x15, 0xd7, 0xce, 0xc5, 0xcf, 0x42, 0x78, 0x00, 0x36, 0xc8, 0x88, 0xea, 0x54,
- 0x1c, 0x94, 0x7f, 0xbc, 0x2e, 0x7b, 0x44, 0x5c, 0x09, 0x64, 0xdb, 0xf0, 0x63, 0xb8, 0xcb, 0x8b,
- 0x3f, 0x5b, 0x8f, 0x50, 0xdf, 0xbd, 0xc8, 0xec, 0x7c, 0xf1, 0xde, 0xd0, 0xc0, 0xf3, 0x89, 0x03,
- 0x62, 0x4e, 0xba, 0x88, 0x65, 0x3d, 0xc0, 0xb1, 0x9c, 0xc1, 0xf6, 0xd2, 0xa3, 0xa4, 0x8c, 0x32,
- 0x60, 0x9a, 0x18, 0x36, 0xcf, 0x9a, 0xe6, 0x45, 0x57, 0x66, 0xe6, 0x85, 0x01, 0x66, 0x51, 0x96,
- 0x61, 0xec, 0xb2, 0xbf, 0xcf, 0x28, 0x97, 0x8d, 0x5d, 0xd5, 0x6c, 0x65, 0xc1, 0x23, 0x1f, 0x22,
- 0x05, 0xd6, 0x2a, 0x18, 0x3f, 0x2d, 0xe0, 0x12, 0xc3, 0x78, 0xbf, 0xf3, 0x85, 0x79, 0x96, 0x8b,
- 0x87, 0x75, 0x48, 0x33, 0x95, 0x9b, 0x82, 0xb2, 0x58, 0x4a, 0xc1, 0x80, 0x47, 0x46, 0x46, 0x29,
- 0xc1, 0x80, 0x03, 0xa8, 0xc7, 0x3e, 0x00, 0xbe, 0xb2, 0xc3, 0x14, 0x06, 0x48, 0x2e, 0xfc, 0x3b,
- 0x95, 0x0c, 0x7f, 0xe7, 0xf0, 0x3b, 0xec, 0x0a, 0x9e, 0x00, 0x97, 0x8a, 0xa2, 0xe9, 0x55, 0x2d,
- 0x38, 0x3a, 0xfb, 0xe7, 0x7e, 0x77, 0x72, 0x6a, 0xc7, 0x1b, 0x4e, 0x18, 0xbc, 0x20, 0x4b, 0x6b,
- 0x5f, 0xbf, 0xf1, 0x0e, 0x11, 0x68, 0xf8, 0xc9, 0x00, 0xd6, 0x90, 0x9b, 0xbc, 0x00, 0xca, 0xbe,
- 0xf2, 0x7a, 0xe1, 0x4f, 0xc6, 0x8d, 0xb6, 0x6b, 0x7d, 0x77, 0x7b, 0x32, 0x69, 0x56, 0x50, 0xc4,
- 0x50, 0x35, 0xc0, 0xe0, 0xe8, 0xc6, 0xf5, 0x77, 0x73, 0xc0, 0x00, 0xb3, 0xe1, 0x0f, 0x71, 0x0b,
- 0x80, 0x35, 0x09, 0x7f, 0x44, 0x2d, 0xbb, 0x4f, 0x70, 0xae, 0x69, 0x99, 0x19, 0xed, 0xaa, 0xe3,
- 0x31, 0x3e, 0x37, 0xcb, 0x95, 0x9a, 0xc0, 0x05, 0xbe, 0x7d, 0xb4, 0xed, 0x72, 0xd7, 0x41, 0x82,
- 0xa4, 0x05, 0x19, 0x21, 0xc9, 0x38, 0x28, 0xb0, 0xd3, 0xfb, 0x01, 0x51, 0x86, 0x86, 0x7f, 0xd6,
- 0xa6, 0x86, 0x60, 0x13, 0x83, 0x98, 0xd1, 0xaf, 0xb9, 0x4f, 0x10, 0x73, 0xb6, 0x28, 0x2f, 0xf2,
- 0xda, 0x53, 0x6d, 0x19, 0xbd, 0x78, 0x77, 0xf7, 0x05, 0x36, 0x7f, 0x22, 0x78, 0x2d, 0x14, 0x62,
- 0xc5, 0xdd, 0x5f, 0xa8, 0x12, 0x5d, 0x7f, 0x80, 0x9d, 0xd9, 0x41, 0x67, 0xd4, 0x30, 0x1a, 0xbe,
- 0x59, 0xf8, 0xb1, 0xdc, 0xa4, 0xc5, 0xbf, 0xb3, 0xc7, 0xaf, 0x05, 0x5e, 0xc1, 0xc9, 0x26, 0x9f,
- 0x89, 0x3a, 0x1a, 0x41, 0x6c, 0xd1, 0xc2, 0x07, 0x69, 0xcf, 0xff, 0xaf, 0xa1, 0x2d, 0x5f, 0xaa,
- 0xeb, 0xc0, 0xd5, 0x3d, 0x34, 0x1b, 0x01, 0xdd, 0x08, 0xdc, 0x15, 0xdc, 0x6f, 0xda, 0x44, 0x35,
- 0x95, 0x05, 0xb0, 0x13, 0x58, 0x66, 0x7e, 0xa8, 0x4d, 0x55, 0xb0, 0xfe, 0xc8, 0x49, 0xcd, 0xe3,
- 0x5e, 0xfb, 0x9a, 0x1a, 0x9b, 0xd7, 0x3f, 0xe9, 0x4c, 0xe8, 0x1d, 0x0b, 0x67, 0xa5, 0x0d, 0x82,
- 0x17, 0x4c, 0x35, 0x5e, 0x86, 0xa1, 0x22, 0x20, 0xf1, 0x23, 0x9c, 0x55, 0x21, 0xb3, 0xf0, 0xc0,
- 0x67, 0x4c, 0xc3, 0xc3, 0xe0, 0xcf, 0x44, 0xeb, 0xcc, 0x8c, 0xb3, 0x0a, 0x77, 0x0c, 0x76, 0x22,
- 0x95, 0xe7, 0xc1, 0xa5, 0xb1, 0xdf, 0x82, 0xb8, 0x00, 0xb0, 0xae, 0x58, 0x0c, 0xff, 0x02, 0xf1,
- 0xe1, 0x0c, 0x2b, 0x62, 0x0f, 0xc7, 0x18, 0xcd, 0xbe, 0x77, 0xee, 0x15, 0x49, 0x53, 0xa1, 0x14,
- 0xc9, 0x6e, 0x98, 0xc1, 0xef, 0xd1, 0xbe, 0x0d, 0xd7, 0x5a, 0xfe, 0x61, 0xdf, 0x11, 0xc5, 0x34,
- 0x2a, 0xfe, 0x58, 0x39, 0x46, 0x8d, 0x59, 0x3c, 0x58, 0xcd, 0x0b, 0x01, 0x55, 0x00, 0x49, 0xbd,
- 0xfe, 0x44, 0x37, 0x8c, 0xae, 0x12, 0x7b, 0x25, 0x03, 0x70, 0x09, 0x5e, 0xc0, 0xb6, 0x8b, 0x72,
- 0x00, 0xb0, 0x8d, 0x83, 0xd5, 0x10, 0xbe, 0xda, 0x38, 0x42, 0xaf, 0x8b, 0xb1, 0xcc, 0x54, 0x16,
- 0x62, 0x86, 0xff, 0x9c, 0x03, 0xbf, 0x8d, 0x9b, 0x1e, 0x1b, 0x3d, 0x1c, 0x6b, 0x78, 0xd7, 0x08,
- 0xfc, 0xc7, 0x24, 0xdb, 0xc6, 0xff, 0xed, 0x11, 0xa7, 0x86, 0x14, 0x47, 0x0e, 0x5e, 0xf6, 0x96,
- 0xb1, 0x79, 0x03, 0x4a, 0x0b, 0x53, 0xfd, 0x93, 0x47, 0x1b, 0x6c, 0x25, 0x6a, 0x90, 0xf4, 0x21,
- 0x00, 0x7b, 0xd6, 0x96, 0xbe, 0x73, 0x3c, 0xe2, 0xd4, 0xe2, 0xf6, 0xd2, 0x23, 0xe9, 0x0d, 0xb2,
- 0x4a, 0x2f, 0xe6, 0x1f, 0x3d, 0x89, 0x42, 0x79, 0x62, 0xbf, 0x02, 0xf0, 0x86, 0x0c, 0xd7, 0x3b,
- 0x04, 0x95, 0x44, 0x18, 0x5c, 0xe4, 0x6d, 0x7c, 0x8d, 0xb4, 0x16, 0x55, 0xa3, 0xf3, 0xa9, 0xf7,
- 0x4b, 0x54, 0x20, 0x3d, 0x28, 0x39, 0x97, 0x24, 0x5c, 0x00, 0x99, 0xdc, 0x7f, 0xe7, 0x92, 0x82,
- 0x5b, 0x83, 0x3b, 0x81, 0x8e, 0xe3, 0x4e, 0x2d, 0x7c, 0x03, 0x1e, 0xb2, 0xcd, 0x7b, 0x39, 0x22,
- 0x8d, 0x58, 0xfe, 0xba, 0xc5, 0xa2, 0xe3, 0x6c, 0xc3, 0xf2, 0x72, 0x3a, 0x30, 0xbc, 0xba, 0x69,
- 0x06, 0xf9, 0x46, 0x21, 0xa1, 0x80, 0x83, 0x62, 0xaa, 0xa0, 0xd8, 0x8b, 0xe7, 0x27, 0x28, 0xd5,
- 0xd7, 0xec, 0xae, 0x15, 0xfd, 0x92, 0x63, 0x64, 0x1c, 0x04, 0xab, 0x23, 0x1b, 0x77, 0xf1, 0x5e,
- 0x34, 0x93, 0x01, 0xc9, 0x06, 0xdb, 0xcf, 0x98, 0xc4, 0x39, 0x31, 0xbf, 0x70, 0xde, 0x69, 0x47,
- 0x6f, 0x75, 0xe0, 0x81, 0x0a, 0xea, 0x89, 0x26, 0x4d, 0xc8, 0x3a, 0xc0, 0xf0, 0xbc, 0x06, 0xd7,
- 0xfb, 0xbc, 0xc7, 0x97, 0x7e, 0x4b, 0xfb, 0xcd, 0x8b, 0xfe, 0xee, 0xdb, 0xd5, 0x54, 0xbe, 0x5d,
- 0x05, 0xf3, 0x8f, 0x7e, 0x8e, 0xe9, 0x78, 0x1f, 0xcf, 0xfa, 0xae, 0x21, 0x91, 0x15, 0x80, 0x17,
- 0x78, 0x55, 0xc4, 0x21, 0x44, 0xdd, 0xbf, 0xaf, 0x6f, 0xd2, 0x11, 0xcb, 0x9a, 0x8a, 0x34, 0xa5,
- 0xf0, 0x2d, 0x51, 0x42, 0x31, 0xce, 0xf2, 0x8e, 0xa4, 0x12, 0x16, 0x71, 0xb6, 0x8a, 0x49, 0x54,
- 0x6b, 0x0e, 0x79, 0xa6, 0x8f, 0xf2, 0xe3, 0x00, 0x3b, 0x4b, 0xaf, 0xcf, 0x02, 0x41, 0xeb, 0xf0,
- 0x75, 0xd1, 0xb7, 0xb8, 0x92, 0x86, 0xfd, 0x25, 0x08, 0x7c, 0xb3, 0xdf, 0x8b, 0x5e, 0x66, 0xbd,
- 0x1c, 0x91, 0x46, 0xac, 0x5d, 0xbd, 0xe3, 0xaa, 0x15, 0xf1, 0xb7, 0x04, 0xff, 0x31, 0x65, 0xbb,
- 0x81, 0x4d, 0x9b, 0x9d, 0x0d, 0x02, 0xfc, 0xc2, 0x91, 0x70, 0x0b, 0x70, 0x1d, 0xa4, 0x0a, 0xa2,
- 0xba, 0x60, 0x58, 0x81, 0x5d, 0x13, 0xd1, 0xbe, 0xe7, 0x81, 0x9a, 0x4c, 0xed, 0x81, 0x72, 0x22,
- 0xaa, 0xa9, 0x66, 0xc6, 0x12, 0x51, 0x58, 0x72, 0x5a, 0x13, 0xde, 0xcc, 0x18, 0xab, 0x75, 0x67,
- 0xbe, 0x28, 0x7c, 0x9e, 0x88, 0x2d, 0x42, 0xc8, 0xe2, 0xe0, 0x61, 0x62, 0xe0, 0x84, 0x69, 0xef,
- 0xdf, 0x35, 0x5a, 0xf9, 0xfd, 0x19, 0x17, 0x4d, 0xf2, 0x37, 0x29, 0xfc, 0xe0, 0x39, 0x17, 0x6f,
- 0xab, 0xff, 0x8d, 0x8a, 0x2d, 0xa2, 0xd6, 0x55, 0x37, 0x8c, 0xa1, 0x43, 0xb9, 0x9f, 0x90, 0x8d,
- 0x7c, 0x1c, 0xb7, 0xa5, 0x5e, 0x10, 0xdf, 0xab, 0x75, 0x49, 0xc1, 0xc9, 0xd4, 0xcf, 0xaf, 0x63,
- 0x24, 0x99, 0xab, 0x07, 0xef, 0x51, 0x9b, 0xdb, 0xfa, 0xc2, 0xe3, 0x5f, 0xa6, 0x19, 0x21, 0x83,
- 0x04, 0xed, 0x00, 0x92, 0x47, 0xa6, 0xd5, 0xc0, 0x7f, 0x9c, 0x30, 0x13, 0x78, 0x16, 0x44, 0x40,
- 0xaa, 0xae, 0xef, 0xf0, 0x4b, 0x13, 0x46, 0x1f, 0x05, 0x64, 0x11, 0xd3, 0x13, 0xdb, 0x66, 0x86,
- 0x30, 0x31, 0x77, 0x4d, 0xf0, 0x32, 0x88, 0xa4, 0x8d, 0x9c, 0xf7, 0xef, 0x57, 0x80, 0xc3, 0x84,
- 0x27, 0x34, 0x9c, 0x1b, 0x6d, 0x9f, 0x98, 0x11, 0xf8, 0x63, 0xc9, 0xfd, 0x2c, 0x29, 0xf1, 0xa8,
- 0x4e, 0x19, 0x5c, 0x41, 0x00, 0xa5, 0x17, 0xcc, 0x0c, 0x91, 0x5a, 0xbe, 0x93, 0x06, 0x84, 0xdb,
- 0x0c, 0xa3, 0x35, 0x4f, 0xdc, 0xc5, 0x35, 0xa7, 0x61, 0x45, 0xf7, 0x84, 0xd3, 0xe1, 0xae, 0x6c,
- 0x02, 0x55, 0x94, 0x30, 0x79, 0xc3, 0xaa, 0x87, 0xab, 0x6e, 0xf8, 0x70, 0x80, 0x7b, 0xea, 0xa3,
- 0xd7, 0xb5, 0x92, 0x2c, 0xd5, 0x83, 0xac, 0x68, 0xb6, 0x03, 0xfe, 0xb2, 0x5c, 0xd7, 0xa1, 0x85,
- 0x04, 0x04, 0x54, 0x42, 0x1a, 0xc7, 0x80, 0x76, 0xaa, 0x7b, 0x30, 0x08, 0xcb, 0x0c, 0x87, 0x08,
- 0x2e, 0x19, 0x10, 0x60, 0x05, 0x53, 0xd9, 0xa9, 0xe0, 0xc8, 0xb4, 0x49, 0x51, 0xc5, 0xd0, 0x8e,
- 0x33, 0x8c, 0xc0, 0x9c, 0x70, 0x02, 0x9b, 0x58, 0xdb, 0xf0, 0x43, 0x99, 0x75, 0x39, 0xb6, 0x78,
- 0x99, 0xd1, 0xe3, 0xe9, 0x8f, 0x80, 0x92, 0x12, 0x9b, 0xa0, 0xc1, 0x60, 0xdf, 0x01, 0x64, 0x7c,
- 0x1f, 0x07, 0xc4, 0x3e, 0xe3, 0xbb, 0x00, 0x58, 0x0f, 0x00, 0x49, 0x3b, 0x41, 0x44, 0xa4, 0x54,
- 0x88, 0xd5, 0xd7, 0xad, 0xcd, 0x0c, 0x2a, 0x26, 0x50, 0xaa, 0x8b, 0x0b, 0xf2, 0xbb, 0x16, 0x74,
- 0xcb, 0x6a, 0x37, 0xe0, 0x72, 0x2d, 0x23, 0x11, 0xb2, 0xae, 0x28, 0xa4, 0x30, 0xc0, 0x18, 0x0b,
- 0xda, 0x55, 0x63, 0x69, 0xc5, 0x95, 0xce, 0xa2, 0x7d, 0xc8, 0xb5, 0x2a, 0x75, 0xad, 0x00, 0x49,
- 0x89, 0x6e, 0x0e, 0x4a, 0x38, 0xe6, 0x24, 0x88, 0xab, 0x07, 0xef, 0x51, 0xb5, 0x5f, 0x80, 0xec,
- 0x87, 0xdb, 0x87, 0x0a, 0xb6, 0xcf, 0xc0, 0x20, 0x1c, 0x10, 0x87, 0x01, 0x18, 0x05, 0xd3, 0x8c,
- 0x02, 0x6c, 0x43, 0x0c, 0x18, 0x32, 0x3f, 0xb7, 0x45, 0xb6, 0x24, 0xb8, 0xe1, 0x61, 0x1b, 0x73,
- 0xd7, 0x3c, 0x67, 0x95, 0x57, 0x69, 0x3c, 0x39, 0x5e, 0x3a, 0xc6, 0x44, 0x28, 0xc4, 0x95, 0x0e,
- 0x5d, 0x33, 0x85, 0x43, 0x8d, 0xd8, 0xc6, 0xf1, 0x2d, 0x51, 0x31, 0x3c, 0x7b, 0xdb, 0xb6, 0xb5,
- 0x94, 0xe6, 0xbd, 0x75, 0xd6, 0x05, 0x2a, 0xf4, 0xfa, 0x6b, 0xbc, 0x0a, 0xa7, 0xda, 0x54, 0xe4,
- 0x6b, 0xc9, 0x72, 0x71, 0x8b, 0x54, 0xa3, 0x93, 0x79, 0x0a, 0x7d, 0xd5, 0x81, 0x9f, 0xc2, 0x82,
- 0x77, 0x1f, 0xd8, 0xe5, 0x5f, 0xd2, 0xee, 0xbe, 0x84, 0x19, 0x10, 0x04, 0xfc, 0x6c, 0x71, 0xa6,
- 0xc2, 0x2d, 0xd3, 0xed, 0x1c, 0xbd, 0x9e, 0xc6, 0x97, 0x82, 0xb8, 0x10, 0xb7, 0xae, 0x9a, 0xc0,
- 0x65, 0x3e, 0x6f, 0x6d, 0xce, 0x81, 0xc6, 0xbc, 0x96, 0xfc, 0x67, 0xd2, 0xfc, 0x0d, 0x95, 0x9e,
- 0x05, 0xbd, 0xfb, 0xe6, 0x74, 0x3a, 0x56, 0x36, 0xec, 0x0f, 0x69, 0xca, 0xcf, 0xcd, 0xa9, 0xef,
- 0xb3, 0x86, 0x63, 0xb3, 0xed, 0xde, 0x0b, 0x66, 0x5f, 0x3f, 0xaf, 0x80, 0x7f, 0xce, 0x92, 0x4d,
- 0xaf, 0x83, 0x11, 0xf6, 0x83, 0xac, 0x4f, 0xc1, 0x49, 0x2b, 0x16, 0x40, 0x8f, 0x0b, 0xcb, 0xec,
- 0x6e, 0xfc, 0xe4, 0x8c, 0xcf, 0xe0, 0x94, 0xd3, 0xac, 0x1c, 0xcd, 0x46, 0x58, 0x0e, 0xa6, 0x44,
- 0x47, 0x00, 0xb6, 0x94, 0x9f, 0xa7, 0x25, 0x9a, 0xb8, 0x6b, 0xd6, 0x93, 0x5b, 0xb5, 0xb7, 0x59,
- 0xf0, 0x2c, 0x2c, 0x90, 0x61, 0x4a, 0xbd, 0x52, 0xea, 0x19, 0x97, 0x0a, 0x91, 0xb1, 0x75, 0x05,
- 0xd4, 0xdd, 0x3d, 0x64, 0x5b, 0x50, 0x70, 0x7c, 0xb7, 0x45, 0x01, 0xdf, 0x37, 0x83, 0x1a, 0xdf,
- 0xc0, 0x76, 0x81, 0x2b, 0xc1, 0x63, 0x62, 0x5b, 0x35, 0xb1, 0x89, 0xa7, 0xf2, 0x17, 0xc3, 0xd7,
- 0x16, 0xf8, 0x7c, 0x61, 0x96, 0x4b, 0x86, 0x93, 0x7c, 0x0d, 0x1c, 0x6c, 0x3e, 0x87, 0x27, 0xb5,
- 0x09, 0xb0, 0xf7, 0x2c, 0x88, 0xef, 0x50, 0xc9, 0x4a, 0x36, 0xc6, 0x47, 0xfa, 0xcb, 0xa6, 0x3f,
- 0x70, 0xc6, 0xbf, 0xe8, 0xed, 0xae, 0x38, 0x0d, 0xa4, 0xe0, 0x4a, 0xcb, 0xe1, 0x6a, 0xa3, 0x0d,
- 0x78, 0x5a, 0x93, 0x43, 0x6a, 0x96, 0x52, 0xad, 0x23, 0x80, 0x5d, 0x10, 0x5d, 0x34, 0xa5, 0x6c,
- 0xb5, 0xca, 0xcb, 0x7c, 0x23, 0xbf, 0x04, 0xa9, 0xde, 0xe0, 0x72, 0xbc, 0x32, 0x5b, 0xc0, 0x09,
- 0x4b, 0x46, 0x42, 0x0e, 0x94, 0x93, 0x8c, 0x9d, 0x9e, 0xa3, 0xdf, 0xa7, 0xf8, 0x7a, 0xc5, 0x79,
- 0x39, 0x53, 0xe9, 0x42, 0xe9, 0x56, 0xff, 0xcf, 0x48, 0x5a, 0x8a, 0xc0, 0x31, 0x79, 0x95, 0x36,
- 0xf4, 0x3e, 0x4e, 0xdb, 0x6b, 0x3f, 0x42, 0x22, 0xd3, 0x73, 0xc0, 0xdd, 0x31, 0x4b, 0xad, 0x87,
- 0x6f, 0xf0, 0xdf, 0x3c, 0xff, 0xb5, 0xb0, 0xdc, 0x3d, 0xe5, 0x36, 0x05, 0x07, 0xf7, 0xf2, 0x7a,
- 0x08, 0x8b, 0xc6, 0xfd, 0x89, 0x50, 0xa6, 0xbd, 0xfc, 0x27, 0x5b, 0x2c, 0x0b, 0xec, 0x25, 0x35,
- 0x49, 0x83, 0x1a, 0xc0, 0x11, 0x9a, 0x34, 0x4e, 0x12, 0x3c, 0x88, 0x87, 0xf3, 0xde, 0x60, 0x1e,
- 0xbe, 0x38, 0xf5, 0x8c, 0x24, 0x9a, 0x37, 0x07, 0xc7, 0xf7, 0x94, 0xa9, 0x17, 0x3d, 0xac, 0x77,
- 0xbc, 0x88, 0x78, 0x16, 0x3d, 0x43, 0x9a, 0xf6, 0x72, 0x51, 0x1a, 0xb0, 0x95, 0xfb, 0xae, 0x03,
- 0xc0, 0x26, 0x91, 0x60, 0x5d, 0x40, 0xd3, 0x61, 0xaa, 0x21, 0x01, 0x18, 0xd5, 0x86, 0xb5, 0x78,
- 0x01, 0x4c, 0xf8, 0x4f, 0x52, 0xbd, 0xe8, 0x7d, 0x99, 0x03, 0x7d, 0x8d, 0xce, 0x1a, 0x7d, 0xce,
- 0xc2, 0xb2, 0xfb, 0x02, 0xfc, 0x67, 0xbf, 0x1b, 0xaa, 0x8c, 0x35, 0x26, 0x15, 0x2d, 0x84, 0x96,
- 0xc4, 0xac, 0xf6, 0x5b, 0xc0, 0x03, 0x77, 0x6f, 0xc2, 0xe4, 0xbd, 0xe1, 0x25, 0xa6, 0x84, 0xaf,
- 0x20, 0xab, 0x54, 0xf1, 0x71, 0x05, 0x83, 0x91, 0x98, 0x81, 0x7b, 0x77, 0xaa, 0xbd, 0x2e, 0xae,
- 0x3f, 0xd6, 0x27, 0x2e, 0xcd, 0x3d, 0x61, 0x19, 0xb1, 0x24, 0xc0, 0x2f, 0xbd, 0x2b, 0x36, 0x05,
- 0xd7, 0x06, 0x3d, 0xcf, 0x27, 0x8e, 0x50, 0x82, 0x16, 0xa6, 0xc0, 0x09, 0xa3, 0x9b, 0x8f, 0x4b,
- 0x4b, 0x6c, 0x56, 0x0e, 0x97, 0xb3, 0xf5, 0x3a, 0xe0, 0x38, 0xcf, 0x72, 0x93, 0x28, 0xa3, 0x85,
- 0x6b, 0x5f, 0xfe, 0x61, 0x10, 0x77, 0xb0, 0x15, 0x92, 0x4c, 0x00, 0x86, 0x92, 0xc3, 0x09, 0x68,
- 0xb9, 0xc8, 0xc5, 0x78, 0x01, 0xcb, 0x9e, 0x2f, 0xf4, 0xf3, 0xd8, 0x41, 0xcd, 0x88, 0xd6, 0x8b,
- 0xae, 0x5b, 0x1e, 0x54, 0x7e, 0xf1, 0xec, 0xa0, 0xef, 0x75, 0xd6, 0xd9, 0xce, 0x1f, 0x6c, 0x8e,
- 0xe6, 0x5a, 0x15, 0x46, 0x1e, 0x88, 0x2e, 0x2b, 0xbb, 0xb9, 0xb4, 0xbf, 0x4f, 0x63, 0xf9, 0x5e,
- 0x8e, 0xcd, 0xa3, 0xfd, 0x11, 0x53, 0x2c, 0xf3, 0x54, 0x57, 0x3a, 0xf7, 0x88, 0x18, 0x57, 0x11,
- 0x9d, 0x89, 0xb5, 0xff, 0xca, 0xb1, 0x66, 0x22, 0xbe, 0x24, 0x78, 0x13, 0x69, 0x47, 0x16, 0xa3,
- 0xc0, 0x09, 0x6e, 0x9f, 0x0f, 0xed, 0x5f, 0x2f, 0xab, 0x9c, 0x95, 0xaa, 0x6f, 0xea, 0x00, 0xcf,
- 0x55, 0xde, 0xbd, 0x8f, 0xc9, 0x18, 0xc7, 0xc1, 0x41, 0x9b, 0xb0, 0x72, 0x35, 0x1a, 0x0f, 0xb9,
- 0x19, 0x11, 0x97, 0x85, 0x07, 0xa5, 0xe1, 0xc0, 0xb2, 0xb3, 0x0c, 0x74, 0x2f, 0x33, 0xb0, 0xc0,
- 0xe9, 0xe2, 0x48, 0xe0, 0x42, 0xb0, 0x23, 0xe5, 0x58, 0x93, 0x60, 0x17, 0x30, 0xa8, 0x13, 0x2f,
- 0x3c, 0x48, 0x18, 0x3b, 0xb1, 0x1b, 0x16, 0xc1, 0x57, 0xd6, 0xed, 0xd5, 0x75, 0x78, 0x01, 0xc1,
- 0x23, 0x2f, 0x8e, 0xf3, 0x91, 0xcd, 0x72, 0x5e, 0x12, 0x53, 0x8d, 0xfa, 0xc0, 0x7d, 0xc5, 0x93,
- 0x3f, 0xcf, 0xff, 0xf1, 0xf5, 0xc3, 0x23, 0xeb, 0x2e, 0x4b, 0x92, 0x9a, 0xe5, 0xb8, 0x2f, 0x6c,
- 0xc3, 0x47, 0x07, 0xec, 0x83, 0x0d, 0xff, 0x9d, 0xa9, 0x4d, 0x09, 0x9d, 0x75, 0xb4, 0x24, 0x16,
- 0xaf, 0x00, 0xe7, 0xc6, 0x1a, 0x8f, 0xaf, 0x64, 0x47, 0xa9, 0x50, 0xbf, 0x08, 0xfb, 0x2c, 0xf8,
- 0x77, 0xff, 0x14, 0x6d, 0x58, 0xe0, 0x74, 0xb3, 0x02, 0x50, 0xa6, 0x0c, 0xaa, 0xb1, 0x0b, 0x2b,
- 0x1d, 0x15, 0xa0, 0x4d, 0xfc, 0x88, 0xb7, 0x0f, 0x57, 0xf4, 0x92, 0xcc, 0x50, 0x3e, 0x35, 0x09,
- 0x0a, 0x18, 0xab, 0xcc, 0xf8, 0x72, 0xfd, 0xf7, 0x9f, 0x1b, 0xdd, 0x5d, 0x2b, 0xcb, 0xcd, 0xbd,
- 0xb7, 0x1d, 0x96, 0xdd, 0xb0, 0xd3, 0xdb, 0x64, 0xbe, 0x33, 0xa8, 0x92, 0x01, 0x0f, 0x2c, 0xe5,
- 0x85, 0xd2, 0x79, 0x9d, 0x23, 0xfe, 0xf8, 0xda, 0x1d, 0x34, 0xd6, 0x95, 0x7f, 0x93, 0x4d, 0x7e,
- 0xec, 0x4f, 0x03, 0xfe, 0xc1, 0x9d, 0xc0, 0x54, 0xe0, 0xca, 0xea, 0x95, 0x4d, 0x34, 0x82, 0x8c,
- 0x94, 0xd7, 0x87, 0xd2, 0x24, 0x5a, 0x1f, 0x00, 0x9e, 0xd8, 0x85, 0xe3, 0xf3, 0xe0, 0x1c, 0xfb,
- 0x9b, 0xf0, 0x63, 0xb8, 0x64, 0x45, 0x70, 0x32, 0x3d, 0x69, 0x9a, 0xf6, 0x72, 0x59, 0x1a, 0xb0,
- 0x3a, 0xb5, 0xfb, 0x60, 0x38, 0x05, 0x0e, 0x52, 0x17, 0x3f, 0xfc, 0x09, 0x14, 0xee, 0x18, 0x04,
- 0xe3, 0x76, 0x13, 0xad, 0x09, 0x5c, 0x2c, 0x2c, 0x5c, 0xed, 0x5d, 0xd6, 0xae, 0xe0, 0xfb, 0x2d,
- 0x18, 0x47, 0x11, 0xb2, 0x15, 0x74, 0x67, 0x94, 0x05, 0x83, 0x9f, 0xe3, 0xd5, 0x53, 0x55, 0x9d,
- 0x72, 0xbe, 0xf0, 0x2f, 0x69, 0x48, 0x6f, 0x63, 0xf9, 0x5e, 0xf2, 0xc0, 0xb0, 0xee, 0x6f, 0x66,
- 0x51, 0x53, 0xbb, 0x4d, 0x28, 0xb6, 0x11, 0x36, 0x16, 0xc8, 0xea, 0xfd, 0x5e, 0xba, 0xda, 0x1e,
- 0x76, 0x99, 0xd0, 0x65, 0x54, 0xea, 0xc0, 0x72, 0x6e, 0x77, 0xe7, 0xee, 0xdb, 0xd7, 0xfb, 0x9b,
- 0x4d, 0xda, 0x37, 0x30, 0x6e, 0xf8, 0xc5, 0xef, 0x60, 0x13, 0x0e, 0x18, 0x58, 0x9c, 0x79, 0xda,
- 0xd0, 0xc2, 0xa3, 0x2c, 0x66, 0xb2, 0x8b, 0xa3, 0x73, 0x3b, 0x35, 0x5a, 0xb1, 0x39, 0x09, 0x26,
- 0x0d, 0xc0, 0x24, 0x89, 0xaf, 0x00, 0x53, 0xc4, 0xaa, 0x5c, 0x5e, 0xdd, 0x03, 0xb4, 0xf5, 0xfa,
- 0x91, 0x66, 0xac, 0x1c, 0xad, 0x46, 0x38, 0x0e, 0x80, 0xa8, 0xba, 0x74, 0xf5, 0xf5, 0x60, 0xbf,
- 0xfe, 0x7f, 0x0d, 0xb7, 0xad, 0x38, 0x3d, 0xb4, 0x23, 0xa3, 0xbc, 0x63, 0xc2, 0x08, 0xde, 0x9a,
- 0x00, 0x88, 0xbf, 0x83, 0xe6, 0xec, 0xfc, 0x57, 0xf0, 0xff, 0xd5, 0xb9, 0x07, 0x3d, 0x42, 0x4d,
- 0x82, 0xcb, 0xf9, 0x3d, 0xc8, 0x70, 0xea, 0xb5, 0x50, 0xb3, 0x11, 0x7c, 0x82, 0x3f, 0xfe, 0x57,
- 0xf0, 0x0e, 0xf3, 0x8a, 0xbd, 0x9f, 0x93, 0xb4, 0x96, 0xe5, 0xf1, 0x97, 0x96, 0x0c, 0xd1, 0x79,
- 0xdf, 0xf9, 0x6f, 0xc0, 0xd5, 0x54, 0x81, 0xbb, 0x97, 0x5f, 0xfb, 0xb6, 0x2e, 0x15, 0xb1, 0x7c,
- 0x5b, 0x8b, 0x4b, 0xa3, 0x9a, 0x30, 0xf5, 0x82, 0x1a, 0x7d, 0x1c, 0x16, 0x6c, 0x08, 0xf2, 0x5c,
- 0x17, 0x52, 0xbe, 0xff, 0x52, 0x3e, 0xf7, 0xbb, 0x25, 0x80, 0x5c, 0x46, 0x89, 0xe5, 0xc7, 0x62,
- 0x74, 0xea, 0xdc, 0xa0, 0xda, 0xa0, 0x3f, 0x08, 0xdf, 0xcf, 0xaf, 0x9b, 0xdf, 0x78, 0x91, 0x6b,
- 0x7c, 0x00, 0x77, 0x74, 0xb0, 0x3e, 0x0c, 0xd4, 0x6c, 0xaf, 0xdd, 0xed, 0xc7, 0x71, 0xa7, 0x16,
- 0x3f, 0x33, 0x8f, 0x5a, 0xc7, 0xbd, 0x47, 0x76, 0x07, 0x24, 0x11, 0xd7, 0xa6, 0x9a, 0x56, 0x69,
- 0x3b, 0x12, 0xb0, 0xe0, 0xd0, 0x12, 0x23, 0xc4, 0x8c, 0x32, 0xc4, 0x3a, 0x00, 0xba, 0x6e, 0xc3,
- 0x89, 0x7c, 0x96, 0x48, 0x0a, 0x08, 0x24, 0x30, 0x8d, 0x2c, 0x0b, 0x56, 0xe6, 0xd5, 0x55, 0x39,
- 0x5e, 0xf5, 0xed, 0x3c, 0xc0, 0x5b, 0x59, 0x0b, 0xe9, 0xbe, 0x2e, 0xb9, 0xb5, 0x7e, 0xff, 0xbd,
- 0x6f, 0x80, 0x1e, 0xc4, 0xe4, 0x1b, 0xaf, 0xfc, 0x55, 0x1f, 0x19, 0x7d, 0x4c, 0x4f, 0xcc, 0xbc,
- 0xee, 0xb2, 0x67, 0x02, 0xe9, 0x2f, 0x1b, 0xe4, 0xfa, 0x1b, 0xc5, 0xfc, 0x9a, 0x2e, 0x41, 0x82,
- 0xc6, 0xfe, 0x01, 0x8f, 0x4b, 0x1b, 0x79, 0x1b, 0x2b, 0x85, 0xe9, 0x5f, 0x92, 0xe1, 0xba, 0x97,
- 0xae, 0x9b, 0x68, 0x7c, 0xd2, 0x4c, 0x8d, 0xdc, 0xb2, 0xc0, 0x46, 0xd2, 0xe1, 0x5e, 0x6b, 0xf3,
- 0x79, 0x7a, 0xf3, 0xcb, 0x3c, 0x5d, 0x23, 0xb0, 0x93, 0x47, 0x39, 0xfd, 0x4e, 0x1a, 0xe5, 0x95,
- 0xc1, 0x47, 0x5f, 0xf9, 0xed, 0x0b, 0xdc, 0xcc, 0x75, 0x2a, 0x6a, 0x06, 0x00, 0x91, 0x19, 0x8c,
- 0x56, 0xfd, 0x00, 0x93, 0x18, 0xfc, 0xd2, 0x30, 0xbd, 0xa2, 0xa2, 0xa6, 0xd8, 0x96, 0x78, 0xf1,
- 0x8e, 0x7c, 0x46, 0xc8, 0x79, 0xf8, 0xda, 0xcb, 0x3b, 0x02, 0x6d, 0x5e, 0x01, 0x32, 0xf4, 0x86,
- 0x7f, 0xe6, 0x7c, 0xfd, 0xcf, 0x08, 0x0f, 0x09, 0x6f, 0x03, 0xfa, 0x11, 0x96, 0x7b, 0x73, 0x75,
- 0x90, 0xdc, 0xfe, 0x5e, 0x62, 0x61, 0x67, 0x1b, 0xc8, 0x8c, 0xb9, 0x32, 0x98, 0x4d, 0x9a, 0xd4,
- 0xa0, 0x39, 0x5b, 0xd6, 0x0b, 0x56, 0x56, 0xcf, 0x55, 0x43, 0x2f, 0x6f, 0xb8, 0xf6, 0x83, 0xff,
- 0xe7, 0x62, 0x7b, 0x73, 0xf9, 0x4e, 0xea, 0xec, 0x3e, 0x1e, 0xa6, 0xbf, 0xbf, 0x87, 0xdb, 0x1a,
- 0xdb, 0xca, 0xb4, 0xc7, 0xa5, 0x30, 0x2b, 0xcd, 0x79, 0xef, 0x9b, 0x58, 0xdc, 0x30, 0xf8, 0x70,
- 0x8e, 0x2f, 0x42, 0xde, 0x83, 0x44, 0x25, 0xf7, 0xdd, 0x55, 0x3e, 0x12, 0x55, 0x4e, 0x15, 0x5f,
- 0x37, 0x91, 0xe9, 0xe3, 0x1f, 0x20, 0xda, 0x51, 0xcb, 0xff, 0xfd, 0x6d, 0x72, 0xfc, 0x3f, 0x5b,
- 0x0f, 0xc7, 0x70, 0xcd, 0x84, 0xd9, 0x8e, 0x36, 0x92, 0x1d, 0x4a, 0x61, 0x70, 0x9b, 0x9b, 0x68,
- 0x9b, 0x27, 0xc6, 0x99, 0x10, 0xa3, 0xce, 0x53, 0x21, 0xf4, 0x31, 0x3c, 0x87, 0x84, 0x69, 0x81,
- 0x9d, 0xa5, 0xef, 0x0f, 0xf1, 0xca, 0xae, 0xf0, 0x63, 0x1c, 0x84, 0x5b, 0x8f, 0x77, 0xe5, 0x6b,
- 0x11, 0xec, 0x26, 0x59, 0x9f, 0x16, 0x89, 0xe1, 0xc2, 0xad, 0x56, 0xb8, 0x2e, 0x31, 0x68, 0x5d,
- 0x2a, 0x83, 0xf6, 0xef, 0xfe, 0x61, 0x76, 0x9d, 0x60, 0x2a, 0x87, 0xc5, 0x85, 0xff, 0x22, 0xe4,
- 0x4b, 0x08, 0x48, 0x13, 0x8a, 0x00, 0x3b, 0x48, 0xc9, 0x21, 0x06, 0xc1, 0xbb, 0xd9, 0xd1, 0x3d,
- 0x52, 0x49, 0x6a, 0x44, 0x93, 0x09, 0xc8, 0x8b, 0x8a, 0x5e, 0x7e, 0x8d, 0x0b, 0x26, 0xc3, 0x59,
- 0xbb, 0xad, 0x92, 0xaa, 0x46, 0x0b, 0xbe, 0xd6, 0xaa, 0xa0, 0x36, 0x5f, 0x34, 0x6a, 0x88, 0x84,
- 0x0a, 0xfc, 0xa8, 0xb8, 0xbd, 0xb4, 0xa4, 0xf4, 0xc6, 0xe1, 0x88, 0x55, 0x5d, 0x4e, 0xc9, 0xdc,
- 0x7d, 0xa2, 0x71, 0x0d, 0x18, 0x1e, 0x16, 0x1d, 0x17, 0x11, 0xb3, 0x91, 0x92, 0xf0, 0xc6, 0x1b,
- 0x3a, 0x54, 0x80, 0x8f, 0x11, 0x71, 0x9b, 0x02, 0x16, 0xf4, 0x8f, 0xf0, 0x37, 0xf2, 0xea, 0xa8,
- 0x95, 0x61, 0x8e, 0x8f, 0x22, 0x22, 0xc0, 0xef, 0x51, 0x0b, 0x18, 0x8d, 0xd8, 0xe8, 0x0b, 0x76,
- 0x3e, 0xa5, 0x28, 0xc3, 0x6f, 0xde, 0xf1, 0xf4, 0x55, 0x7d, 0x48, 0xfd, 0xe3, 0xa5, 0x64, 0x45,
- 0x70, 0x3c, 0xbe, 0x0f, 0x06, 0x22, 0xc8, 0x95, 0x89, 0x0a, 0x56, 0xd6, 0x8a, 0x36, 0x42, 0xbe,
- 0xe6, 0x20, 0x00, 0x5c, 0xaa, 0xc6, 0x2e, 0xea, 0x19, 0x11, 0xfc, 0x07, 0x38, 0x08, 0x30, 0x7f,
- 0xb1, 0xe7, 0xfd, 0x71, 0x1c, 0x37, 0xc1, 0xd1, 0x4c, 0x3f, 0x16, 0x4c, 0x4d, 0x06, 0x69, 0xca,
- 0x3b, 0x8b, 0x79, 0xfd, 0x05, 0x0c, 0x8c, 0x60, 0xee, 0xaa, 0x91, 0x16, 0xf1, 0xab, 0x8a, 0x55,
- 0xf1, 0xb2, 0x85, 0xfc, 0xa7, 0xde, 0x6f, 0x32, 0xd3, 0x1f, 0xfd, 0xc2, 0x0d, 0xc7, 0x74, 0x4d,
- 0xcb, 0xae, 0x77, 0x96, 0xd3, 0xf3, 0x0a, 0xa0, 0x97, 0xd1, 0xf5, 0x54, 0xb8, 0xba, 0x45, 0x63,
- 0x1f, 0xe4, 0xef, 0x80, 0x63, 0xd4, 0xef, 0xef, 0x74, 0x56, 0x93, 0xf3, 0xfe, 0x60, 0x97, 0xcb,
- 0xf5, 0x55, 0x89, 0x0b, 0x92, 0x4e, 0xb5, 0x22, 0xe3, 0x0e, 0xc4, 0x5e, 0xc9, 0x0b, 0xc8, 0x52,
- 0xc1, 0x43, 0x0a, 0x6e, 0x6e, 0xee, 0xe9, 0xd2, 0x58, 0xe1, 0x08, 0xd5, 0x93, 0xdd, 0x96, 0x57,
- 0x8b, 0x06, 0x2f, 0xb4, 0x3b, 0x0a, 0x00, 0x5f, 0x9d, 0x55, 0x14, 0x57, 0xfe, 0xee, 0xbe, 0x19,
- 0x61, 0xa5, 0x63, 0x81, 0x6a, 0xf0, 0x1e, 0xf8, 0xdc, 0xa0, 0xf4, 0x98, 0xaa, 0x0b, 0x40, 0xfa,
- 0xea, 0xb1, 0xb7, 0xce, 0xb7, 0x80, 0x3b, 0x56, 0x09, 0xb6, 0xa5, 0x92, 0x84, 0x0b, 0x01, 0xca,
- 0x51, 0x86, 0xad, 0xd5, 0x1a, 0xc5, 0x9f, 0xba, 0x2b, 0xc5, 0x30, 0x66, 0xd2, 0xbc, 0xa5, 0xb1,
- 0xcd, 0x3a, 0x73, 0x29, 0x49, 0x47, 0x58, 0xe3, 0xb7, 0x55, 0xeb, 0x15, 0x7f, 0x0d, 0xf8, 0x12,
- 0x55, 0x02, 0x92, 0x3a, 0xe7, 0x60, 0xdf, 0xfa, 0x3a, 0x3a, 0x01, 0x35, 0xf0, 0x06, 0xe5, 0x85,
- 0xdd, 0x21, 0xef, 0xe7, 0x84, 0xda, 0x08, 0x22, 0xa2, 0xab, 0x83, 0x92, 0x25, 0x15, 0x8b, 0x00,
- 0x4f, 0x6a, 0xc9, 0x01, 0xa4, 0xc1, 0x62, 0xf6, 0x07, 0x24, 0x19, 0xbb, 0x5d, 0xe0, 0x36, 0x69,
- 0xf5, 0x6a, 0xef, 0x22, 0x73, 0xc7, 0xb6, 0xc2, 0x03, 0xc9, 0x53, 0x9f, 0x4d, 0xd5, 0x1e, 0x03,
- 0x00, 0xd9, 0xa4, 0x44, 0x44, 0x45, 0x15, 0x2e, 0xdb, 0x91, 0x09, 0xf0, 0xd8, 0x30, 0x0b, 0x08,
- 0x29, 0x55, 0x1e, 0xd2, 0x58, 0xa1, 0xed, 0xda, 0xe0, 0x64, 0xec, 0x83, 0x2b, 0x5b, 0x30, 0x7a,
- 0x90, 0xb0, 0x5f, 0x1a, 0x55, 0x38, 0xa6, 0x5d, 0x6f, 0xaa, 0x4e, 0x03, 0x6e, 0x00, 0x0b, 0xc6,
- 0x35, 0x5d, 0x37, 0x23, 0xea, 0xa9, 0x81, 0xa2, 0x52, 0x0e, 0x9c, 0xd5, 0x7e, 0xaa, 0x98, 0x05,
- 0x5c, 0x0c, 0xf3, 0x41, 0x07, 0x3e, 0x81, 0x6b, 0xf1, 0x7f, 0x50, 0xef, 0x9b, 0x8f, 0xc2, 0xf0,
- 0x97, 0xaf, 0xbf, 0x00, 0x52, 0x02, 0x57, 0x59, 0xfc, 0x75, 0x0c, 0x90, 0x1a, 0x47, 0x17, 0x0e,
- 0xf0, 0x0d, 0x3f, 0x6e, 0x97, 0x80, 0x99, 0x60, 0x37, 0x6a, 0xcc, 0xe9, 0xd9, 0x11, 0x09, 0xc4,
- 0x09, 0x60, 0x00, 0x25, 0x06, 0x2f, 0xb6, 0x8e, 0xaf, 0x68, 0xa9, 0x29, 0xab, 0xa9, 0xaa, 0xa7,
- 0x45, 0xcb, 0x0c, 0xe4, 0x85, 0xbc, 0x27, 0xd5, 0xa6, 0x00, 0x72, 0xa5, 0xc0, 0x72, 0xf1, 0xef,
- 0x71, 0x42, 0x0c, 0x1b, 0x02, 0xdb, 0x44, 0x40, 0x0b, 0xde, 0x15, 0x7c, 0x43, 0xdf, 0xe2, 0x52,
- 0x0b, 0x2c, 0x9f, 0xf5, 0x24, 0xab, 0xc4, 0x69, 0xaa, 0xa2, 0xe0, 0x39, 0xe0, 0x2e, 0x11, 0x2e,
- 0x11, 0x39, 0x0f, 0x38, 0x5e, 0x6f, 0x2a, 0x70, 0xa3, 0x5e, 0x9c, 0xdc, 0xe8, 0xd5, 0x63, 0x6b,
- 0x70, 0x05, 0xf0, 0x27, 0xbd, 0x70, 0x0d, 0x4b, 0xf5, 0x54, 0xe0, 0x79, 0x11, 0x4a, 0x16, 0xb9,
- 0x03, 0x2f, 0x58, 0xf5, 0x39, 0xbc, 0xa9, 0xc9, 0xff, 0xc5, 0x94, 0x6a, 0xa8, 0x51, 0x05, 0x0b,
- 0x82, 0xfe, 0xa0, 0xd7, 0xd5, 0xc4, 0xae, 0xb7, 0x45, 0xfc, 0x4a, 0x2f, 0x07, 0x72, 0x87, 0x70,
- 0x1c, 0x88, 0x97, 0x8d, 0x59, 0x30, 0x3d, 0xfa, 0x80, 0xd3, 0xd8, 0x09, 0xaa, 0x8f, 0xbc, 0x03,
- 0xfc, 0x0a, 0xaf, 0x00, 0x70, 0x16, 0xa4, 0xec, 0xaa, 0xa3, 0xe3, 0x76, 0xd2, 0x85, 0x11, 0xef,
- 0x91, 0x91, 0x1c, 0xc0, 0x67, 0xbc, 0x50, 0xf8, 0x67, 0xbc, 0x32, 0x78, 0xf5, 0xde, 0xed, 0x27,
- 0x67, 0x01, 0x12, 0xf0, 0x46, 0x7d, 0x49, 0xe3, 0x75, 0xfc, 0x3a, 0x54, 0xe2, 0xf0, 0xe6, 0x71,
- 0xbf, 0x55, 0x14, 0xaa, 0x28, 0xe0, 0xec, 0x65, 0x5e, 0x7f, 0x16, 0x44, 0x97, 0x02, 0x92, 0x13,
- 0x34, 0x9f, 0x4b, 0xc4, 0xd3, 0x78, 0xe5, 0x6b, 0x99, 0x29, 0xa3, 0xa4, 0xad, 0xd1, 0xe5, 0x39,
- 0xc9, 0x07, 0x00, 0x24, 0x65, 0x03, 0x6b, 0x27, 0xb7, 0xb1, 0x48, 0xbf, 0x56, 0x0e, 0xe6, 0xa3,
- 0xb9, 0x46, 0x42, 0x18, 0xe8, 0xfa, 0x07, 0x80, 0x87, 0xee, 0xc8, 0x88, 0xc0, 0x21, 0x89, 0x8f,
- 0x58, 0xe9, 0x08, 0xb4, 0x6b, 0xbc, 0x79, 0xac, 0x56, 0x5f, 0xa6, 0x4b, 0x89, 0x6f, 0x88, 0xe2,
- 0xc0, 0x69, 0x93, 0x51, 0x1f, 0x63, 0xda, 0xaa, 0xe7, 0x8b, 0xfe, 0xf4, 0xf6, 0x92, 0x34, 0xb5,
- 0x55, 0x0a, 0x41, 0x5d, 0x8c, 0x48, 0x2d, 0x22, 0x64, 0x44, 0xf0, 0x22, 0xc0, 0x77, 0x44, 0x67,
- 0xb4, 0xc4, 0x2b, 0x97, 0x85, 0xe0, 0x4b, 0xe1, 0x77, 0x0e, 0x83, 0x04, 0x74, 0xe8, 0x6d, 0x4c,
- 0xf0, 0xcb, 0x84, 0xe9, 0x60, 0x4b, 0x21, 0x6a, 0x73, 0xa6, 0x49, 0x1d, 0x2c, 0x22, 0x72, 0xae,
- 0xd7, 0xb8, 0xc5, 0xf8, 0x22, 0x00, 0x76, 0xf2, 0x85, 0x7c, 0x8e, 0x30, 0x92, 0x1f, 0x02, 0xe1,
- 0x12, 0x83, 0xc5, 0x80, 0xc1, 0xc4, 0x0d, 0x53, 0x5b, 0xd8, 0xe8, 0x95, 0x4d, 0x24, 0x81, 0xc0,
- 0x2a, 0x34, 0x24, 0x6a, 0x47, 0x7f, 0xf3, 0x8c, 0x15, 0x6d, 0xda, 0xf8, 0x1d, 0xe1, 0x6d, 0x1c,
- 0x00, 0xb8, 0x4c, 0x74, 0xfa, 0xd1, 0xaa, 0x35, 0xce, 0xba, 0x51, 0xa8, 0xc3, 0x87, 0x22, 0x10,
- 0x21, 0xf2, 0xbc, 0xbc, 0xa6, 0x8d, 0x6f, 0x6d, 0x74, 0x66, 0xb8, 0x64, 0xe6, 0x7f, 0xe3, 0x50,
- 0xef, 0x59, 0x02, 0x31, 0xeb, 0x0c, 0x69, 0x2a, 0x5a, 0xe3, 0x73, 0xe4, 0x8d, 0xfe, 0xcd, 0xab,
- 0x00, 0x4b, 0x46, 0x06, 0x0d, 0xbf, 0x57, 0xb2, 0xe2, 0x4d, 0x69, 0xb0, 0xda, 0x69, 0x22, 0x17,
- 0xde, 0x65, 0xdf, 0xe4, 0x3b, 0x98, 0x18, 0x6b, 0xda, 0xd3, 0x25, 0xbd, 0x36, 0x1c, 0xa5, 0x56,
- 0x8e, 0x2c, 0x60, 0x17, 0x38, 0x70, 0x3b, 0xf6, 0x64, 0x44, 0x5e, 0x34, 0xd8, 0xe3, 0x6d, 0x74,
- 0xd8, 0xcd, 0xe1, 0x16, 0x31, 0xc2, 0x5c, 0x2d, 0xb6, 0x34, 0xb7, 0x95, 0x6e, 0x8e, 0x2e, 0x31,
- 0x02, 0xac, 0x20, 0x9e, 0x05, 0x45, 0x86, 0x01, 0x10, 0x54, 0xe3, 0x91, 0xad, 0xf0, 0x9e, 0x3d,
- 0x96, 0xda, 0x7d, 0xe1, 0x25, 0x06, 0x45, 0x00, 0x48, 0xe4, 0xcd, 0xe0, 0xec, 0x06, 0x4e, 0x2d,
- 0x92, 0x74, 0xa1, 0x26, 0x5e, 0xe9, 0x26, 0x8a, 0x30, 0x21, 0x34, 0x47, 0x44, 0x67, 0xea, 0xd6,
- 0x59, 0xa4, 0x39, 0xb5, 0x87, 0x22, 0x3f, 0x63, 0x52, 0xe3, 0xda, 0xbc, 0x80, 0x01, 0x45, 0x17,
- 0xdd, 0x32, 0xcd, 0x89, 0x8c, 0x22, 0xc2, 0xc8, 0x16, 0xa8, 0x44, 0x61, 0x18, 0x56, 0x15, 0x99,
- 0x66, 0x46, 0x64, 0x61, 0x18, 0x56, 0x22, 0xd5, 0xce, 0x8c, 0xe7, 0x0a, 0xcc, 0x8e, 0xba, 0xf2,
- 0x2d, 0x91, 0xd7, 0xd6, 0x37, 0xc7, 0xbb, 0xe1, 0xc9, 0x3d, 0xf1, 0xbf, 0x93, 0x8f, 0x28, 0xdb,
- 0xf4, 0x28, 0x32, 0x0e, 0xa2, 0xb3, 0x35, 0x5f, 0x02, 0x4e, 0xda, 0xb0, 0xf7, 0xe8, 0xcb, 0x50,
- 0x9a, 0xf6, 0xe7, 0x1a, 0xe3, 0x80, 0x4f, 0x29, 0xb5, 0x04, 0xfd, 0x8a, 0x95, 0x8c, 0x09, 0xa4,
- 0x0e, 0x58, 0x13, 0x47, 0xa8, 0x13, 0x34, 0xec, 0xf6, 0x7f, 0x2b, 0x30, 0xf2, 0xe2, 0xca, 0xcd,
- 0x44, 0xff, 0x75, 0xeb, 0xfd, 0xa7, 0x8f, 0x6e, 0x6f, 0xf4, 0x6e, 0x7c, 0x0f, 0x75, 0x5b, 0x9f,
- 0x97, 0x5d, 0xc6, 0x38, 0xaa, 0xe3, 0x2d, 0x5a, 0x22, 0x8f, 0xcc, 0xb0, 0x82, 0xcc, 0xa6, 0xbd,
- 0x00, 0xe6, 0xcf, 0x2a, 0x50, 0xd0, 0x0e, 0xca, 0x4d, 0xb8, 0x27, 0xec, 0x86, 0x8c, 0xe4, 0xaa,
- 0xc1, 0xec, 0xd9, 0x7e, 0x87, 0x4d, 0x51, 0xa3, 0x1d, 0x94, 0x88, 0xf0, 0x30, 0xac, 0x20, 0xfb,
- 0xbe, 0x76, 0xf2, 0xbb, 0x1f, 0xca, 0x0e, 0x83, 0x13, 0x78, 0x6c, 0xf0, 0x97, 0x4a, 0x62, 0x53,
- 0xd0, 0x21, 0xa5, 0xc8, 0x5f, 0x3b, 0xe0, 0x1a, 0x17, 0xdf, 0x9b, 0x01, 0x68, 0x1b, 0x6a, 0xcf,
- 0xa6, 0x41, 0xe3, 0x46, 0x70, 0x1c, 0xfb, 0x3c, 0xb0, 0x1c, 0x3b, 0xe5, 0x7c, 0xf4, 0x21, 0x77,
- 0x62, 0x2c, 0x2a, 0x5d, 0xee, 0xd2, 0xec, 0x70, 0x88, 0x57, 0x11, 0xc8, 0x42, 0xf8, 0x67, 0x8e,
- 0xc8, 0x8c, 0xd4, 0x1e, 0xce, 0x0d, 0xdb, 0x03, 0xf4, 0x73, 0x43, 0x05, 0xbf, 0xad, 0xa1, 0x4c,
- 0x6e, 0xa4, 0x55, 0x00, 0x0b, 0x5d, 0x07, 0xbc, 0x19, 0x6f, 0x3d, 0x4f, 0x80, 0xe4, 0x53, 0x7f,
- 0xdf, 0xd5, 0xc2, 0x0f, 0xc5, 0xde, 0xfa, 0x78, 0xf5, 0xd6, 0xfb, 0xda, 0xaa, 0xba, 0xae, 0xfe,
- 0xf3, 0xce, 0x8a, 0xa4, 0x41, 0x0b, 0xe3, 0xc7, 0x01, 0x1b, 0x35, 0xdb, 0x83, 0xfc, 0x91, 0x4d,
- 0xf2, 0xe7, 0x76, 0x0f, 0xc0, 0xaf, 0x68, 0xe1, 0x81, 0x18, 0xb3, 0xf0, 0x02, 0x8d, 0xcd, 0x36,
- 0x01, 0x4a, 0x94, 0xe2, 0x7e, 0xaa, 0xc2, 0x91, 0x44, 0xa5, 0xd5, 0x50, 0x45, 0x87, 0xf5, 0xe4,
- 0x3b, 0xc0, 0xd9, 0x81, 0x1b, 0x24, 0x29, 0x98, 0xd4, 0x9e, 0x7f, 0xe7, 0xea, 0xa9, 0x83, 0xab,
- 0xf7, 0xb4, 0x88, 0x98, 0x87, 0x9c, 0xf6, 0xb7, 0x35, 0xf8, 0xd8, 0x35, 0x4b, 0xfb, 0xde, 0xd1,
- 0x81, 0xc6, 0x6e, 0x0e, 0x9c, 0x76, 0x8e, 0x03, 0x95, 0x27, 0x74, 0x10, 0xc2, 0x9f, 0x82, 0x8f,
- 0x4d, 0x75, 0x78, 0xf3, 0x91, 0xeb, 0x8e, 0x1d, 0x91, 0xfd, 0x80, 0x80, 0x39, 0xc9, 0xb1, 0x07,
- 0xbe, 0x03, 0x63, 0x65, 0x58, 0x5f, 0x74, 0x2e, 0x4d, 0x35, 0xe6, 0xb4, 0x55, 0x5c, 0x62, 0xe7,
- 0x3e, 0x71, 0x55, 0x5a, 0x03, 0xe7, 0x6d, 0xf3, 0x6b, 0xd9, 0x0e, 0x56, 0x88, 0xe6, 0x35, 0x50,
- 0x09, 0x52, 0xdf, 0x41, 0xad, 0xbb, 0xad, 0x9f, 0xf4, 0xc1, 0x07, 0xfa, 0x84, 0x0f, 0x9e, 0x5e,
- 0xa0, 0xe3, 0x3c, 0xa5, 0x6e, 0x02, 0x6f, 0x11, 0xc1, 0x35, 0xc8, 0xc1, 0xce, 0xe2, 0x5f, 0x3c,
- 0x13, 0x58, 0xac, 0xa9, 0xc5, 0xf9, 0xc3, 0xb4, 0x8e, 0xcf, 0x71, 0xf4, 0x38, 0x0e, 0xeb, 0x1e,
- 0xe8, 0x21, 0x39, 0xad, 0x9a, 0xe5, 0x36, 0x68, 0x9d, 0xe0, 0xac, 0x76, 0x1c, 0x3b, 0xa5, 0x8d,
- 0xfe, 0xb8, 0x84, 0xf7, 0xf6, 0xd2, 0xc3, 0x89, 0x0c, 0xb2, 0x1c, 0xcb, 0x9a, 0x40, 0x83, 0x98,
- 0x97, 0xe4, 0xfa, 0xdb, 0x77, 0x39, 0x17, 0x69, 0xc1, 0x9d, 0x4d, 0xaa, 0x54, 0x7f, 0xff, 0xd5,
- 0xe9, 0x4a, 0x1c, 0x92, 0x84, 0x4d, 0x41, 0x0b, 0xb3, 0xc7, 0x19, 0x6f, 0xa5, 0x92, 0xe3, 0x46,
- 0x15, 0x8a, 0x6c, 0xdd, 0x66, 0x08, 0xbc, 0x68, 0xa7, 0x80, 0xea, 0xf3, 0xec, 0x70, 0x9c, 0x8f,
- 0x6f, 0x89, 0x5f, 0x05, 0x42, 0xd2, 0xfb, 0xfb, 0x0b, 0x3b, 0xf3, 0x3b, 0xb2, 0xdc, 0x8f, 0xb1,
- 0x6e, 0x1f, 0xe8, 0x89, 0xef, 0xc2, 0xfe, 0x02, 0x85, 0x3e, 0x72, 0x4b, 0x21, 0x34, 0x01, 0xce,
- 0x63, 0xc7, 0x04, 0x6d, 0x33, 0xbc, 0x7c, 0xa7, 0x55, 0x7a, 0x0f, 0x0f, 0x45, 0x04, 0xf3, 0xa5,
- 0xe5, 0xc0, 0xfb, 0x2e, 0xb1, 0xd9, 0x73, 0x1f, 0x7f, 0x96, 0x40, 0xe3, 0xc0, 0x76, 0xf6, 0xaf,
- 0x2b, 0x2b, 0x0a, 0x7b, 0x7f, 0xde, 0x05, 0xbd, 0xbf, 0x7e, 0x17, 0x23, 0x25, 0x2e, 0x62, 0x5b,
- 0xf0, 0x27, 0x55, 0x4e, 0xc5, 0x7d, 0x25, 0xf2, 0x9a, 0x3a, 0xe7, 0x14, 0xe3, 0x80, 0xea, 0x31,
- 0x0b, 0x80, 0x8b, 0xc0, 0x05, 0x5d, 0xdd, 0x1e, 0xe3, 0x93, 0x6b, 0xcb, 0x79, 0x7b, 0x3f, 0xb5,
- 0x06, 0x52, 0x2b, 0xe6, 0x3a, 0xaa, 0xf1, 0xaf, 0x1d, 0x96, 0x6b, 0x0e, 0x52, 0x04, 0xd7, 0x7e,
- 0x69, 0xf7, 0x2b, 0x58, 0x69, 0xb6, 0xf5, 0x50, 0xbc, 0x7a, 0x85, 0x79, 0x42, 0x9c, 0x95, 0x5e,
- 0x60, 0x5c, 0x72, 0x1b, 0xe4, 0xaa, 0xb6, 0xf1, 0xe6, 0x77, 0xec, 0xb4, 0x5f, 0x6c, 0xd1, 0xe9,
- 0x28, 0xb0, 0x25, 0x40, 0xc2, 0x5e, 0xbe, 0x73, 0x06, 0xcb, 0xd2, 0x3c, 0xd0, 0x71, 0x75, 0x20,
- 0xb9, 0xaa, 0x90, 0x1d, 0xc8, 0x88, 0xe0, 0x4a, 0xf0, 0x48, 0x07, 0x8a, 0x1c, 0xcc, 0x41, 0x92,
- 0x27, 0xd9, 0xa9, 0xd0, 0x2f, 0x78, 0x64, 0x6d, 0x79, 0x5f, 0x06, 0xbf, 0xa1, 0xf6, 0xe3, 0xc1,
- 0xf7, 0xd6, 0xb8, 0x69, 0xac, 0x1e, 0xdf, 0x9f, 0x17, 0x00, 0xd1, 0xb9, 0x63, 0xaf, 0x46, 0x7f,
- 0x2e, 0x44, 0x7e, 0x01, 0xf6, 0x96, 0x34, 0x75, 0xdd, 0x01, 0xf7, 0xc0, 0x2f, 0x80, 0x15, 0x14,
- 0x1c, 0xe4, 0x32, 0x8e, 0x01, 0xce, 0x20, 0xc7, 0x5f, 0x22, 0x3e, 0x02, 0xd9, 0x6f, 0x01, 0x6c,
- 0x18, 0x4f, 0x5a, 0xfe, 0x6d, 0x55, 0xa1, 0xce, 0xc3, 0x82, 0x48, 0x31, 0xe4, 0x44, 0xe0, 0x28,
- 0x3c, 0x19, 0xc0, 0x39, 0x91, 0x83, 0xc0, 0xe5, 0x81, 0x77, 0xa8, 0x1f, 0xf6, 0xea, 0x2f, 0xb4,
- 0xd1, 0xc6, 0x38, 0x9c, 0x1c, 0x07, 0x88, 0x83, 0x07, 0x4c, 0xc6, 0x9e, 0xe3, 0x5e, 0x08, 0xb1,
- 0x98, 0xf8, 0x3e, 0xaa, 0xc9, 0x6e, 0xc3, 0x9e, 0x1c, 0x61, 0x99, 0x11, 0xdc, 0x01, 0x1c, 0x07,
- 0xf6, 0x97, 0x18, 0xb5, 0x13, 0xa2, 0xe9, 0x58, 0xef, 0xfb, 0xe2, 0xe5, 0x97, 0xff, 0xea, 0xa9,
- 0x34, 0xca, 0xcc, 0x2f, 0x7f, 0xb1, 0x1c, 0xe0, 0x05, 0x70, 0x64, 0x44, 0xf0, 0x0c, 0xe0, 0x19,
- 0xc0, 0x63, 0x2a, 0x10, 0x9c, 0x44, 0xdc, 0x6b, 0xaa, 0x57, 0xbc, 0xef, 0x78, 0x00, 0x39, 0xc4,
- 0xc7, 0x5e, 0x8a, 0x81, 0x8c, 0x88, 0xde, 0x00, 0x8c, 0x06, 0xbe, 0xc3, 0xc9, 0xae, 0x51, 0x60,
- 0xd3, 0x8a, 0x78, 0xc0, 0x0e, 0x25, 0xff, 0xfd, 0xdb, 0x8f, 0x09, 0xd7, 0x52, 0xac, 0x4d, 0xd5,
- 0x5c, 0xa9, 0xe3, 0xad, 0xc1, 0x80, 0x60, 0x39, 0xc3, 0x87, 0x70, 0xe1, 0x52, 0x38, 0x15, 0xc0,
- 0x70, 0xe2, 0x1c, 0x38, 0x87, 0x0e, 0x05, 0x23, 0x03, 0x9c, 0x38, 0x76, 0x0e, 0x1c, 0x23, 0x87,
- 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38, 0x87, 0x0e, 0x05, 0x23, 0x03, 0x9c, 0x38, 0x76, 0x0e, 0x1c,
- 0x23, 0x87, 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38, 0x87, 0x0e, 0x05, 0x23, 0x03, 0x9c, 0x38, 0x76,
- 0x0e, 0x1c, 0x23, 0x87, 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38, 0x87, 0x0e, 0x05, 0x23, 0x03, 0x9c,
- 0x38, 0x76, 0x0e, 0x1c, 0x23, 0x87, 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38, 0x87, 0x0e, 0x05, 0x23,
- 0x03, 0x9c, 0x38, 0x76, 0x0e, 0x1c, 0x23, 0x87, 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38, 0x87, 0x0e,
- 0x05, 0x23, 0x03, 0x9c, 0x38, 0x76, 0x0e, 0x1c, 0x23, 0x87, 0x9c, 0x05, 0x76, 0x03, 0x1c, 0x38,
- 0x87, 0x0e, 0x05, 0x23, 0x0f, 0xfe, 0xf6, 0xa7, 0xbf, 0x78, 0xfb, 0x2d, 0xfb, 0xc5, 0x00, 0x00,
- 0x00, 0x00, 0x45, 0x49, 0x44, 0x4e, 0x42, 0xae, 0x82, 0x60,
- ],
- disp: function()
- {
- // Do Nothing
-
- throw "Does Nothing!";
- }
-
-};
-
-try
-{
- LOGO.disp();
-}
-catch(e)
-{
- alert("Error: " + e + "\n");
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/resources/jetty-logging.properties b/jetty-spdy/spdy-http-server/src/test/resources/jetty-logging.properties
deleted file mode 100644
index be1b7aa594..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/resources/jetty-logging.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-#org.eclipse.jetty.spdy.LEVEL=DEBUG
-#org.eclipse.jetty.server.LEVEL=DEBUG
-#org.eclipse.jetty.io.ssl.LEVEL=DEBUG
-#org.eclipse.jetty.spdy.LEVEL=DEBUG
-#org.eclipse.jetty.client.LEVEL=DEBUG
-#org.eclipse.jetty.spdy.server.http.ReferrerPushStrategy.LEVEL=DEBUG
-#org.eclipse.jetty.spdy.server.proxy.LEVEL=DEBUG
-#org.mortbay.LEVEL=DEBUG
-
diff --git a/jetty-spdy/spdy-http-server/src/test/resources/keystore.jks b/jetty-spdy/spdy-http-server/src/test/resources/keystore.jks
deleted file mode 100644
index 428ba54776..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/resources/keystore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-http-server/src/test/resources/truststore.jks b/jetty-spdy/spdy-http-server/src/test/resources/truststore.jks
deleted file mode 100644
index 839cb8c351..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/resources/truststore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-npn-tests/pom.xml b/jetty-spdy/spdy-npn-tests/pom.xml
deleted file mode 100644
index 7b54c55fe2..0000000000
--- a/jetty-spdy/spdy-npn-tests/pom.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-parent</artifactId>
- <version>9.2.11-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>spdy-npn-tests</artifactId>
- <name>Jetty :: SPDY :: NPN Tests</name>
-
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copy</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.mortbay.jetty.npn</groupId>
- <artifactId>npn-boot</artifactId>
- <version>${npn.version}</version>
- <type>jar</type>
- <overWrite>false</overWrite>
- <outputDirectory>${project.build.directory}/npn</outputDirectory>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>-Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar</argLine>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty.npn</groupId>
- <artifactId>npn-api</artifactId>
- <version>${npn.api.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-start</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-server</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-server</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-http-server</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-http-server</artifactId>
- <version>${project.version}</version>
- <classifier>tests</classifier>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractNPNTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractNPNTest.java
deleted file mode 100644
index d225d1fc04..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractNPNTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.net.InetSocketAddress;
-
-import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.toolchain.test.TestTracker;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.junit.After;
-import org.junit.Rule;
-
-public class AbstractNPNTest
-{
- @Rule
- public final TestTracker tracker = new TestTracker();
- protected Server server;
- protected SPDYServerConnector connector;
- protected SPDYClient.Factory clientFactory;
-
- protected InetSocketAddress prepare() throws Exception
- {
- server = new Server();
- connector = new SPDYServerConnector(server, newSslContextFactory(), null);
- connector.setPort(0);
- connector.setIdleTimeout(30000);
- server.addConnector(connector);
- server.start();
-
- QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setName(threadPool.getName() + "-client");
- clientFactory = new SPDYClient.Factory(threadPool);
- clientFactory.start();
-
- NextProtoNego.debug = true;
-
- return new InetSocketAddress("localhost", connector.getLocalPort());
- }
-
- protected SslContextFactory newSslContextFactory()
- {
- SslContextFactory sslContextFactory = new SslContextFactory();
- sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
- sslContextFactory.setKeyStorePassword("storepwd");
- sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
- sslContextFactory.setTrustStorePassword("storepwd");
- sslContextFactory.setProtocol("TLSv1");
- sslContextFactory.setIncludeProtocols("TLSv1");
- return sslContextFactory;
- }
-
- @After
- public void dispose() throws Exception
- {
- clientFactory.stop();
- server.stop();
- }
-}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNModuleTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNModuleTest.java
deleted file mode 100644
index 72c1c6d077..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNModuleTest.java
+++ /dev/null
@@ -1,193 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import org.eclipse.jetty.start.BaseHome;
-import org.eclipse.jetty.start.FileArg;
-import org.eclipse.jetty.start.Module;
-import org.eclipse.jetty.toolchain.test.FS;
-import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.eclipse.jetty.util.IO;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-@RunWith(Parameterized.class)
-public class NPNModuleTest
-{
- /** This is here to prevent pointless download attempts */
- private static final List<String> KNOWN_GOOD_NPN_URLS = new ArrayList<>();
-
- static
- {
- /** The main() method in this test case can be run to validate this list independently */
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.11.v20150415/npn-boot-1.1.11.v20150415.jar");
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.10.v20150130/npn-boot-1.1.10.v20150130.jar");
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.9.v20141016/npn-boot-1.1.9.v20141016.jar");
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.8.v20141013/npn-boot-1.1.8.v20141013.jar");
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.6.v20130911/npn-boot-1.1.6.v20130911.jar");
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar");
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.4.v20130313/npn-boot-1.1.4.v20130313.jar");
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.3.v20130313/npn-boot-1.1.3.v20130313.jar");
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.2.v20130305/npn-boot-1.1.2.v20130305.jar");
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.1.v20121030/npn-boot-1.1.1.v20121030.jar");
- KNOWN_GOOD_NPN_URLS.add("http://central.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.0.v20120525/npn-boot-1.1.0.v20120525.jar");
- }
-
- @Parameters(name = "{index}: mod:{0}")
- public static List<Object[]> data()
- {
- File npnBootModDir = MavenTestingUtils.getProjectDir("../spdy-http-server/src/main/config/modules/protonego-impl");
- List<Object[]> data = new ArrayList<>();
- for (File file : npnBootModDir.listFiles())
- {
- if (Pattern.matches("npn-.*\\.mod",file.getName()))
- {
- data.add(new Object[] { file.getName() });
- }
- }
- return data;
- }
-
- @Parameter(value = 0)
- public String modBootFile;
-
- private static BaseHome basehome;
-
- @BeforeClass
- public static void initBaseHome() throws IOException
- {
- File homeDir = MavenTestingUtils.getProjectDir("../spdy-http-server/src/main/config");
- File baseDir = MavenTestingUtils.getTargetTestingDir(NPNModuleTest.class.getName());
- FS.ensureEmpty(baseDir);
-
- String cmdLine[] = { "jetty.home="+homeDir.getAbsolutePath(),"jetty.base="+baseDir.getAbsolutePath() };
- basehome = new BaseHome(cmdLine);
- }
-
- /**
- * Check the sanity of the npn-boot file module
- */
- @Test
- public void testModuleValues() throws IOException
- {
- Path modFile = basehome.getPath("modules/protonego-impl/" + modBootFile);
- Module mod = new Module(basehome,modFile);
- assertNotNull("module",mod);
-
- // Validate logical name
- assertThat("Module name",mod.getName(),is("protonego-boot"));
-
- List<String> expectedBootClasspath = new ArrayList<>();
-
- for (String line : mod.getFiles())
- {
- FileArg farg = new FileArg(line);
- if (farg.uri != null)
- {
- assertTrue("Not a known good NPN URL: " + farg.uri,KNOWN_GOOD_NPN_URLS.contains(farg.uri));
- expectedBootClasspath.add("-Xbootclasspath/p:" + farg.location);
- }
- }
-
- for (String line : mod.getJvmArgs())
- {
- expectedBootClasspath.remove(line);
- }
-
- if (expectedBootClasspath.size() > 0)
- {
- StringBuilder err = new StringBuilder();
- err.append("XBootClasspath mismatch between [files] and [exec]");
- err.append("\nThe following are inferred from your [files] definition in ");
- err.append(modFile.toAbsolutePath().toString());
- err.append("\nbut are not referenced in your [exec] section");
- for (String entry : expectedBootClasspath)
- {
- err.append("\n").append(entry);
- }
- fail(err.toString());
- }
- }
-
- public static void main(String[] args)
- {
- File outputDir = MavenTestingUtils.getTargetTestingDir(NPNModuleTest.class.getSimpleName() + "-main");
- FS.ensureEmpty(outputDir);
- for (String ref : KNOWN_GOOD_NPN_URLS)
- {
- try
- {
- URL url = new URL(ref);
- System.err.printf("Attempting: %s%n",ref);
- HttpURLConnection connection = (HttpURLConnection)url.openConnection();
- String refname = url.toURI().getPath();
- int idx = refname.lastIndexOf('/');
- File outputFile = new File(outputDir,refname.substring(idx));
- try (InputStream stream = connection.getInputStream(); FileOutputStream out = new FileOutputStream(outputFile))
- {
- assertThat("Response Status Code",connection.getResponseCode(),is(200));
- IO.copy(stream,out);
- System.err.printf("Downloaded %,d bytes%n",outputFile.length());
- }
- catch (IOException e)
- {
- e.printStackTrace(System.err);
- }
- }
- catch (MalformedURLException e)
- {
- System.err.printf("Bad Ref: %s%n",ref);
- e.printStackTrace(System.err);
- }
- catch (URISyntaxException e)
- {
- System.err.printf("Bad Ref Syntax: %s%n",ref);
- e.printStackTrace(System.err);
- }
- catch (IOException e)
- {
- System.err.printf("Bad Connection: %s%n",ref);
- e.printStackTrace(System.err);
- }
- }
- }
-}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNNegotiationTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNNegotiationTest.java
deleted file mode 100644
index 57f46005cb..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNNegotiationTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-
-import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class NPNNegotiationTest extends AbstractNPNTest
-{
- @Test
- public void testServerAdvertisingHTTPSpeaksHTTP() throws Exception
- {
- InetSocketAddress address = prepare();
- connector.addConnectionFactory(new HttpConnectionFactory());
-
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLContext sslContext = sslContextFactory.getSslContext();
-
- try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort()))
- {
- client.setUseClientMode(true);
- client.setSoTimeout(5000);
-
- NextProtoNego.put(client, new NextProtoNego.ClientProvider()
- {
- @Override
- public boolean supports()
- {
- return true;
- }
-
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public String selectProtocol(List<String> strings)
- {
- Assert.assertNotNull(strings);
- String protocol = "http/1.1";
- Assert.assertTrue(strings.contains(protocol));
- return protocol;
- }
- });
-
- client.startHandshake();
-
- // Verify that the server really speaks http/1.1
-
- OutputStream output = client.getOutputStream();
- output.write(("" +
- "GET / HTTP/1.1\r\n" +
- "Host: localhost:" + address.getPort() + "\r\n" +
- "\r\n" +
- "").getBytes(StandardCharsets.UTF_8));
- output.flush();
-
- InputStream input = client.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
- String line = reader.readLine();
- Assert.assertTrue(line.contains(" 404 "));
- }
- }
-
- @Test
- public void testServerAdvertisingSPDYAndHTTPSpeaksHTTPWhenNegotiated() throws Exception
- {
- InetSocketAddress address = prepare();
- connector.addConnectionFactory(new HttpConnectionFactory());
-
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLContext sslContext = sslContextFactory.getSslContext();
- try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort()))
- {
- client.setUseClientMode(true);
- client.setSoTimeout(5000);
-
- NextProtoNego.put(client, new NextProtoNego.ClientProvider()
- {
- @Override
- public boolean supports()
- {
- return true;
- }
-
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public String selectProtocol(List<String> strings)
- {
- Assert.assertNotNull(strings);
- String spdyProtocol = "spdy/2";
- Assert.assertTrue(strings.contains(spdyProtocol));
- String httpProtocol = "http/1.1";
- Assert.assertTrue(strings.contains(httpProtocol));
- Assert.assertTrue(strings.indexOf(spdyProtocol) < strings.indexOf(httpProtocol));
- return httpProtocol;
- }
- });
-
- client.startHandshake();
-
- // Verify that the server really speaks http/1.1
-
- OutputStream output = client.getOutputStream();
- output.write(("" +
- "GET / HTTP/1.1\r\n" +
- "Host: localhost:" + address.getPort() + "\r\n" +
- "\r\n" +
- "").getBytes(StandardCharsets.UTF_8));
- output.flush();
-
- InputStream input = client.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
- String line = reader.readLine();
- Assert.assertTrue(line.contains(" 404 "));
- }
- }
-
- @Test
- public void testServerAdvertisingSPDYAndHTTPSpeaksDefaultProtocolWhenNPNMissing() throws Exception
- {
- InetSocketAddress address = prepare();
- connector.addConnectionFactory(new HttpConnectionFactory());
-
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLContext sslContext = sslContextFactory.getSslContext();
- try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort()))
- {
- client.setUseClientMode(true);
- client.setSoTimeout(5000);
-
- NextProtoNego.put(client, new NextProtoNego.ClientProvider()
- {
- @Override
- public boolean supports()
- {
- return false;
- }
-
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public String selectProtocol(List<String> strings)
- {
- return null;
- }
- });
-
- client.startHandshake();
-
- // Verify that the server really speaks http/1.1
-
- OutputStream output = client.getOutputStream();
- output.write(("" +
- "GET / HTTP/1.1\r\n" +
- "Host: localhost:" + address.getPort() + "\r\n" +
- "\r\n" +
- "").getBytes(StandardCharsets.UTF_8));
- output.flush();
-
- InputStream input = client.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
- String line = reader.readLine();
- Assert.assertTrue(line.contains(" 404 "));
- }
- }
-}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLEngineLeakTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLEngineLeakTest.java
deleted file mode 100644
index f2350eddc1..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLEngineLeakTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.lang.reflect.Field;
-import java.net.InetSocketAddress;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SSLEngineLeakTest extends AbstractNPNTest
-{
- @Test
- public void testSSLEngineLeak() throws Exception
- {
- System.gc();
- Thread.sleep(1000);
-
- Field field = NextProtoNego.class.getDeclaredField("objects");
- field.setAccessible(true);
- @SuppressWarnings("unchecked")
- Map<Object, NextProtoNego.Provider> objects = (Map<Object, NextProtoNego.Provider>)field.get(null);
- int initialSize = objects.size();
-
- avoidStackLocalVariables();
- // Allow the close to arrive to the server and the selector to process it
- Thread.sleep(1000);
-
- // Perform GC to be sure that the map is cleared
- System.gc();
- Thread.sleep(1000);
-
- // Check that the map is empty
- if (objects.size() != initialSize)
- {
- System.err.println(objects);
- server.dumpStdErr();
- }
-
- Assert.assertEquals(initialSize, objects.size());
- }
-
- private void avoidStackLocalVariables() throws Exception
- {
- InetSocketAddress address = prepare();
- Session session = clientFactory.newSPDYClient(SPDY.V3).connect(address, null);
- session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
- }
-}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLSynReplyTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLSynReplyTest.java
deleted file mode 100644
index 1bb2a14743..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLSynReplyTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.List;
-import javax.net.ssl.SSLEngine;
-
-import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SSLSynReplyTest extends AbstractNPNTest
-{
- @Test
- public void testGentleCloseDuringHandshake() throws Exception
- {
- InetSocketAddress address = prepare();
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
- sslEngine.setUseClientMode(true);
- NextProtoNego.put(sslEngine, new NextProtoNego.ClientProvider()
- {
- @Override
- public boolean supports()
- {
- return true;
- }
-
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public String selectProtocol(List<String> protocols)
- {
- return null;
- }
- });
- sslEngine.beginHandshake();
-
- ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
- sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
- encrypted.flip();
-
- try (SocketChannel channel = SocketChannel.open(address))
- {
- // Send ClientHello, immediately followed by TLS Close Alert and then by FIN
- channel.write(encrypted);
- sslEngine.closeOutbound();
- encrypted.clear();
- sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
- encrypted.flip();
- channel.write(encrypted);
- channel.shutdownOutput();
-
- // Read ServerHello from server
- encrypted.clear();
- int read = channel.read(encrypted);
- encrypted.flip();
- Assert.assertTrue(read > 0);
- // Cannot decrypt, as the SSLEngine has been already closed
-
- // Now if we read more, we should either read the TLS Close Alert, or directly -1
- encrypted.clear();
- read = channel.read(encrypted);
- // Sending a TLS Close Alert during handshake results in an exception when
- // unwrapping that the server react to by closing the connection abruptly.
- Assert.assertTrue(read < 0);
- }
- }
-
- @Test
- public void testAbruptCloseDuringHandshake() throws Exception
- {
- InetSocketAddress address = prepare();
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
- sslEngine.setUseClientMode(true);
- NextProtoNego.put(sslEngine, new NextProtoNego.ClientProvider()
- {
- @Override
- public boolean supports()
- {
- return true;
- }
-
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public String selectProtocol(List<String> protocols)
- {
- return null;
- }
- });
- sslEngine.beginHandshake();
-
- ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
- sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
- encrypted.flip();
-
- try (SocketChannel channel = SocketChannel.open(address))
- {
- // Send ClientHello, immediately followed by FIN (no TLS Close Alert)
- channel.write(encrypted);
- channel.shutdownOutput();
-
- // Read ServerHello from server
- encrypted.clear();
- int read = channel.read(encrypted);
- encrypted.flip();
- Assert.assertTrue(read > 0);
- ByteBuffer decrypted = ByteBuffer.allocate(sslEngine.getSession().getApplicationBufferSize());
- sslEngine.unwrap(encrypted, decrypted);
-
- // Now if we read more, we should either read the TLS Close Alert, or directly -1
- encrypted.clear();
- read = channel.read(encrypted);
- // Since we have close the connection abruptly, the server also does so
- Assert.assertTrue(read < 0);
- }
- }
-}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPLoadTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPLoadTest.java
deleted file mode 100644
index 72f6ca4733..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPLoadTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
-
-public class NPNProxySPDYToHTTPLoadTest extends ProxySPDYToHTTPLoadTest
-{
- public NPNProxySPDYToHTTPLoadTest(short version)
- {
- super(version, new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"));
- }
-}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPTest.java
deleted file mode 100644
index e28ca0e4b8..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPTest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-public class NPNProxySPDYToHTTPTest extends ProxySPDYToHTTPTest
-{
- public NPNProxySPDYToHTTPTest(short version)
- {
- super(version);
- }
-}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYLoadTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYLoadTest.java
deleted file mode 100644
index 3d00c6eac4..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYLoadTest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-public class NPNProxySPDYToSPDYLoadTest extends ProxySPDYToSPDYLoadTest
-{
- public NPNProxySPDYToSPDYLoadTest(short version)
- {
- super(version);
- }
-}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYTest.java
deleted file mode 100644
index d92ba2b0d5..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYTest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server.proxy;
-
-public class NPNProxySPDYToSPDYTest extends ProxySPDYToSPDYTest
-{
- public NPNProxySPDYToSPDYTest(short version)
- {
- super(version);
- }
-}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/resources/jetty-logging.properties b/jetty-spdy/spdy-npn-tests/src/test/resources/jetty-logging.properties
deleted file mode 100644
index ead13ec197..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/resources/jetty-logging.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-#org.eclipse.jetty.spdy.LEVEL=DEBUG
diff --git a/jetty-spdy/spdy-npn-tests/src/test/resources/keystore.jks b/jetty-spdy/spdy-npn-tests/src/test/resources/keystore.jks
deleted file mode 100644
index 428ba54776..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/resources/keystore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-npn-tests/src/test/resources/truststore.jks b/jetty-spdy/spdy-npn-tests/src/test/resources/truststore.jks
deleted file mode 100644
index 839cb8c351..0000000000
--- a/jetty-spdy/spdy-npn-tests/src/test/resources/truststore.jks
+++ /dev/null
Binary files differ
diff --git a/jetty-spdy/spdy-server/pom.xml b/jetty-spdy/spdy-server/pom.xml
deleted file mode 100644
index bd16a8646f..0000000000
--- a/jetty-spdy/spdy-server/pom.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-parent</artifactId>
- <version>9.2.15-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>spdy-server</artifactId>
- <name>Jetty :: SPDY :: Server Binding</name>
-
- <properties>
- <bundle-symbolic-name>${project.groupId}.server</bundle-symbolic-name>
- </properties>
-
- <url>http://www.eclipse.org/jetty</url>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>manifest</goal>
- </goals>
- <configuration>
- <instructions>
- <Export-Package>org.eclipse.jetty.spdy.server;version="9.1"</Export-Package>
- <Import-Package>org.eclipse.jetty.alpn;resolution:=optional,org.eclipse.jetty.alpn.server;resolution:=optional, org.eclipse.jetty.npn;resolution:=optional,org.eclipse.jetty.*;version="[9.0,10.0)",*</Import-Package>
- <_nouses>true</_nouses>
- </instructions>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-core</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.spdy</groupId>
- <artifactId>spdy-client</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-server</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.npn</groupId>
- <artifactId>npn-api</artifactId>
- <version>${npn.api.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty.alpn</groupId>
- <artifactId>alpn-api</artifactId>
- <version>${alpn.api.version}</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnection.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnection.java
deleted file mode 100644
index 0d5e20b6a1..0000000000
--- a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnection.java
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.util.List;
-import javax.net.ssl.SSLEngine;
-
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.NegotiatingServerConnection;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class NPNServerConnection extends NegotiatingServerConnection implements NextProtoNego.ServerProvider
-{
- private static final Logger LOG = Log.getLogger(NPNServerConnection.class);
-
- public NPNServerConnection(EndPoint endPoint, SSLEngine engine, Connector connector, List<String> protocols, String defaultProtocol)
- {
- super(connector, endPoint, engine, protocols, defaultProtocol);
- NextProtoNego.put(engine, this);
- }
-
- @Override
- public void unsupported()
- {
- protocolSelected(getDefaultProtocol());
- }
-
- @Override
- public List<String> protocols()
- {
- return getProtocols();
- }
-
- @Override
- public void protocolSelected(String protocol)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("{} protocol selected {}", this, protocol);
- setProtocol(protocol != null ? protocol : getDefaultProtocol());
- NextProtoNego.remove(getSSLEngine());
- }
-
- @Override
- public void close()
- {
- NextProtoNego.remove(getSSLEngine());
- super.close();
- }
-}
diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java
deleted file mode 100644
index 628d542ab2..0000000000
--- a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.util.List;
-import javax.net.ssl.SSLEngine;
-
-import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.NegotiatingServerConnectionFactory;
-import org.eclipse.jetty.util.annotation.Name;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class NPNServerConnectionFactory extends NegotiatingServerConnectionFactory
-{
- private static final Logger LOG = Log.getLogger(NPNServerConnectionFactory.class);
-
- public NPNServerConnectionFactory(@Name("protocols") String... protocols)
- {
- super("npn", protocols);
- try
- {
- ClassLoader npnClassLoader = NextProtoNego.class.getClassLoader();
- if (npnClassLoader != null)
- {
- LOG.warn("NPN must be in the boot classloader, not in: " + npnClassLoader);
- throw new IllegalStateException("NPN must be in the boot classloader");
- }
- }
- catch (Throwable x)
- {
- LOG.warn("NPN not available: " + x);
- throw new IllegalStateException("NPN not available", x);
- }
- }
-
- @Override
- protected AbstractConnection newServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol)
- {
- return new NPNServerConnection(endPoint, engine, connector, protocols, defaultProtocol);
- }
-}
diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnectionFactory.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnectionFactory.java
deleted file mode 100644
index 6ced409bd8..0000000000
--- a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnectionFactory.java
+++ /dev/null
@@ -1,245 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.eclipse.jetty.io.Connection;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.server.AbstractConnectionFactory;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.spdy.CompressionFactory;
-import org.eclipse.jetty.spdy.FlowControlStrategy;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.StandardSession;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.client.FlowControlStrategyFactory;
-import org.eclipse.jetty.spdy.client.SPDYConnection;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.annotation.ManagedAttribute;
-import org.eclipse.jetty.util.annotation.ManagedObject;
-
-@ManagedObject("SPDY Server Connection Factory")
-public class SPDYServerConnectionFactory extends AbstractConnectionFactory
-{
- /**
- * @deprecated use {@link #checkProtocolNegotiationAvailable()} instead.
- */
- @Deprecated
- public static void checkNPNAvailable()
- {
- checkProtocolNegotiationAvailable();
- }
-
- public static void checkProtocolNegotiationAvailable()
- {
- if (!isAvailableInBootClassPath("org.eclipse.jetty.alpn.ALPN") &&
- !isAvailableInBootClassPath("org.eclipse.jetty.npn.NextProtoNego"))
- throw new IllegalStateException("No ALPN nor NPN classes available");
- }
-
- private static boolean isAvailableInBootClassPath(String className)
- {
- try
- {
- Class<?> klass = ClassLoader.getSystemClassLoader().loadClass(className);
- if (klass.getClassLoader() != null)
- throw new IllegalStateException(className + " must be on JVM boot classpath");
- return true;
- }
- catch (ClassNotFoundException x)
- {
- return false;
- }
- }
-
- private final Queue<Session> sessions = new ConcurrentLinkedQueue<>();
- private final short version;
- private final ServerSessionFrameListener listener;
- private int initialWindowSize;
- private boolean dispatchIO;
-
- public SPDYServerConnectionFactory(int version)
- {
- this(version, null);
- }
-
- public SPDYServerConnectionFactory(int version, ServerSessionFrameListener listener)
- {
- super("spdy/" + version);
- this.version = (short)version;
- this.listener = listener;
- setInitialWindowSize(65536);
- setDispatchIO(true);
- }
-
- @ManagedAttribute("SPDY version")
- public short getVersion()
- {
- return version;
- }
-
- public ServerSessionFrameListener getServerSessionFrameListener()
- {
- return listener;
- }
-
- @Override
- public Connection newConnection(Connector connector, EndPoint endPoint)
- {
- CompressionFactory compressionFactory = new StandardCompressionFactory();
- Parser parser = new Parser(compressionFactory.newDecompressor());
- Generator generator = new Generator(connector.getByteBufferPool(), compressionFactory.newCompressor());
-
- ServerSessionFrameListener listener = provideServerSessionFrameListener(connector, endPoint);
- SPDYConnection connection = new ServerSPDYConnection(connector, endPoint, parser, listener,
- isDispatchIO(), getInputBufferSize());
-
- FlowControlStrategy flowControlStrategy = newFlowControlStrategy(version);
-
- StandardSession session = new StandardSession(getVersion(), connector.getByteBufferPool(),
- connector.getScheduler(), connection, endPoint, connection, 2, listener,
- generator, flowControlStrategy);
- session.setWindowSize(getInitialWindowSize());
- parser.addListener(session);
- connection.setSession(session);
-
- sessionOpened(session);
-
- return configure(connection, connector, endPoint);
- }
-
- protected FlowControlStrategy newFlowControlStrategy(short version)
- {
- return FlowControlStrategyFactory.newFlowControlStrategy(version);
- }
-
- protected ServerSessionFrameListener provideServerSessionFrameListener(Connector connector, EndPoint endPoint)
- {
- return listener;
- }
-
- @ManagedAttribute("Initial Window Size")
- public int getInitialWindowSize()
- {
- return initialWindowSize;
- }
-
- public void setInitialWindowSize(int initialWindowSize)
- {
- this.initialWindowSize = initialWindowSize;
- }
-
- @ManagedAttribute("Dispatch I/O to a pooled thread")
- public boolean isDispatchIO()
- {
- return dispatchIO;
- }
-
- public void setDispatchIO(boolean dispatchIO)
- {
- this.dispatchIO = dispatchIO;
- }
-
- protected boolean sessionOpened(Session session)
- {
- // Add sessions only if the connector is not stopping
- return sessions.offer(session);
- }
-
- protected boolean sessionClosed(Session session)
- {
- // Remove sessions only if the connector is not stopping
- // to avoid concurrent removes during iterations
- return sessions.remove(session);
- }
-
- void closeSessions()
- {
- for (Session session : sessions)
- session.goAway(new GoAwayInfo(), Callback.Adapter.INSTANCE);
- sessions.clear();
- }
-
- @Override
- protected void doStop() throws Exception
- {
- closeSessions();
- super.doStop();
- }
-
- public Collection<Session> getSessions()
- {
- return Collections.unmodifiableCollection(sessions);
- }
-
- @Override
- protected void dumpThis(Appendable out) throws IOException
- {
- super.dumpThis(out);
- dump(out, "", sessions);
- }
-
- private class ServerSPDYConnection extends SPDYConnection implements Runnable
- {
- private final ServerSessionFrameListener listener;
- private final AtomicBoolean connected = new AtomicBoolean();
-
- private ServerSPDYConnection(Connector connector, EndPoint endPoint, Parser parser,
- ServerSessionFrameListener listener, boolean dispatchIO, int bufferSize)
- {
- super(endPoint, connector.getByteBufferPool(), parser, connector.getExecutor(),
- dispatchIO, bufferSize);
- this.listener = listener;
- }
-
- @Override
- public void onOpen()
- {
- super.onOpen();
- if (connected.compareAndSet(false, true))
- getExecutor().execute(this);
- }
-
- @Override
- public void onClose()
- {
- super.onClose();
- sessionClosed(getSession());
- }
-
- @Override
- public void run()
- {
- // NPE guard to support tests
- if (listener != null)
- listener.onConnect(getSession());
- }
- }
-
-}
diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnector.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnector.java
deleted file mode 100644
index 4faee0bb60..0000000000
--- a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnector.java
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.util.Objects;
-
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.NegotiatingServerConnectionFactory;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-
-public class SPDYServerConnector extends ServerConnector
-{
- public SPDYServerConnector(Server server, ServerSessionFrameListener listener)
- {
- super(server, (SslContextFactory)null, new SPDYServerConnectionFactory(SPDY.V2, listener));
- }
-
- public SPDYServerConnector(Server server, SslContextFactory sslContextFactory, ServerSessionFrameListener listener)
- {
- this(server, sslContextFactory, listener, new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"));
- }
-
- public SPDYServerConnector(Server server, SslContextFactory sslContextFactory, ServerSessionFrameListener listener, NegotiatingServerConnectionFactory negotiator)
- {
- super(server, Objects.requireNonNull(sslContextFactory),
- negotiator,
- new SPDYServerConnectionFactory(SPDY.V3, listener),
- new SPDYServerConnectionFactory(SPDY.V2, listener),
- new HttpConnectionFactory());
- negotiator.setDefaultProtocol("http/1.1");
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/AbstractTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/AbstractTest.java
deleted file mode 100644
index 1366f0fec6..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/AbstractTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import java.net.InetSocketAddress;
-import java.util.concurrent.Executor;
-
-import org.eclipse.jetty.server.ConnectionFactory;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.junit.After;
-import org.junit.Rule;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-
-public abstract class AbstractTest
-{
- @Rule
- public final TestWatcher testName = new TestWatcher()
- {
-
- @Override
- public void starting(Description description)
- {
- super.starting(description);
- System.err.printf("Running %s.%s()%n",
- description.getClassName(),
- description.getMethodName());
- }
- };
-
- protected final short version = SPDY.V2;
-
- protected Server server;
- protected SPDYClient.Factory clientFactory;
- protected ServerConnector connector;
-
- protected InetSocketAddress startServer(ServerSessionFrameListener listener) throws Exception
- {
- return startServer(version, listener);
- }
-
- protected InetSocketAddress startServer(short version, ServerSessionFrameListener listener) throws Exception
- {
- if (server == null)
- server = newServer();
- if (connector == null)
- connector = newSPDYServerConnector(server, listener);
- if (listener == null)
- listener = connector.getConnectionFactory(SPDYServerConnectionFactory.class).getServerSessionFrameListener();
-
- ConnectionFactory spdy = new SPDYServerConnectionFactory(version, listener);
- connector.addConnectionFactory(spdy);
- connector.setPort(0);
- server.addConnector(connector);
-
- if (connector.getConnectionFactory(NPNServerConnectionFactory.class)!=null)
- connector.getConnectionFactory(NPNServerConnectionFactory.class).setDefaultProtocol(spdy.getProtocol());
- else
- connector.setDefaultProtocol(spdy.getProtocol());
-
- server.start();
- return new InetSocketAddress("localhost", connector.getLocalPort());
- }
-
- protected Server newServer()
- {
- QueuedThreadPool pool = new QueuedThreadPool();
- pool.setName(pool.getName()+"-server");
- return new Server(pool);
- }
-
- protected ServerConnector newSPDYServerConnector(Server server, ServerSessionFrameListener listener)
- {
- return new SPDYServerConnector(server, listener);
- }
-
- protected Session startClient(InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
- {
- return startClient(version, socketAddress, listener);
- }
-
- protected Session startClient(short version, InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
- {
- if (clientFactory == null)
- {
- QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setName(threadPool.getName() + "-client");
- clientFactory = newSPDYClientFactory(threadPool);
- }
- clientFactory.start();
-
- return clientFactory.newSPDYClient(version).connect(socketAddress, listener);
- }
-
- protected SPDYClient.Factory newSPDYClientFactory(Executor threadPool)
- {
- return new SPDYClient.Factory(threadPool);
- }
-
- protected SslContextFactory newSslContextFactory()
- {
- SslContextFactory sslContextFactory = new SslContextFactory();
- sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
- sslContextFactory.setKeyStorePassword("storepwd");
- sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
- sslContextFactory.setTrustStorePassword("storepwd");
- sslContextFactory.setProtocol("TLSv1");
- sslContextFactory.setIncludeProtocols("TLSv1");
- return sslContextFactory;
- }
-
- @After
- public void destroy() throws Exception
- {
- if (clientFactory != null)
- {
- clientFactory.stop();
- }
- if (server != null)
- {
- server.stop();
- server.join();
- }
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ClosedStreamTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ClosedStreamTest.java
deleted file mode 100644
index 07eb552d18..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ClosedStreamTest.java
+++ /dev/null
@@ -1,273 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertThat;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.BytesDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.GoAwayFrame;
-import org.eclipse.jetty.spdy.frames.RstStreamFrame;
-import org.eclipse.jetty.spdy.frames.SynReplyFrame;
-import org.eclipse.jetty.spdy.frames.SynStreamFrame;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.spdy.parser.Parser.Listener;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class ClosedStreamTest extends AbstractTest
-{
- //TODO: Right now it sends a rst as the stream is unknown to the session once it's closed.
- //TODO: But according to the spec we probably should just ignore the data?!
- @Test
- public void testDataSentOnClosedStreamIsIgnored() throws Exception
- {
- ServerSocketChannel server = ServerSocketChannel.open();
- server.bind(new InetSocketAddress("localhost", 0));
-
- Session session = startClient(new InetSocketAddress("localhost", server.socket().getLocalPort()), null);
- final CountDownLatch dataLatch = new CountDownLatch(2);
- session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataLatch.countDown();
- }
- });
-
- SocketChannel channel = server.accept();
- ByteBuffer readBuffer = ByteBuffer.allocate(1024);
- channel.read(readBuffer);
- readBuffer.flip();
- int streamId = readBuffer.getInt(8);
-
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory.StandardCompressor());
-
- ByteBuffer writeBuffer = generator.control(new SynReplyFrame(SPDY.V2, (byte)0, streamId, new Fields()));
- channel.write(writeBuffer);
- Assert.assertThat(writeBuffer.hasRemaining(), is(false));
-
- byte[] bytes = new byte[1];
- writeBuffer = generator.data(streamId, bytes.length, new BytesDataInfo(bytes, true));
- channel.write(writeBuffer);
- Assert.assertThat(writeBuffer.hasRemaining(), is(false));
-
- // Write again to simulate the faulty condition
- writeBuffer.flip();
- channel.write(writeBuffer);
- Assert.assertThat(writeBuffer.hasRemaining(), is(false));
-
- Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS));
-
- session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
-
- server.close();
- }
-
- @Test
- public void testSendDataOnHalfClosedStreamCausesExceptionOnServer() throws Exception
- {
- final CountDownLatch replyReceivedLatch = new CountDownLatch(1);
- final CountDownLatch clientReceivedDataLatch = new CountDownLatch(1);
- final CountDownLatch exceptionWhenSendingData = new CountDownLatch(1);
-
- Session clientSession = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- try
- {
- replyReceivedLatch.await(5,TimeUnit.SECONDS);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- try
- {
- stream.data(new StringDataInfo("data send after half closed",false), new Callback.Adapter());
- }
- catch (RuntimeException e)
- {
- // we expect an exception here, but we don't want it to be logged
- exceptionWhenSendingData.countDown();
- }
-
- return null;
- }
- }),null);
-
- Stream stream = clientSession.syn(new SynInfo(new Fields(), false),new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- replyReceivedLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- clientReceivedDataLatch.countDown();
- }
- });
- assertThat("reply has been received by client",replyReceivedLatch.await(5,TimeUnit.SECONDS),is(true));
- assertThat("stream is half closed from server",stream.isHalfClosed(),is(true));
- assertThat("client has not received any data sent after stream was half closed by server",
- clientReceivedDataLatch.await(1,TimeUnit.SECONDS), is(false));
- assertThat("sending data threw an exception",exceptionWhenSendingData.await(5,TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testV2ReceiveDataOnHalfClosedStream() throws Exception
- {
- runReceiveDataOnHalfClosedStream(SPDY.V2);
- }
-
- @Test
- @Ignore("until v3 is properly implemented")
- public void testV3ReceiveDataOnHalfClosedStream() throws Exception
- {
- runReceiveDataOnHalfClosedStream(SPDY.V3);
- }
-
- private void runReceiveDataOnHalfClosedStream(short version) throws Exception
- {
- final CountDownLatch clientResetReceivedLatch = new CountDownLatch(1);
- final CountDownLatch serverReplySentLatch = new CountDownLatch(1);
- final CountDownLatch clientReplyReceivedLatch = new CountDownLatch(1);
- final CountDownLatch serverDataReceivedLatch = new CountDownLatch(1);
- final CountDownLatch goAwayReceivedLatch = new CountDownLatch(1);
-
- InetSocketAddress startServer = startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- serverReplySentLatch.countDown();
- try
- {
- clientReplyReceivedLatch.await(5,TimeUnit.SECONDS);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- serverDataReceivedLatch.countDown();
- }
- };
- }
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- goAwayReceivedLatch.countDown();
- }
- });
-
- final Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory().newCompressor());
- int streamId = 1;
- ByteBuffer synData = generator.control(new SynStreamFrame(version,SynInfo.FLAG_CLOSE, streamId,0,(byte)0,(short)0,new Fields()));
-
- final SocketChannel socketChannel = SocketChannel.open(startServer);
- socketChannel.write(synData);
- assertThat("synData is fully written", synData.hasRemaining(), is(false));
-
- assertThat("server: push reply is sent",serverReplySentLatch.await(5,TimeUnit.SECONDS),is(true));
-
- Parser parser = new Parser(new StandardCompressionFactory.StandardDecompressor());
- parser.addListener(new Listener.Adapter()
- {
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- if (frame instanceof SynReplyFrame)
- {
- SynReplyFrame synReplyFrame = (SynReplyFrame)frame;
- clientReplyReceivedLatch.countDown();
- int streamId = synReplyFrame.getStreamId();
- ByteBuffer data = generator.data(streamId,0,new StringDataInfo("data",false));
- try
- {
- socketChannel.write(data);
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
- else if (frame instanceof RstStreamFrame)
- {
- clientResetReceivedLatch.countDown();
- }
- }
- });
- ByteBuffer response = ByteBuffer.allocate(28);
- socketChannel.read(response);
- response.flip();
- parser.parse(response);
-
- assertThat("server didn't receive data",serverDataReceivedLatch.await(1,TimeUnit.SECONDS),not(true));
- assertThat("client didn't receive reset",clientResetReceivedLatch.await(1,TimeUnit.SECONDS),not(true));
-
- ByteBuffer buffer = generator.control(new GoAwayFrame(version, streamId, SessionStatus.OK.getCode()));
- socketChannel.write(buffer);
- Assert.assertThat(buffer.hasRemaining(), is(false));
-
- assertThat("GoAway frame is received by server", goAwayReceivedLatch.await(5,TimeUnit.SECONDS), is(true));
-
- socketChannel.close();
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/FlowControlTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/FlowControlTest.java
deleted file mode 100644
index 2953f9c25e..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/FlowControlTest.java
+++ /dev/null
@@ -1,493 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Exchanger;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.BytesDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.SPDYException;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Settings;
-import org.eclipse.jetty.spdy.api.SettingsInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.FutureCallback;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class FlowControlTest extends AbstractTest
-{
- @Test
- public void testFlowControlWithConcurrentSettings() throws Exception
- {
- // Initial window is 64 KiB. We allow the client to send 1024 B
- // then we change the window to 512 B. At this point, the client
- // must stop sending data (although the initial window allows it)
-
- final int size = 512;
- final AtomicReference<DataInfo> dataInfoRef = new AtomicReference<>();
- final CountDownLatch dataLatch = new CountDownLatch(2);
- final CountDownLatch settingsLatch = new CountDownLatch(1);
- Session session = startClient(SPDY.V3, startServer(SPDY.V3, new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- return new StreamFrameListener.Adapter()
- {
- private final AtomicInteger dataFrames = new AtomicInteger();
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- int dataFrameCount = dataFrames.incrementAndGet();
- if (dataFrameCount == 1)
- {
- dataInfoRef.set(dataInfo);
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, size));
- stream.getSession().settings(new SettingsInfo(settings), new FutureCallback());
- }
- else if (dataFrameCount > 1)
- {
- dataInfo.consume(dataInfo.length());
- dataLatch.countDown();
- }
- }
- };
- }
- }), new SessionFrameListener.Adapter()
- {
- @Override
- public void onSettings(Session session, SettingsInfo settingsInfo)
- {
- settingsLatch.countDown();
- }
- });
-
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
- stream.data(new BytesDataInfo(new byte[size * 2], false));
- settingsLatch.await(5, TimeUnit.SECONDS);
-
- // Send the second chunk of data, must not arrive since we're flow control stalled now
- stream.data(new BytesDataInfo(new byte[size * 2], true), new Callback.Adapter());
- Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS));
-
- // Consume the data arrived to server, this will resume flow control
- DataInfo dataInfo = dataInfoRef.get();
- dataInfo.consume(dataInfo.length());
-
- Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testServerFlowControlOneBigWrite() throws Exception
- {
- final int windowSize = 1536;
- final int length = 5 * windowSize;
- final CountDownLatch settingsLatch = new CountDownLatch(1);
- Session session = startClient(SPDY.V3, startServer(SPDY.V3, new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onSettings(Session session, SettingsInfo settingsInfo)
- {
- settingsLatch.countDown();
- }
-
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- stream.data(new BytesDataInfo(new byte[length], true), new Callback.Adapter());
- return null;
- }
- }), null);
-
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, windowSize));
- session.settings(new SettingsInfo(settings));
-
- Assert.assertTrue(settingsLatch.await(5, TimeUnit.SECONDS));
-
- final Exchanger<DataInfo> exchanger = new Exchanger<>();
- session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
- {
- private AtomicInteger dataFrames = new AtomicInteger();
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- try
- {
- int dataFrames = this.dataFrames.incrementAndGet();
- if (dataFrames == 1)
- {
- // Do not consume nor read from the data frame.
- // We should then be flow-control stalled
- exchanger.exchange(dataInfo);
- }
- else if (dataFrames == 2)
- {
- // Read but not consume, we should be flow-control stalled
- dataInfo.asByteBuffer(false);
- exchanger.exchange(dataInfo);
- }
- else if (dataFrames == 3)
- {
- // Consume partially, we should be flow-control stalled
- dataInfo.consumeInto(ByteBuffer.allocate(dataInfo.length() / 2));
- exchanger.exchange(dataInfo);
- }
- else if (dataFrames == 4 || dataFrames == 5)
- {
- // Consume totally
- dataInfo.asByteBuffer(true);
- exchanger.exchange(dataInfo);
- }
- else
- {
- Assert.fail();
- }
- }
- catch (InterruptedException x)
- {
- throw new SPDYException(x);
- }
- }
- });
-
- DataInfo dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
- checkThatWeAreFlowControlStalled(exchanger);
-
- Assert.assertEquals(windowSize, dataInfo.available());
- Assert.assertEquals(0, dataInfo.consumed());
- dataInfo.asByteBuffer(true);
-
- dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
- checkThatWeAreFlowControlStalled(exchanger);
-
- Assert.assertEquals(0, dataInfo.available());
- Assert.assertEquals(0, dataInfo.consumed());
- dataInfo.consume(dataInfo.length());
-
- dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
- checkThatWeAreFlowControlStalled(exchanger);
-
- Assert.assertEquals(dataInfo.length() / 2, dataInfo.consumed());
- dataInfo.asByteBuffer(true);
-
- dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
- Assert.assertEquals(dataInfo.length(), dataInfo.consumed());
- // Check that we are not flow control stalled
- dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
- Assert.assertEquals(dataInfo.length(), dataInfo.consumed());
- }
-
- @Test
- public void testClientFlowControlOneBigWrite() throws Exception
- {
- final int windowSize = 1536;
- final Exchanger<DataInfo> exchanger = new Exchanger<>();
- final CountDownLatch settingsLatch = new CountDownLatch(1);
- Session session = startClient(SPDY.V3, startServer(SPDY.V3, new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onConnect(Session session)
- {
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, windowSize));
- session.settings(new SettingsInfo(settings), new FutureCallback());
- }
-
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- return new StreamFrameListener.Adapter()
- {
- private AtomicInteger dataFrames = new AtomicInteger();
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- try
- {
- int dataFrames = this.dataFrames.incrementAndGet();
- if (dataFrames == 1)
- {
- // Do not consume nor read from the data frame.
- // We should then be flow-control stalled
- exchanger.exchange(dataInfo);
- }
- else if (dataFrames == 2)
- {
- // Read but not consume, we should be flow-control stalled
- dataInfo.asByteBuffer(false);
- exchanger.exchange(dataInfo);
- }
- else if (dataFrames == 3)
- {
- // Consume partially, we should be flow-control stalled
- dataInfo.consumeInto(ByteBuffer.allocate(dataInfo.length() / 2));
- exchanger.exchange(dataInfo);
- }
- else if (dataFrames == 4 || dataFrames == 5)
- {
- // Consume totally
- dataInfo.asByteBuffer(true);
- exchanger.exchange(dataInfo);
- }
- else
- {
- Assert.fail();
- }
- }
- catch (InterruptedException x)
- {
- throw new SPDYException(x);
- }
- }
- };
- }
- }), new SessionFrameListener.Adapter()
- {
- @Override
- public void onSettings(Session session, SettingsInfo settingsInfo)
- {
- settingsLatch.countDown();
- }
- });
-
- Assert.assertTrue(settingsLatch.await(5, TimeUnit.SECONDS));
-
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
- final int length = 5 * windowSize;
- stream.data(new BytesDataInfo(new byte[length], true), new Callback.Adapter());
-
- DataInfo dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
- checkThatWeAreFlowControlStalled(exchanger);
-
- Assert.assertEquals(windowSize, dataInfo.available());
- Assert.assertEquals(0, dataInfo.consumed());
- dataInfo.asByteBuffer(true);
-
- dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
- checkThatWeAreFlowControlStalled(exchanger);
-
- Assert.assertEquals(0, dataInfo.available());
- Assert.assertEquals(0, dataInfo.consumed());
- dataInfo.consume(dataInfo.length());
-
- dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
- checkThatWeAreFlowControlStalled(exchanger);
-
- Assert.assertEquals(dataInfo.length() / 2, dataInfo.consumed());
- dataInfo.asByteBuffer(true);
-
- dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
- Assert.assertEquals(dataInfo.length(), dataInfo.consumed());
- // Check that we are not flow control stalled
- dataInfo = exchanger.exchange(null, 5, TimeUnit.SECONDS);
- Assert.assertEquals(dataInfo.length(), dataInfo.consumed());
- }
-
- @Test
- public void testStreamsStalledDoesNotStallOtherStreams() throws Exception
- {
- final int windowSize = 1024;
- final CountDownLatch settingsLatch = new CountDownLatch(1);
- Session session = startClient(SPDY.V3, startServer(SPDY.V3, new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onSettings(Session session, SettingsInfo settingsInfo)
- {
- settingsLatch.countDown();
- }
-
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- stream.data(new BytesDataInfo(new byte[windowSize * 2], true), new Callback.Adapter());
- return null;
- }
- }), null);
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, windowSize));
- session.settings(new SettingsInfo(settings));
-
- Assert.assertTrue(settingsLatch.await(5, TimeUnit.SECONDS));
-
- final CountDownLatch latch = new CountDownLatch(3);
- final AtomicReference<DataInfo> dataInfoRef1 = new AtomicReference<>();
- final AtomicReference<DataInfo> dataInfoRef2 = new AtomicReference<>();
- session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger dataFrames = new AtomicInteger();
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- int frames = dataFrames.incrementAndGet();
- if (frames == 1)
- {
- // Do not consume it to stall flow control
- dataInfoRef1.set(dataInfo);
- }
- else
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- latch.countDown();
- }
- }
- });
- session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), new StreamFrameListener.Adapter()
- {
- private final AtomicInteger dataFrames = new AtomicInteger();
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- int frames = dataFrames.incrementAndGet();
- if (frames == 1)
- {
- // Do not consume it to stall flow control
- dataInfoRef2.set(dataInfo);
- }
- else
- {
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- latch.countDown();
- }
- }
- });
- session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- DataInfo dataInfo1 = dataInfoRef1.getAndSet(null);
- if (dataInfo1 != null)
- dataInfo1.consume(dataInfo1.length());
- DataInfo dataInfo2 = dataInfoRef2.getAndSet(null);
- if (dataInfo2 != null)
- dataInfo2.consume(dataInfo2.length());
- dataInfo.consume(dataInfo.length());
- if (dataInfo.isClose())
- latch.countDown();
- }
- });
-
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testSendBigFileWithoutFlowControl() throws Exception
- {
- testSendBigFile(SPDY.V2);
- }
-
- @Test
- public void testSendBigFileWithFlowControl() throws Exception
- {
- testSendBigFile(SPDY.V3);
- }
-
- private void testSendBigFile(short version) throws Exception
- {
- final int dataSize = 1024 * 1024;
- final ByteBufferDataInfo bigByteBufferDataInfo = new ByteBufferDataInfo(ByteBuffer.allocate(dataSize),false);
- final CountDownLatch allDataReceivedLatch = new CountDownLatch(1);
-
- Session session = startClient(version, startServer(version, new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- stream.data(bigByteBufferDataInfo, new Callback.Adapter());
- return null;
- }
- }),new SessionFrameListener.Adapter());
-
- session.syn(new SynInfo(new Fields(), false),new StreamFrameListener.Adapter()
- {
- private int dataBytesReceived;
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataBytesReceived = dataBytesReceived + dataInfo.length();
- dataInfo.consume(dataInfo.length());
- if (dataBytesReceived == dataSize)
- allDataReceivedLatch.countDown();
- }
- });
-
- assertThat("all data bytes have been received by the client", allDataReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- private void checkThatWeAreFlowControlStalled(final Exchanger<DataInfo> exchanger)
- {
- expectException(TimeoutException.class, new Callable<DataInfo>()
- {
- @Override
- public DataInfo call() throws Exception
- {
- return exchanger.exchange(null, 1, TimeUnit.SECONDS);
- }
- });
- }
-
- private void expectException(Class<? extends Exception> exception, Callable<DataInfo> command)
- {
- try
- {
- command.call();
- Assert.fail();
- }
- catch (Exception x)
- {
- Assert.assertSame(exception, x.getClass());
- }
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/GoAwayTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/GoAwayTest.java
deleted file mode 100644
index a8342027a4..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/GoAwayTest.java
+++ /dev/null
@@ -1,234 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.FutureCallback;
-import org.eclipse.jetty.util.FuturePromise;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class GoAwayTest extends AbstractTest
-{
- @Test
- public void testServerReceivesGoAwayOnClientGoAway() throws Exception
- {
- final CountDownLatch latch = new CountDownLatch(1);
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- return null;
- }
-
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- Assert.assertEquals(0, goAwayInfo.getLastStreamId());
- Assert.assertSame(SessionStatus.OK, goAwayInfo.getSessionStatus());
- latch.countDown();
- }
- };
- Session session = startClient(startServer(serverSessionFrameListener), null);
-
- session.syn(new SynInfo(new Fields(), true), null);
-
- session.goAway(new GoAwayInfo());
-
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testClientReceivesGoAwayOnServerGoAway() throws Exception
- {
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- stream.getSession().goAway(new GoAwayInfo(), new FutureCallback());
- return null;
- }
- };
- final AtomicReference<GoAwayResultInfo> ref = new AtomicReference<>();
- final CountDownLatch latch = new CountDownLatch(1);
- SessionFrameListener clientSessionFrameListener = new SessionFrameListener.Adapter()
- {
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- ref.set(goAwayInfo);
- latch.countDown();
- }
- };
- Session session = startClient(startServer(serverSessionFrameListener), clientSessionFrameListener);
-
- Stream stream1 = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), null);
-
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- GoAwayResultInfo goAwayResultInfo = ref.get();
- Assert.assertNotNull(goAwayResultInfo);
- Assert.assertEquals(stream1.getId(), goAwayResultInfo.getLastStreamId());
- Assert.assertSame(SessionStatus.OK, goAwayResultInfo.getSessionStatus());
- }
-
- @Test
- public void testSynStreamIgnoredAfterGoAway() throws Exception
- {
- final CountDownLatch latch = new CountDownLatch(1);
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- private final AtomicInteger syns = new AtomicInteger();
-
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- int synCount = syns.incrementAndGet();
- if (synCount == 1)
- {
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- stream.getSession().goAway(new GoAwayInfo(), new FutureCallback());
- }
- else
- {
- latch.countDown();
- }
- return null;
- }
- };
- SessionFrameListener clientSessionFrameListener = new SessionFrameListener.Adapter()
- {
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- session.syn(new SynInfo(new Fields(), true), null, new FuturePromise<Stream>());
- }
- };
- Session session = startClient(startServer(serverSessionFrameListener), clientSessionFrameListener);
-
- session.syn(new SynInfo(new Fields(), true), null);
-
- Assert.assertFalse(latch.await(1, TimeUnit.SECONDS));
- }
-
- @Test
- public void testDataNotProcessedAfterGoAway() throws Exception
- {
- final CountDownLatch closeLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- private AtomicInteger syns = new AtomicInteger();
-
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- int synCount = syns.incrementAndGet();
- if (synCount == 1)
- {
- return null;
- }
- else
- {
- stream.getSession().goAway(new GoAwayInfo(), new FutureCallback());
- closeLatch.countDown();
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataLatch.countDown();
- }
- };
- }
- }
- };
- final AtomicReference<GoAwayResultInfo> goAwayRef = new AtomicReference<>();
- final CountDownLatch goAwayLatch = new CountDownLatch(1);
- SessionFrameListener clientSessionFrameListener = new SessionFrameListener.Adapter()
- {
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- goAwayRef.set(goAwayInfo);
- goAwayLatch.countDown();
- }
- };
- Session session = startClient(startServer(serverSessionFrameListener), clientSessionFrameListener);
-
- // First stream is processed ok
- final CountDownLatch reply1Latch = new CountDownLatch(1);
- session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- reply1Latch.countDown();
- }
- });
- Assert.assertTrue(reply1Latch.await(5, TimeUnit.SECONDS));
-
- // Second stream is closed in the middle
- Stream stream2 = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
- Assert.assertTrue(closeLatch.await(5, TimeUnit.SECONDS));
-
- // There is a race between the data we want to send, and the client
- // closing the connection because the server closed it after the
- // go_away, so we guard with a try/catch to have the test pass cleanly
- try
- {
- stream2.data(new StringDataInfo("foo", true));
- Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS));
- }
- catch (ExecutionException x)
- {
- // doesn't matter which exception we get, it's important that the data is not been written and the
- // previous assertion is true
- }
-
- // The last good stream is the second, because it was received by the server
- Assert.assertTrue(goAwayLatch.await(5, TimeUnit.SECONDS));
- GoAwayResultInfo goAway = goAwayRef.get();
- Assert.assertNotNull(goAway);
- Assert.assertEquals(stream2.getId(), goAway.getLastStreamId());
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/HeadersTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/HeadersTest.java
deleted file mode 100644
index 34f3c82791..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/HeadersTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class HeadersTest extends AbstractTest
-{
- @Test
- public void testHeaders() throws Exception
- {
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- Assert.assertTrue(stream.isHalfClosed());
- stream.headers(new HeadersInfo(new Fields(), true), new Callback.Adapter());
- Assert.assertTrue(stream.isClosed());
- }
- };
- }
- };
-
- Session session = startClient(startServer(serverSessionFrameListener), null);
-
- final CountDownLatch latch = new CountDownLatch(1);
- session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Fields headers = new Fields();
- headers.put("foo", "bar");
- headers.put("baz", "woo");
- stream.headers(new HeadersInfo(headers, true), new Callback.Adapter());
- Assert.assertTrue(stream.isHalfClosed());
- }
-
- @Override
- public void onHeaders(Stream stream, HeadersInfo headersInfo)
- {
- Assert.assertTrue(stream.isClosed());
- latch.countDown();
- }
- });
-
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/IdleTimeoutTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/IdleTimeoutTest.java
deleted file mode 100644
index 195bb6a950..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/IdleTimeoutTest.java
+++ /dev/null
@@ -1,257 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import java.net.InetSocketAddress;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class IdleTimeoutTest extends AbstractTest
-{
- private final int idleTimeout = 1000;
-
- @Test
- public void testServerEnforcingIdleTimeout() throws Exception
- {
- server = newServer();
- connector = newSPDYServerConnector(server, new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- return null;
- }
- });
- connector.setIdleTimeout(idleTimeout);
-
- final CountDownLatch latch = new CountDownLatch(1);
- Session session = startClient(startServer(null), new SessionFrameListener.Adapter()
- {
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- latch.countDown();
- }
- });
-
- session.syn(new SynInfo(new Fields(), true), null);
-
- Assert.assertTrue(latch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testServerEnforcingIdleTimeoutWithUnrespondedStream() throws Exception
- {
- server = newServer();
- connector = newSPDYServerConnector(server, null);
- connector.setIdleTimeout(idleTimeout);
-
- final CountDownLatch latch = new CountDownLatch(1);
- Session session = startClient(startServer(null), new SessionFrameListener.Adapter()
- {
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- latch.countDown();
- }
- });
-
- // The SYN is not replied, and the server should idle timeout
- session.syn(new SynInfo(new Fields(), true), null);
-
- Assert.assertTrue(latch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testServerNotEnforcingIdleTimeoutWithPendingStream() throws Exception
- {
- server = newServer();
- connector = newSPDYServerConnector(server, new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- try
- {
- Thread.sleep(2 * idleTimeout);
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- return null;
- }
- catch (InterruptedException x)
- {
- Assert.fail();
- return null;
- }
- }
- });
- connector.setIdleTimeout(idleTimeout);
-
- final CountDownLatch goAwayLatch = new CountDownLatch(1);
- Session session = startClient(startServer(null), new SessionFrameListener.Adapter()
- {
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- goAwayLatch.countDown();
- }
- });
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- replyLatch.countDown();
- }
- });
-
- Assert.assertTrue(replyLatch.await(3 * idleTimeout, TimeUnit.MILLISECONDS));
-
- // Just make sure onGoAway has never been called, but don't wait too much
- Assert.assertFalse(goAwayLatch.await(idleTimeout / 2, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testClientEnforcingIdleTimeout() throws Exception
- {
- final CountDownLatch latch = new CountDownLatch(1);
- InetSocketAddress address = startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- return null;
- }
-
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- latch.countDown();
- }
- });
-
- QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setName(threadPool.getName() + "-client");
- clientFactory = newSPDYClientFactory(threadPool);
- clientFactory.start();
- SPDYClient client = clientFactory.newSPDYClient(SPDY.V2);
- client.setIdleTimeout(idleTimeout);
- Session session = client.connect(address, null);
-
- session.syn(new SynInfo(new Fields(), true), null);
-
- Assert.assertTrue(latch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testClientEnforcingIdleTimeoutWithUnrespondedStream() throws Exception
- {
- final CountDownLatch latch = new CountDownLatch(1);
- InetSocketAddress address = startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- latch.countDown();
- }
- });
-
- QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setName(threadPool.getName() + "-client");
- clientFactory = newSPDYClientFactory(threadPool);
- clientFactory.start();
- SPDYClient client = clientFactory.newSPDYClient(SPDY.V2);
- client.setIdleTimeout(idleTimeout);
- Session session = client.connect(address, null);
-
- session.syn(new SynInfo(new Fields(), true), null);
-
- Assert.assertTrue(latch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
- }
-
- @Test
- public void testClientNotEnforcingIdleTimeoutWithPendingStream() throws Exception
- {
- final CountDownLatch latch = new CountDownLatch(1);
- InetSocketAddress address = startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- return null;
- }
-
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- latch.countDown();
- }
- });
-
- QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setName(threadPool.getName() + "-client");
- clientFactory = newSPDYClientFactory(threadPool);
- clientFactory.start();
- SPDYClient client = clientFactory.newSPDYClient(SPDY.V2);
- client.setIdleTimeout(idleTimeout);
- Session session = client.connect(address, null);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- try
- {
- Thread.sleep(2 * idleTimeout);
- replyLatch.countDown();
- }
- catch (InterruptedException e)
- {
- Assert.fail();
- }
- }
- });
-
- Assert.assertFalse(latch.await(2 * idleTimeout, TimeUnit.MILLISECONDS));
- Assert.assertTrue(replyLatch.await(3 * idleTimeout, TimeUnit.MILLISECONDS));
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/MaxConcurrentStreamTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/MaxConcurrentStreamTest.java
deleted file mode 100644
index 9cc8115f5e..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/MaxConcurrentStreamTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Settings;
-import org.eclipse.jetty.spdy.api.SettingsInfo;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MaxConcurrentStreamTest extends AbstractTest
-{
- @Test
- public void testMaxConcurrentStreamsSetByServer() throws Exception, ExecutionException
- {
- final CountDownLatch settingsReceivedLatch = new CountDownLatch(1);
- final CountDownLatch dataReceivedLatch = new CountDownLatch(1);
-
- Session session = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onConnect(Session session)
- {
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.MAX_CONCURRENT_STREAMS, 1));
- try
- {
- session.settings(new SettingsInfo(settings));
- }
- catch (ExecutionException | InterruptedException | TimeoutException e)
- {
- e.printStackTrace();
- }
- }
-
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- try
- {
- stream.reply(new ReplyInfo(true));
- }
- catch (ExecutionException | InterruptedException | TimeoutException e)
- {
- e.printStackTrace();
- }
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataReceivedLatch.countDown();
- }
- };
- }
- }), new SessionFrameListener.Adapter()
- {
- @Override
- public void onSettings(Session session, SettingsInfo settingsInfo)
- {
- settingsReceivedLatch.countDown();
- }
- });
-
- assertThat("Settings frame received", settingsReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
-
- SynInfo synInfo = new SynInfo(new Fields(), false);
- Stream stream = session.syn(synInfo, null);
-
- boolean failed = false;
- try
- {
- session.syn(synInfo, null);
- }
- catch (ExecutionException | InterruptedException | TimeoutException e)
- {
- failed = true;
- }
-
- assertThat("Opening second stream failed", failed, is(true));
-
- stream.data(new ByteBufferDataInfo(BufferUtil.EMPTY_BUFFER, true));
- assertThat("Data has been received on first stream.", dataReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/PingTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/PingTest.java
deleted file mode 100644
index 1684229dda..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/PingTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.jetty.spdy.api.PingInfo;
-import org.eclipse.jetty.spdy.api.PingResultInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.util.Promise;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class PingTest extends AbstractTest
-{
- @Test
- public void testPingPong() throws Exception
- {
- final AtomicReference<PingResultInfo> ref = new AtomicReference<>();
- final CountDownLatch latch = new CountDownLatch(1);
- SessionFrameListener clientSessionFrameListener = new SessionFrameListener.Adapter()
- {
- @Override
- public void onPing(Session session, PingResultInfo pingInfo)
- {
- ref.set(pingInfo);
- latch.countDown();
- }
- };
- Session session = startClient(startServer(null), clientSessionFrameListener);
- PingResultInfo pingResultInfo = session.ping(new PingInfo(5, TimeUnit.SECONDS));
- Assert.assertEquals(1, pingResultInfo.getPingId() % 2);
-
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- PingResultInfo pongInfo = ref.get();
- Assert.assertNotNull(pongInfo);
- Assert.assertEquals(pingResultInfo.getPingId(), pongInfo.getPingId());
- }
-
- @Test
- public void testServerPingPong() throws Exception
- {
- final CountDownLatch pingReceived = new CountDownLatch(1);
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- private final CountDownLatch pingSent = new CountDownLatch(1);
- private int pingId;
-
- @Override
- public void onConnect(Session session)
- {
- session.ping(new PingInfo(), new Promise.Adapter<PingResultInfo>()
- {
- @Override
- public void succeeded(PingResultInfo pingInfo)
- {
- pingId = pingInfo.getPingId();
- pingSent.countDown();
- }
- });
- }
-
- @Override
- public void onPing(Session session, PingResultInfo pingInfo)
- {
- try
- {
- // This callback may be notified before the promise above,
- // so make sure we wait here to know the pingId
- Assert.assertTrue(pingSent.await(5, TimeUnit.SECONDS));
- Assert.assertEquals(0, pingInfo.getPingId() % 2);
- Assert.assertEquals(pingId, pingInfo.getPingId());
- pingReceived.countDown();
- }
- catch (InterruptedException x)
- {
- Assert.fail();
- }
- }
- };
- startClient(startServer(serverSessionFrameListener), null);
-
- Assert.assertTrue(pingReceived.await(5, TimeUnit.SECONDS));
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ProtocolViolationsTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ProtocolViolationsTest.java
deleted file mode 100644
index cedf9e14a7..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ProtocolViolationsTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.BytesDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.HeadersInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.frames.ControlFrameType;
-import org.eclipse.jetty.spdy.frames.SynReplyFrame;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ProtocolViolationsTest extends AbstractTest
-{
- @Test
- public void testSendDataBeforeReplyIsIllegal() throws Exception
- {
- final CountDownLatch resetLatch = new CountDownLatch(1);
- final CountDownLatch latch = new CountDownLatch(1);
- Session session = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- try
- {
- stream.data(new StringDataInfo("failure", true), new Callback.Adapter());
- return null;
- }
- catch (IllegalStateException x)
- {
- latch.countDown();
- return null;
- }
- }
- }), new SessionFrameListener.Adapter()
- {
- @Override
- public void onRst(Session session, RstInfo rstInfo)
- {
- Assert.assertSame(StreamStatus.PROTOCOL_ERROR, rstInfo.getStreamStatus());
- resetLatch.countDown();
- }
- });
- session.syn(new SynInfo(new Fields(), true), null);
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testReceiveDataBeforeReplyIsIllegal() throws Exception
- {
- ServerSocketChannel server = ServerSocketChannel.open();
- server.bind(new InetSocketAddress("localhost", 0));
-
- Session session = startClient(new InetSocketAddress("localhost", server.socket().getLocalPort()), null);
- session.syn(new SynInfo(new Fields(), true), null);
-
- SocketChannel channel = server.accept();
- ByteBuffer readBuffer = ByteBuffer.allocate(1024);
- channel.read(readBuffer);
- readBuffer.flip();
- int streamId = readBuffer.getInt(8);
-
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory.StandardCompressor());
- byte[] bytes = new byte[1];
- ByteBuffer writeBuffer = generator.data(streamId, bytes.length, new BytesDataInfo(bytes, true));
- channel.write(writeBuffer);
- assertThat("data is fully written", writeBuffer.hasRemaining(),is(false));
-
- readBuffer.clear();
- channel.read(readBuffer);
- readBuffer.flip();
- Assert.assertEquals(ControlFrameType.RST_STREAM.getCode(), readBuffer.getShort(2));
- Assert.assertEquals(streamId, readBuffer.getInt(8));
-
- session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
-
- server.close();
- }
-
- @Test(expected = IllegalStateException.class)
- public void testSendDataAfterCloseIsIllegal() throws Exception
- {
- Session session = startClient(startServer(null), null);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), null);
- stream.data(new StringDataInfo("test", true));
- }
-
- @Test(expected = IllegalStateException.class)
- public void testSendHeadersAfterCloseIsIllegal() throws Exception
- {
- Session session = startClient(startServer(null), null);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0), null);
- stream.headers(new HeadersInfo(new Fields(), true));
- }
-
- @Test //TODO: throws an ISException in StandardStream.updateCloseState(). But instead we should send a rst or something to the server probably?!
- public void testServerClosesStreamTwice() throws Exception
- {
- ServerSocketChannel server = ServerSocketChannel.open();
- server.bind(new InetSocketAddress("localhost", 0));
-
- Session session = startClient(new InetSocketAddress("localhost", server.socket().getLocalPort()), null);
- final CountDownLatch dataLatch = new CountDownLatch(2);
- session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataLatch.countDown();
- }
- });
-
- SocketChannel channel = server.accept();
- ByteBuffer readBuffer = ByteBuffer.allocate(1024);
- channel.read(readBuffer);
- readBuffer.flip();
- int streamId = readBuffer.getInt(8);
-
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory.StandardCompressor());
-
- ByteBuffer writeBuffer = generator.control(new SynReplyFrame(SPDY.V2, (byte)0, streamId, new Fields()));
- channel.write(writeBuffer);
- assertThat("SynReply is fully written", writeBuffer.hasRemaining(), is(false));
-
- byte[] bytes = new byte[1];
- writeBuffer = generator.data(streamId, bytes.length, new BytesDataInfo(bytes, true));
- channel.write(writeBuffer);
- assertThat("data is fully written", writeBuffer.hasRemaining(), is(false));
-
- // Write again to simulate the faulty condition
- writeBuffer.flip();
- channel.write(writeBuffer);
- assertThat("data is fully written", writeBuffer.hasRemaining(), is(false));
-
- Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS));
-
- session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
-
- server.close();
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/PushStreamTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/PushStreamTest.java
deleted file mode 100644
index ab4e5edb2d..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/PushStreamTest.java
+++ /dev/null
@@ -1,591 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.Matchers.sameInstance;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.Exchanger;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.BytesDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.PushInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.SessionStatus;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.DataFrame;
-import org.eclipse.jetty.spdy.frames.GoAwayFrame;
-import org.eclipse.jetty.spdy.frames.RstStreamFrame;
-import org.eclipse.jetty.spdy.frames.SynStreamFrame;
-import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.spdy.parser.Parser.Listener;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class PushStreamTest extends AbstractTest
-{
- private static final Logger LOG = Log.getLogger(PushStreamTest.class);
-
- @Test
- public void testSynPushStream() throws Exception
- {
- final AtomicReference<Stream> pushStreamRef = new AtomicReference<>();
- final CountDownLatch pushStreamLatch = new CountDownLatch(1);
-
- Session clientSession = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- stream.push(new PushInfo(new Fields(), true), new Promise.Adapter<Stream>());
- return null;
- }
- }), null);
-
- Stream stream = clientSession.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- assertThat("streamId is even", stream.getId() % 2, is(0));
- assertThat("stream is unidirectional", stream.isUnidirectional(), is(true));
- assertThat("stream is closed", stream.isClosed(), is(true));
- assertThat("stream has associated stream", stream.getAssociatedStream(), notNullValue());
- try
- {
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- fail("Cannot reply to push streams");
- }
- catch (IllegalStateException x)
- {
- // Expected
- }
- pushStreamRef.set(stream);
- pushStreamLatch.countDown();
- return null;
- }
- });
- assertThat("onSyn has been called", pushStreamLatch.await(5, TimeUnit.SECONDS), is(true));
- Stream pushStream = pushStreamRef.get();
- assertThat("main stream and associated stream are the same", stream, sameInstance(pushStream.getAssociatedStream()));
- }
-
- @Test
- public void testSendDataOnPushStreamAfterAssociatedStreamIsClosed() throws Exception
- {
- final Exchanger<Stream> streamExchanger = new Exchanger<>();
- final CountDownLatch pushStreamSynLatch = new CountDownLatch(1);
- final CyclicBarrier replyBarrier = new CyclicBarrier(3);
- final CyclicBarrier closeBarrier = new CyclicBarrier(3);
- final CountDownLatch streamDataSent = new CountDownLatch(2);
- final CountDownLatch pushStreamDataReceived = new CountDownLatch(2);
- final CountDownLatch exceptionCountDownLatch = new CountDownLatch(1);
-
- Session clientSession = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- try
- {
- replyBarrier.await(5, TimeUnit.SECONDS);
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- try
- {
- if (dataInfo.isClose())
- {
- stream.data(new StringDataInfo("close stream", true));
- closeBarrier.await(5, TimeUnit.SECONDS);
- }
- streamDataSent.countDown();
- if (pushStreamDataReceived.getCount() == 2)
- {
- Stream pushStream = stream.push(new PushInfo(new Fields(), false));
- streamExchanger.exchange(pushStream, 5, TimeUnit.SECONDS);
- }
- }
- catch (Exception e)
- {
- exceptionCountDownLatch.countDown();
- }
- }
- };
- }
- catch (Exception e)
- {
- exceptionCountDownLatch.countDown();
- throw new IllegalStateException(e);
- }
- }
-
- }), null);
-
- Stream stream = clientSession.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- pushStreamSynLatch.countDown();
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- pushStreamDataReceived.countDown();
- super.onData(stream, dataInfo);
- }
- };
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- try
- {
- replyBarrier.await(5, TimeUnit.SECONDS);
- }
- catch (Exception e)
- {
- exceptionCountDownLatch.countDown();
- }
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- try
- {
- closeBarrier.await(5, TimeUnit.SECONDS);
- }
- catch (Exception e)
- {
- exceptionCountDownLatch.countDown();
- }
- }
- });
-
- replyBarrier.await(5, TimeUnit.SECONDS);
- stream.data(new StringDataInfo("client data", false));
- Stream pushStream = streamExchanger.exchange(null, 5, TimeUnit.SECONDS);
- pushStream.data(new StringDataInfo("first push data frame", false));
- // nasty, but less complex than using another cyclicBarrier for example
- while (pushStreamDataReceived.getCount() != 1)
- Thread.sleep(1);
- stream.data(new StringDataInfo("client close", true));
- closeBarrier.await(5, TimeUnit.SECONDS);
- assertThat("stream is closed", stream.isClosed(), is(true));
- pushStream.data(new StringDataInfo("second push data frame while associated stream has been closed already", false));
- assertThat("2 pushStream data frames have been received.", pushStreamDataReceived.await(5, TimeUnit.SECONDS), is(true));
- assertThat("2 data frames have been sent", streamDataSent.await(5, TimeUnit.SECONDS), is(true));
- assertThatNoExceptionOccurred(exceptionCountDownLatch);
- }
-
- @Test
- public void testSynPushStreamOnClosedStream() throws Exception
- {
- final CountDownLatch pushStreamFailedLatch = new CountDownLatch(1);
-
- Session clientSession = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- stream.push(new PushInfo(1, TimeUnit.SECONDS, new Fields(), false),
- new Promise.Adapter<Stream>()
- {
- @Override
- public void failed(Throwable x)
- {
- pushStreamFailedLatch.countDown();
- }
- });
- return super.onSyn(stream, synInfo);
- }
- }), new SessionFrameListener.Adapter());
-
- clientSession.syn(new SynInfo(new Fields(), true), null);
- assertThat("pushStream push has failed", pushStreamFailedLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- @Test
- public void testSendBigDataOnPushStreamWhenAssociatedStreamIsClosed() throws Exception
- {
- final CountDownLatch streamClosedLatch = new CountDownLatch(1);
- final CountDownLatch allDataReceived = new CountDownLatch(1);
- final CountDownLatch exceptionCountDownLatch = new CountDownLatch(1);
- final Exchanger<ByteBuffer> exchanger = new Exchanger<>();
- final int dataSizeInBytes = 1024 * 1024 * 1;
- final byte[] transferBytes = createHugeByteArray(dataSizeInBytes);
-
- Session clientSession = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- try
- {
- Stream pushStream = stream.push(new PushInfo(new Fields(), false));
- stream.reply(new ReplyInfo(true));
- // wait until stream is closed
- streamClosedLatch.await(5, TimeUnit.SECONDS);
- pushStream.data(new BytesDataInfo(transferBytes, true), new Callback.Adapter());
- return null;
- }
- catch (Exception e)
- {
- exceptionCountDownLatch.countDown();
- throw new IllegalStateException(e);
- }
- }
- }), null);
-
- Stream stream = clientSession.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- return new StreamFrameListener.Adapter()
- {
- ByteBuffer receivedBytes = ByteBuffer.allocate(dataSizeInBytes);
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataInfo.consumeInto(receivedBytes);
- if (dataInfo.isClose())
- {
- allDataReceived.countDown();
- try
- {
- receivedBytes.flip();
- exchanger.exchange(receivedBytes.slice(), 5, TimeUnit.SECONDS);
- }
- catch (Exception e)
- {
- exceptionCountDownLatch.countDown();
- }
- }
- }
- };
- }
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- streamClosedLatch.countDown();
- super.onReply(stream, replyInfo);
- }
- });
-
- ByteBuffer receivedBytes = exchanger.exchange(null, 5, TimeUnit.SECONDS);
-
- assertThat("received byte array is the same as transferred byte array", Arrays.equals(transferBytes, receivedBytes.array()), is(true));
- assertThat("onReply has been called to close the stream", streamClosedLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("stream is closed", stream.isClosed(), is(true));
- assertThat("all data has been received", allDataReceived.await(20, TimeUnit.SECONDS), is(true));
- assertThatNoExceptionOccurred(exceptionCountDownLatch);
- }
-
- private byte[] createHugeByteArray(int sizeInBytes)
- {
- byte[] bytes = new byte[sizeInBytes];
- ThreadLocalRandom.current().nextBytes(bytes);
- return bytes;
- }
-
-
- @Test
- public void testClientResetsStreamAfterPushSynDoesPreventSendingDataFramesWithFlowControl() throws Exception
- {
- final boolean flowControl = true;
- testNoMoreFramesAreSentOnPushStreamAfterClientResetsThePushStream(flowControl);
- }
-
- @Test
- public void testClientResetsStreamAfterPushSynDoesPreventSendingDataFramesWithoutFlowControl() throws Exception
- {
- final boolean flowControl = false;
- testNoMoreFramesAreSentOnPushStreamAfterClientResetsThePushStream(flowControl);
- }
-
- private volatile boolean read = true;
-
- private void testNoMoreFramesAreSentOnPushStreamAfterClientResetsThePushStream(final boolean flowControl) throws Exception
- {
- final short version = SPDY.V3;
- final AtomicBoolean unexpectedExceptionOccurred = new AtomicBoolean(false);
- final CountDownLatch resetReceivedLatch = new CountDownLatch(1);
- final CountDownLatch allDataFramesReceivedLatch = new CountDownLatch(1);
- final CountDownLatch goAwayReceivedLatch = new CountDownLatch(1);
- final int dataSizeInBytes = 1024 * 256;
- final byte[] transferBytes = createHugeByteArray(dataSizeInBytes);
-
- InetSocketAddress serverAddress = startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(final Stream stream, SynInfo synInfo)
- {
- new Thread(new Runnable()
- {
-
- @Override
- public void run()
- {
- Stream pushStream = null;
- try
- {
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- pushStream = stream.push(new PushInfo(new Fields(), false));
- resetReceivedLatch.await(5, TimeUnit.SECONDS);
- }
- catch (InterruptedException | ExecutionException | TimeoutException e)
- {
- e.printStackTrace();
- unexpectedExceptionOccurred.set(true);
- }
- assert pushStream != null;
- try
- {
- pushStream.data(new BytesDataInfo(transferBytes, true));
- stream.data(new StringDataInfo("close", true));
- }
- catch (InterruptedException | ExecutionException | TimeoutException e)
- {
- LOG.debug(e.getMessage());
- }
- }
- }).start();
- return null;
- }
-
- @Override
- public void onRst(Session session, RstInfo rstInfo)
- {
- resetReceivedLatch.countDown();
- }
-
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
- {
- goAwayReceivedLatch.countDown();
- }
- }/*TODO, flowControl*/);
-
- final SocketChannel channel = SocketChannel.open(serverAddress);
- final Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory.StandardCompressor());
- int streamId = 1;
- ByteBuffer writeBuffer = generator.control(new SynStreamFrame(version, (byte)0, streamId, 0, (byte)0, (short)0, new Fields()));
- channel.write(writeBuffer);
- assertThat("writeBuffer is fully written", writeBuffer.hasRemaining(), is(false));
-
- final Parser parser = new Parser(new StandardCompressionFactory.StandardDecompressor());
- parser.addListener(new Listener.Adapter()
- {
- int bytesRead = 0;
-
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- if (frame instanceof SynStreamFrame)
- {
- int pushStreamId = ((SynStreamFrame)frame).getStreamId();
- ByteBuffer writeBuffer = generator.control(new RstStreamFrame(version, pushStreamId, StreamStatus.CANCEL_STREAM.getCode(version)));
- try
- {
- channel.write(writeBuffer);
- }
- catch (IOException e)
- {
- e.printStackTrace();
- unexpectedExceptionOccurred.set(true);
- }
- }
- }
-
- @Override
- public void onDataFrame(DataFrame frame, ByteBuffer data)
- {
- if (frame.getStreamId() == 2)
- bytesRead = bytesRead + frame.getLength();
- if (bytesRead == dataSizeInBytes)
- {
- allDataFramesReceivedLatch.countDown();
- return;
- }
- if (flowControl)
- {
- ByteBuffer writeBuffer = generator.control(new WindowUpdateFrame(version, frame.getStreamId(), frame.getLength()));
- try
- {
- channel.write(writeBuffer);
- }
- catch (IOException e)
- {
- e.printStackTrace();
- unexpectedExceptionOccurred.set(true);
- }
- }
- }
- });
-
- Thread reader = new Thread(new Runnable()
- {
- @Override
- public void run()
- {
- ByteBuffer readBuffer = ByteBuffer.allocate(dataSizeInBytes * 2);
- while (read)
- {
- try
- {
- channel.read(readBuffer);
- }
- catch (IOException e)
- {
- e.printStackTrace();
- unexpectedExceptionOccurred.set(true);
- }
- readBuffer.flip();
- parser.parse(readBuffer);
- readBuffer.clear();
- }
-
- }
- });
- reader.start();
- read = false;
-
- assertThat("no unexpected exceptions occurred", unexpectedExceptionOccurred.get(), is(false));
- assertThat("not all dataframes have been received as the pushstream has been reset by the client.", allDataFramesReceivedLatch.await(streamId, TimeUnit.SECONDS), is(false));
-
-
- ByteBuffer buffer = generator.control(new GoAwayFrame(version, streamId, SessionStatus.OK.getCode()));
- channel.write(buffer);
- Assert.assertThat(buffer.hasRemaining(), is(false));
-
- assertThat("GoAway frame is received by server", goAwayReceivedLatch.await(5, TimeUnit.SECONDS), is(true));
- channel.shutdownOutput();
- channel.close();
- }
-
- @Test
- public void testOddEvenStreamIds() throws Exception
- {
- final CountDownLatch pushStreamIdIsEvenLatch = new CountDownLatch(3);
-
- Session clientSession = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.push(new PushInfo(new Fields(), false), new Promise.Adapter<Stream>());
- return null;
- }
- }), null);
-
- Stream stream = clientSession.syn(new SynInfo(new Fields(), false),
- new VerifyPushStreamIdIsEvenStreamFrameListener(pushStreamIdIsEvenLatch));
- Stream stream2 = clientSession.syn(new SynInfo(new Fields(), false),
- new VerifyPushStreamIdIsEvenStreamFrameListener(pushStreamIdIsEvenLatch));
- Stream stream3 = clientSession.syn(new SynInfo(new Fields(), false),
- new VerifyPushStreamIdIsEvenStreamFrameListener(pushStreamIdIsEvenLatch));
- assertStreamIdIsOdd(stream);
- assertStreamIdIsOdd(stream2);
- assertStreamIdIsOdd(stream3);
-
- assertThat("all pushStreams had even ids", pushStreamIdIsEvenLatch.await(5, TimeUnit.SECONDS), is(true));
- }
-
- private class VerifyPushStreamIdIsEvenStreamFrameListener extends StreamFrameListener.Adapter
- {
- final CountDownLatch pushStreamIdIsEvenLatch;
-
- private VerifyPushStreamIdIsEvenStreamFrameListener(CountDownLatch pushStreamIdIsEvenLatch)
- {
- this.pushStreamIdIsEvenLatch = pushStreamIdIsEvenLatch;
- }
-
- @Override
- public StreamFrameListener onPush(Stream stream, PushInfo pushInfo)
- {
- assertStreamIdIsEven(stream);
- pushStreamIdIsEvenLatch.countDown();
- return super.onPush(stream, pushInfo);
- }
- }
-
- private void assertStreamIdIsEven(Stream stream)
- {
- assertThat("streamId is odd", stream.getId() % 2, is(0));
- }
-
- private void assertStreamIdIsOdd(Stream stream)
- {
- assertThat("streamId is odd", stream.getId() % 2, is(1));
- }
-
- private void assertThatNoExceptionOccurred(final CountDownLatch exceptionCountDownLatch) throws InterruptedException
- {
- assertThat("No exception occurred", exceptionCountDownLatch.await(1, TimeUnit.SECONDS), is(false));
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ResetStreamTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ResetStreamTest.java
deleted file mode 100644
index c28657c637..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/ResetStreamTest.java
+++ /dev/null
@@ -1,204 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.RstInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.FutureCallback;
-import org.junit.Test;
-
-public class ResetStreamTest extends AbstractTest
-{
- @Test
- public void testResetStreamIsRemoved() throws Exception
- {
- Session session = startClient(startServer(new ServerSessionFrameListener.Adapter()/*TODO, true*/), null);
-
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
- session.rst(new RstInfo(5, TimeUnit.SECONDS, stream.getId(), StreamStatus.CANCEL_STREAM));
-
- assertEquals("session expected to contain 0 streams", 0, session.getStreams().size());
- }
-
- @Test
- public void testRefusedStreamIsRemoved() throws Exception
- {
- final AtomicReference<Session> serverSessionRef = new AtomicReference<>();
- final CountDownLatch synLatch = new CountDownLatch(1);
- final CountDownLatch rstLatch = new CountDownLatch(1);
- Session clientSession = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Session serverSession = stream.getSession();
- serverSessionRef.set(serverSession);
- serverSession.rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new FutureCallback());
- synLatch.countDown();
- return null;
- }
- }), new SessionFrameListener.Adapter()
- {
- @Override
- public void onRst(Session session, RstInfo rstInfo)
- {
- rstLatch.countDown();
- }
- });
-
- Stream stream = clientSession.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
-
- assertTrue("syncLatch didn't count down", synLatch.await(5, TimeUnit.SECONDS));
- Session serverSession = serverSessionRef.get();
- assertEquals("serverSession expected to contain 0 streams", 0, serverSession.getStreams().size());
-
- assertTrue("rstLatch didn't count down", rstLatch.await(5, TimeUnit.SECONDS));
- // Need to sleep a while to give the chance to the implementation to remove the stream
- TimeUnit.SECONDS.sleep(1);
- assertTrue("stream is expected to be reset", stream.isReset());
- assertEquals("clientSession expected to contain 0 streams", 0, clientSession.getStreams().size());
- }
-
- @Test
- public void testRefusedStreamIgnoresData() throws Exception
- {
- final CountDownLatch synLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- final CountDownLatch rstLatch = new CountDownLatch(1);
- Session session = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- try
- {
- // Refuse the stream, we must ignore data frames
- assertTrue(synLatch.await(5, TimeUnit.SECONDS));
- stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new FutureCallback());
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataLatch.countDown();
- }
- };
- }
- catch (InterruptedException x)
- {
- x.printStackTrace();
- return null;
- }
- }
- }), new SessionFrameListener.Adapter()
- {
- @Override
- public void onRst(Session session, RstInfo rstInfo)
- {
- rstLatch.countDown();
- }
- });
-
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
- stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "data", true), new Callback.Adapter()
- {
- @Override
- public void succeeded()
- {
- synLatch.countDown();
- }
- });
-
- assertTrue("rstLatch didn't count down", rstLatch.await(5, TimeUnit.SECONDS));
- assertTrue("stream is expected to be reset", stream.isReset());
- assertFalse("dataLatch shouldn't be count down", dataLatch.await(1, TimeUnit.SECONDS));
- }
-
- @Test
- public void testResetAfterServerReceivedFirstDataFrameAndSecondDataFrameFails() throws Exception
- {
- final CountDownLatch synLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- final CountDownLatch rstLatch = new CountDownLatch(1);
- final CountDownLatch failLatch = new CountDownLatch(1);
- Session session = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- synLatch.countDown();
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- dataLatch.countDown();
- stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new FutureCallback());
- }
- };
- }
- }), new SessionFrameListener.Adapter()
- {
- @Override
- public void onRst(Session session, RstInfo rstInfo)
- {
- rstLatch.countDown();
- }
- });
-
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0), null);
- assertThat("push is received by server", synLatch.await(5, TimeUnit.SECONDS), is(true));
- stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "data", false), new Callback.Adapter());
- assertThat("stream is reset", rstLatch.await(5, TimeUnit.SECONDS), is(true));
- stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "2nd dataframe", false), new Callback.Adapter()
- {
- @Override
- public void failed(Throwable x)
- {
- failLatch.countDown();
- }
- });
-
- assertThat("2nd data call failed", failLatch.await(5, TimeUnit.SECONDS), is(true));
- assertThat("stream is reset", stream.isReset(), is(true));
- }
-
- // TODO: If server already received 2nd dataframe after it rst, it should ignore it. Not easy to do.
-
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SPDYClientFactoryTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SPDYClientFactoryTest.java
deleted file mode 100644
index 91f197bea2..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SPDYClientFactoryTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SPDYClientFactoryTest extends AbstractTest
-{
- @Test
- public void testStoppingClientFactorySendsGoAway() throws Exception
- {
- final CountDownLatch latch = new CountDownLatch(1);
- startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayResultInfo)
- {
- latch.countDown();
- }
- }), null);
-
- // Sleep a while to avoid the factory is
- // stopped before a session can be opened
- TimeUnit.SECONDS.sleep(1);
-
- clientFactory.stop();
-
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(clientFactory.getSessions().isEmpty());
- }
-
- @Test
- public void testSessionClosedIsRemovedFromClientFactory() throws Exception
- {
- Session session = startClient(startServer(null), null);
-
- session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
-
- for (int i=0;i<10;i++)
- {
- // Sleep a while to allow the factory to remove the session
- // since it is done asynchronously by the selector thread
- TimeUnit.SECONDS.sleep(1);
- if (clientFactory.getSessions().isEmpty())
- return;
- }
-
- Assert.fail(clientFactory.getSessions().toString());
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SPDYServerConnectorTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SPDYServerConnectorTest.java
deleted file mode 100644
index 46c664c830..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SPDYServerConnectorTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.spdy.api.GoAwayInfo;
-import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SPDYServerConnectorTest extends AbstractTest
-{
- @Test
- public void testStoppingServerConnectorSendsGoAway() throws Exception
- {
- final CountDownLatch latch = new CountDownLatch(1);
- startClient(startServer(null), new SessionFrameListener.Adapter()
- {
- @Override
- public void onGoAway(Session session, GoAwayResultInfo goAwayResultInfo)
- {
- latch.countDown();
- }
- });
-
- // Sleep a while to avoid the connector is
- // stopped before a session can be opened
- TimeUnit.SECONDS.sleep(1);
-
- connector.stop();
-
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(connector.getConnectionFactory(SPDYServerConnectionFactory.class).getSessions().isEmpty());
- }
-
- @Test
- public void testSessionClosedIsRemovedFromServerConnector() throws Exception
- {
- Session session = startClient(startServer(null), null);
-
- session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
-
- // Sleep a while to allow the connector to remove the session
- // since it is done asynchronously by the selector thread
- TimeUnit.SECONDS.sleep(1);
-
- Assert.assertTrue(connector.getConnectionFactory(SPDYServerConnectionFactory.class).getSessions().isEmpty());
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SettingsTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SettingsTest.java
deleted file mode 100644
index 5a13bb93dd..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SettingsTest.java
+++ /dev/null
@@ -1,168 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import java.net.InetSocketAddress;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Settings;
-import org.eclipse.jetty.spdy.api.SettingsInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.util.FutureCallback;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SettingsTest extends AbstractTest
-{
- @Test
- public void testSettingsUsage() throws Exception
- {
- Settings settings = new Settings();
- int streamsValue = 100;
- settings.put(new Settings.Setting(Settings.ID.MAX_CONCURRENT_STREAMS, Settings.Flag.PERSIST, streamsValue));
- int windowValue = 32768;
- settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, windowValue));
- int newCode = 91;
- Settings.ID newID = Settings.ID.from(newCode);
- int newValue = 97;
- settings.put(new Settings.Setting(newID, newValue));
-
- Settings.Setting setting1 = settings.get(Settings.ID.MAX_CONCURRENT_STREAMS);
- Assert.assertSame(Settings.ID.MAX_CONCURRENT_STREAMS, setting1.id());
- Assert.assertSame(Settings.Flag.PERSIST, setting1.flag());
- Assert.assertEquals(streamsValue, setting1.value());
-
- Settings.Setting setting2 = settings.get(Settings.ID.INITIAL_WINDOW_SIZE);
- Assert.assertSame(Settings.ID.INITIAL_WINDOW_SIZE, setting2.id());
- Assert.assertSame(Settings.Flag.NONE, setting2.flag());
- Assert.assertEquals(windowValue, setting2.value());
-
- int size = settings.size();
- Settings.Setting setting3 = settings.remove(Settings.ID.from(newCode));
- Assert.assertEquals(size - 1, settings.size());
- Assert.assertNotNull(setting3);
- Assert.assertSame(newID, setting3.id());
- Assert.assertEquals(newValue, setting3.value());
- }
-
- @Test
- public void testSettings() throws Exception
- {
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.UPLOAD_BANDWIDTH, 1024 * 1024));
- settings.put(new Settings.Setting(Settings.ID.DOWNLOAD_BANDWIDTH, 1024 * 1024));
- settings.put(new Settings.Setting(Settings.ID.CURRENT_CONGESTION_WINDOW, Settings.Flag.PERSISTED, 1024));
- final SettingsInfo clientSettingsInfo = new SettingsInfo(settings);
- final CountDownLatch latch = new CountDownLatch(1);
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onSettings(Session session, SettingsInfo serverSettingsInfo)
- {
- Assert.assertEquals(clientSettingsInfo.getFlags(), serverSettingsInfo.getFlags());
- Assert.assertEquals(clientSettingsInfo.getSettings(), serverSettingsInfo.getSettings());
- latch.countDown();
- }
- };
- Session session = startClient(startServer(serverSessionFrameListener), null);
-
- session.settings(clientSettingsInfo);
-
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testServerSettings() throws Exception
- {
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.UPLOAD_BANDWIDTH, 1024 * 1024));
- settings.put(new Settings.Setting(Settings.ID.DOWNLOAD_BANDWIDTH, 1024 * 1024));
- settings.put(new Settings.Setting(Settings.ID.CURRENT_CONGESTION_WINDOW, Settings.Flag.PERSIST, 1024));
- final SettingsInfo serverSettingsInfo = new SettingsInfo(settings);
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onConnect(Session session)
- {
- session.settings(serverSettingsInfo, new FutureCallback());
- }
- };
-
- final CountDownLatch latch = new CountDownLatch(1);
- SessionFrameListener clientSessionFrameListener = new SessionFrameListener.Adapter()
- {
- @Override
- public void onSettings(Session session, SettingsInfo clientSettingsInfo)
- {
- Assert.assertEquals(serverSettingsInfo.getFlags(), clientSettingsInfo.getFlags());
- Assert.assertEquals(serverSettingsInfo.getSettings(), clientSettingsInfo.getSettings());
- latch.countDown();
- }
- };
-
- startClient(startServer(serverSessionFrameListener), clientSessionFrameListener);
-
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testSettingIDIsTheSameInBothV2AndV3() throws Exception
- {
- final AtomicReference<SettingsInfo> v2 = new AtomicReference<>();
- final AtomicReference<SettingsInfo> v3 = new AtomicReference<>();
- final CountDownLatch settingsLatch = new CountDownLatch(2);
- InetSocketAddress address = startServer(new ServerSessionFrameListener.Adapter()
- {
- private final AtomicInteger count = new AtomicInteger();
-
- @Override
- public void onSettings(Session session, SettingsInfo settingsInfo)
- {
- int count = this.count.incrementAndGet();
- if (count == 1)
- v2.set(settingsInfo);
- else if (count == 2)
- v3.set(settingsInfo);
- else
- Assert.fail();
- settingsLatch.countDown();
- }
- });
-
- Settings settings = new Settings();
- settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, Settings.Flag.PERSIST, 0xC0_00));
- SettingsInfo settingsInfo = new SettingsInfo(settings);
-
- Session sessionV2 = startClient(address, null);
- sessionV2.settings(settingsInfo);
-
- Session sessionV3 = clientFactory.newSPDYClient(SPDY.V3).connect(address, null);
- sessionV3.settings(settingsInfo);
-
- Assert.assertTrue(settingsLatch.await(5, TimeUnit.SECONDS));
- Assert.assertEquals(v2.get().getSettings(), v3.get().getSettings());
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SynDataReplyDataLoadTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SynDataReplyDataLoadTest.java
deleted file mode 100644
index 6dfdb5b691..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SynDataReplyDataLoadTest.java
+++ /dev/null
@@ -1,288 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.eclipse.jetty.io.LeakTrackingByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.spdy.api.ByteBufferDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.eclipse.jetty.util.thread.Scheduler;
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-public class SynDataReplyDataLoadTest extends AbstractTest
-{
- private static final int TIMEOUT = 60 * 1000;
- private static final Logger logger = Log.getLogger(SynDataReplyDataLoadTest.class);
-
- @Test(timeout = TIMEOUT)
- @Ignore("Test needs to be rewritten")
- public void testSynDataReplyDataLoad() throws Exception
- {
- LeakTrackingByteBufferPool serverBufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
- LeakTrackingByteBufferPool clientBufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
-
- ServerSessionFrameListener listener = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- stream.reply(new ReplyInfo(synInfo.getHeaders(), false), new Callback.Adapter());
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- ByteBuffer buffer = dataInfo.asByteBuffer(true);
- stream.data(new ByteBufferDataInfo(buffer, dataInfo.isClose()), new Callback.Adapter());
- }
- };
- }
- };
-
- short spdyVersion = SPDY.V2;
- long idleTimeout = 2 * TIMEOUT;
-
- server = newServer();
- connector = new ServerConnector(server, null, null, serverBufferPool, 1,
- Math.max(1, Runtime.getRuntime().availableProcessors() / 2),
- new SPDYServerConnectionFactory(spdyVersion, listener));
- connector.setIdleTimeout(idleTimeout);
-
- QueuedThreadPool clientExecutor = new QueuedThreadPool();
- clientExecutor.setName(clientExecutor.getName() + "-client");
- clientFactory = new SPDYClient.Factory(clientExecutor, null, clientBufferPool, null, idleTimeout);
- final Session session = startClient(spdyVersion, startServer(spdyVersion, listener), null);
-
- final Thread testThread = Thread.currentThread();
- Runnable timeout = new Runnable()
- {
- @Override
- public void run()
- {
- logger.warn("Interrupting test, it is taking too long");
- logger.warn("SERVER: {}", server.dump());
- logger.warn("CLIENT: {}", clientFactory.dump());
- testThread.interrupt();
- }
- };
-
- final int iterations = 500;
- final int count = 50;
-
- final Fields headers = new Fields();
- headers.put("method", "get");
- headers.put("url", "/");
- headers.put("version", "http/1.1");
- headers.put("host", "localhost:8080");
- headers.put("content-type", "application/octet-stream");
-
- final CountDownLatch latch = new CountDownLatch(count * iterations);
- session.addListener(new Session.StreamListener.Adapter()
- {
- @Override
- public void onStreamClosed(Stream stream)
- {
- latch.countDown();
- }
- });
-
- ExecutorService threadPool = Executors.newFixedThreadPool(count);
- List<Callable<Object>> tasks = new ArrayList<>();
-
- tasks.clear();
- for (int i = 0; i < count; ++i)
- {
- tasks.add(new Callable<Object>()
- {
- @Override
- public Object call() throws Exception
- {
- synGetDataGet(session, headers, iterations);
- return null;
- }
- });
- }
- Scheduler.Task syncTimeoutTask = clientFactory.getScheduler().schedule(timeout, TIMEOUT / 2, TimeUnit.MILLISECONDS);
- {
- long begin = System.nanoTime();
- List<Future<Object>> futures = threadPool.invokeAll(tasks);
- for (Future<Object> future : futures)
- future.get(iterations, TimeUnit.SECONDS);
- Assert.assertTrue(latch.await(count * iterations, TimeUnit.SECONDS));
- long end = System.nanoTime();
- System.err.printf("SYN+GET+DATA+GET completed in %d ms%n", TimeUnit.NANOSECONDS.toMillis(end - begin));
- }
- syncTimeoutTask.cancel();
-
- tasks.clear();
- for (int i = 0; i < count; ++i)
- {
- tasks.add(new Callable<Object>()
- {
- @Override
- public Object call() throws Exception
- {
- synCompletedData(session, headers, iterations);
- return null;
- }
- });
- }
- Scheduler.Task asyncTimeoutTask = clientFactory.getScheduler().schedule(timeout, TIMEOUT / 2, TimeUnit.MILLISECONDS);
- {
- long begin = System.nanoTime();
- List<Future<Object>> futures = threadPool.invokeAll(tasks);
- for (Future<Object> future : futures)
- future.get(iterations, TimeUnit.SECONDS);
- Assert.assertTrue(latch.await(count * iterations, TimeUnit.SECONDS));
- long end = System.nanoTime();
- System.err.printf("SYN+COMPLETED+DATA completed in %d ms%n", TimeUnit.NANOSECONDS.toMillis(end - begin));
- }
- asyncTimeoutTask.cancel();
-
- threadPool.shutdown();
-
- System.gc();
-
- assertThat("Server BufferPool - leaked acquires", serverBufferPool.getLeakedAcquires(), is(0L));
- assertThat("Server BufferPool - leaked releases", serverBufferPool.getLeakedReleases(), is(0L));
- assertThat("Server BufferPool - unreleased", serverBufferPool.getLeakedResources(), is(0L));
-
- assertThat("Client BufferPool - leaked acquires", clientBufferPool.getLeakedAcquires(), is(0L));
- assertThat("Client BufferPool - leaked releases", clientBufferPool.getLeakedReleases(), is(0L));
- assertThat("Client BufferPool - unreleased", clientBufferPool.getLeakedResources(), is(0L));
- }
-
- private void synCompletedData(Session session, Fields headers, int iterations) throws Exception
- {
- final Map<Integer, Integer> counter = new ConcurrentHashMap<>(iterations);
- final CountDownLatch requestsLatch = new CountDownLatch(2 * iterations);
- for (int i = 0; i < iterations; ++i)
- {
- final AtomicInteger count = new AtomicInteger(2);
- final int index = i;
- counter.put(index, index);
- session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertEquals(2, count.getAndDecrement());
- requestsLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- // TCP can split the data frames, so I may be receiving more than 1 data frame
- dataInfo.asBytes(true);
- if (dataInfo.isClose())
- {
- Assert.assertEquals(1, count.getAndDecrement());
- counter.remove(index);
- requestsLatch.countDown();
- }
- }
- }, new Promise.Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream stream)
- {
- stream.data(new StringDataInfo("data_" + stream.getId(), true),
- new Callback.Adapter());
- }
- }
- );
- }
- Assert.assertTrue(requestsLatch.await(iterations, TimeUnit.SECONDS));
- Assert.assertTrue(counter.toString(), counter.isEmpty());
- }
-
- private void synGetDataGet(Session session, Fields headers, int iterations) throws Exception
- {
- final Map<Integer, Integer> counter = new ConcurrentHashMap<>(iterations);
- final CountDownLatch latch = new CountDownLatch(2 * iterations);
- for (int i = 0; i < iterations; ++i)
- {
- final AtomicInteger count = new AtomicInteger(2);
- final int index = i;
- counter.put(index, index);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, headers, false, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertEquals(2, count.getAndDecrement());
- latch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- // TCP can split the data frames, so I may be receiving more than 1 data frame
- dataInfo.asBytes(true);
- if (dataInfo.isClose())
- {
- Assert.assertEquals(1, count.getAndDecrement());
- counter.remove(index);
- latch.countDown();
- }
- }
- });
- stream.data(new StringDataInfo(5, TimeUnit.SECONDS, "data_" + stream.getId(), true));
- }
- Assert.assertTrue(latch.await(iterations, TimeUnit.SECONDS));
- Assert.assertTrue(counter.toString(), counter.isEmpty());
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SynReplyTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SynReplyTest.java
deleted file mode 100644
index 29c2b50385..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SynReplyTest.java
+++ /dev/null
@@ -1,375 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.io.ByteArrayOutputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.jetty.spdy.api.BytesDataInfo;
-import org.eclipse.jetty.spdy.api.DataInfo;
-import org.eclipse.jetty.spdy.api.ReplyInfo;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.SessionFrameListener;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StringDataInfo;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.util.Callback;
-import org.eclipse.jetty.util.Fields;
-import org.eclipse.jetty.util.Promise;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SynReplyTest extends AbstractTest
-{
- @Test
- public void testSynReply() throws Exception
- {
- final AtomicReference<Session> sessionRef = new AtomicReference<>();
- final CountDownLatch sessionLatch = new CountDownLatch(1);
- final CountDownLatch synLatch = new CountDownLatch(1);
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onConnect(Session session)
- {
- sessionRef.set(session);
- sessionLatch.countDown();
- }
-
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Assert.assertTrue(stream.isHalfClosed());
- stream.reply(new ReplyInfo(new Fields(), true), new Callback.Adapter());
- synLatch.countDown();
- return null;
- }
- };
-
- Session session = startClient(startServer(serverSessionFrameListener), null);
-
- Assert.assertTrue(sessionLatch.await(5, TimeUnit.SECONDS));
- Session serverSession = sessionRef.get();
- Assert.assertNotNull(serverSession);
-
- final CountDownLatch streamCreatedLatch = new CountDownLatch(1);
- final CountDownLatch streamRemovedLatch = new CountDownLatch(1);
- session.addListener(new Session.StreamListener()
- {
- @Override
- public void onStreamCreated(Stream stream)
- {
- streamCreatedLatch.countDown();
- }
-
- @Override
- public void onStreamClosed(Stream stream)
- {
- streamRemovedLatch.countDown();
- }
- });
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), true, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertTrue(stream.isClosed());
- replyLatch.countDown();
- }
- });
-
- Assert.assertTrue(synLatch.await(5, TimeUnit.SECONDS));
-
- Assert.assertTrue(streamCreatedLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(stream.isClosed());
-
- Assert.assertTrue(streamRemovedLatch.await(5, TimeUnit.SECONDS));
- Assert.assertEquals(0, session.getStreams().size());
- }
-
- @Test
- public void testSynDataReply() throws Exception
- {
- final byte[] dataBytes = "foo".getBytes(StandardCharsets.UTF_8);
-
- final CountDownLatch synLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch = new CountDownLatch(1);
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Assert.assertFalse(stream.isHalfClosed());
- Assert.assertFalse(stream.isClosed());
- synLatch.countDown();
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- ByteBuffer buffer = ByteBuffer.allocate(2);
- while (dataInfo.available() > 0)
- {
- dataInfo.readInto(buffer);
- buffer.flip();
- bytes.write(buffer.array(), buffer.arrayOffset(), buffer.remaining());
- buffer.clear();
- }
- Assert.assertTrue(Arrays.equals(dataBytes, bytes.toByteArray()));
- Assert.assertTrue(stream.isHalfClosed());
- Assert.assertFalse(stream.isClosed());
-
- stream.reply(new ReplyInfo(true), new Callback.Adapter());
- Assert.assertTrue(stream.isClosed());
- dataLatch.countDown();
- }
- };
- }
- };
-
- Session session = startClient(startServer(serverSessionFrameListener), null);
-
- final CountDownLatch streamRemovedLatch = new CountDownLatch(1);
- session.addListener(new Session.StreamListener.Adapter()
- {
- @Override
- public void onStreamClosed(Stream stream)
- {
- streamRemovedLatch.countDown();
- }
- });
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- Stream stream = session.syn(new SynInfo(5, TimeUnit.SECONDS, new Fields(), false, (byte)0),
- new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- replyLatch.countDown();
- }
- });
- stream.data(new BytesDataInfo(dataBytes, true));
-
- Assert.assertTrue(synLatch.await(5, TimeUnit.SECONDS));
-
- Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
-
- Assert.assertTrue(streamRemovedLatch.await(5, TimeUnit.SECONDS));
- Assert.assertEquals(0, session.getStreams().size());
- }
-
- @Test
- public void testSynReplyDataData() throws Exception
- {
- final String data1 = "foo";
- final String data2 = "bar";
- Session session = startClient(startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(final Stream stream, SynInfo synInfo)
- {
- Assert.assertTrue(stream.isHalfClosed());
-
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- stream.data(new StringDataInfo(5, TimeUnit.SECONDS, data1, false), new Callback.Adapter()
- {
- @Override
- public void succeeded()
- {
- stream.data(new StringDataInfo(data2, true), new Adapter());
- }
- });
-
- return null;
- }
- }), null);
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch dataLatch1 = new CountDownLatch(1);
- final CountDownLatch dataLatch2 = new CountDownLatch(1);
- session.syn(new SynInfo(new Fields(), true), new StreamFrameListener.Adapter()
- {
- private AtomicInteger dataCount = new AtomicInteger();
-
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- int dataCount = this.dataCount.incrementAndGet();
- if (dataCount == 1)
- {
- String chunk1 = dataInfo.asString(StandardCharsets.UTF_8, true);
- Assert.assertEquals(data1, chunk1);
- dataLatch1.countDown();
- }
- else if (dataCount == 2)
- {
- String chunk2 = dataInfo.asString(StandardCharsets.UTF_8, true);
- Assert.assertEquals(data2, chunk2);
- dataLatch2.countDown();
- }
- }
- });
-
- Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(dataLatch1.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(dataLatch2.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testServerSynDataReplyData() throws Exception
- {
- final String serverData = "server";
- final String clientData = "client";
-
- final CountDownLatch replyLatch = new CountDownLatch(1);
- final CountDownLatch clientDataLatch = new CountDownLatch(1);
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public void onConnect(Session session)
- {
- session.syn(new SynInfo(new Fields(), false), new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- String data = dataInfo.asString(StandardCharsets.UTF_8, true);
- Assert.assertEquals(clientData, data);
- clientDataLatch.countDown();
- }
- }, new Promise.Adapter<Stream>()
- {
- @Override
- public void succeeded(Stream stream)
- {
- stream.data(new StringDataInfo(serverData, true), new Callback.Adapter());
- }
- });
- }
- };
-
- final CountDownLatch synLatch = new CountDownLatch(1);
- final CountDownLatch serverDataLatch = new CountDownLatch(1);
- SessionFrameListener clientSessionFrameListener = new SessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Assert.assertEquals(0, stream.getId() % 2);
-
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- stream.data(new StringDataInfo(clientData, true), new Callback.Adapter());
- synLatch.countDown();
-
- return new StreamFrameListener.Adapter()
- {
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- ByteBuffer buffer = dataInfo.asByteBuffer(false);
- String data = StandardCharsets.UTF_8.decode(buffer).toString();
- Assert.assertEquals(serverData, data);
- serverDataLatch.countDown();
- }
- };
- }
- };
-
- startClient(startServer(serverSessionFrameListener), clientSessionFrameListener);
-
- Assert.assertTrue(synLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(serverDataLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(clientDataLatch.await(5, TimeUnit.SECONDS));
- }
-
- @Test
- public void testSynReplyDataSynReplyData() throws Exception
- {
- final String data = "foo";
- ServerSessionFrameListener serverSessionFrameListener = new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- Assert.assertTrue(stream.isHalfClosed());
-
- stream.reply(new ReplyInfo(false), new Callback.Adapter());
- stream.data(new StringDataInfo(data, true), new Callback.Adapter());
-
- return null;
- }
- };
-
- Session session = startClient(startServer(serverSessionFrameListener), null);
-
- final CountDownLatch replyLatch = new CountDownLatch(2);
- final CountDownLatch dataLatch = new CountDownLatch(2);
- StreamFrameListener clientStreamFrameListener = new StreamFrameListener.Adapter()
- {
- @Override
- public void onReply(Stream stream, ReplyInfo replyInfo)
- {
- Assert.assertFalse(replyInfo.isClose());
- replyLatch.countDown();
- }
-
- @Override
- public void onData(Stream stream, DataInfo dataInfo)
- {
- String chunk = dataInfo.asString(StandardCharsets.UTF_8, true);
- Assert.assertEquals(data, chunk);
- dataLatch.countDown();
- }
- };
- session.syn(new SynInfo(new Fields(), true), clientStreamFrameListener);
- session.syn(new SynInfo(new Fields(), true), clientStreamFrameListener);
-
- Assert.assertTrue(replyLatch.await(5, TimeUnit.SECONDS));
- Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/UnsupportedVersionTest.java b/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/UnsupportedVersionTest.java
deleted file mode 100644
index 5d92bee910..0000000000
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/UnsupportedVersionTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.spdy.server;
-
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.spdy.StandardCompressionFactory;
-import org.eclipse.jetty.spdy.api.SPDY;
-import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.Stream;
-import org.eclipse.jetty.spdy.api.StreamFrameListener;
-import org.eclipse.jetty.spdy.api.StreamStatus;
-import org.eclipse.jetty.spdy.api.SynInfo;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.frames.ControlFrame;
-import org.eclipse.jetty.spdy.frames.ControlFrameType;
-import org.eclipse.jetty.spdy.frames.RstStreamFrame;
-import org.eclipse.jetty.spdy.frames.SynStreamFrame;
-import org.eclipse.jetty.spdy.generator.Generator;
-import org.eclipse.jetty.spdy.parser.Parser;
-import org.eclipse.jetty.util.Fields;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class UnsupportedVersionTest extends AbstractTest
-{
- @Test
- public void testSynWithUnsupportedVersion() throws Exception
- {
- final CountDownLatch synLatch = new CountDownLatch(1);
- InetSocketAddress address = startServer(new ServerSessionFrameListener.Adapter()
- {
- @Override
- public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
- {
- synLatch.countDown();
- return null;
- }
-
- @Override
- public void onFailure(Session session, Throwable x)
- {
- // Suppress exception logging for this test
- }
- });
-
- SynStreamFrame frame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, new Fields());
- Generator generator = new Generator(new MappedByteBufferPool(), new StandardCompressionFactory.StandardCompressor());
- ByteBuffer buffer = generator.control(frame);
- // Replace the version byte with an unsupported version
- buffer.putShort(0, (short)0x8001);
-
- SocketChannel channel = SocketChannel.open(address);
- channel.write(buffer);
- Assert.assertFalse(buffer.hasRemaining());
-
- Assert.assertFalse(synLatch.await(1, TimeUnit.SECONDS));
-
- buffer = ByteBuffer.allocate(1024);
- channel.read(buffer);
- buffer.flip();
-
- final CountDownLatch rstLatch = new CountDownLatch(1);
- Parser parser = new Parser(new StandardCompressionFactory.StandardDecompressor());
- parser.addListener(new Parser.Listener.Adapter()
- {
- @Override
- public void onControlFrame(ControlFrame frame)
- {
- Assert.assertSame(ControlFrameType.RST_STREAM, frame.getType());
- Assert.assertEquals(StreamStatus.UNSUPPORTED_VERSION.getCode(frame.getVersion()), ((RstStreamFrame)frame).getStatusCode());
- rstLatch.countDown();
- }
- });
- parser.parse(buffer);
-
- Assert.assertTrue(rstLatch.await(5, TimeUnit.SECONDS));
- }
-}
diff --git a/jetty-spdy/spdy-server/src/test/resources/jetty-logging.properties b/jetty-spdy/spdy-server/src/test/resources/jetty-logging.properties
deleted file mode 100644
index ead13ec197..0000000000
--- a/jetty-spdy/spdy-server/src/test/resources/jetty-logging.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-#org.eclipse.jetty.spdy.LEVEL=DEBUG

Back to the top