Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: a8bff06d67b69e076949f3e3e497820732d02aa1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.eclipse.jetty.spdy.api;

import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
import org.junit.Ignore;
import org.junit.Test;

@Ignore
public class ServerUsageTest
{
    @Test
    public void testServerSynAndReplyWithData() throws Exception
    {
        new ServerSessionFrameListener.Adapter()
        {
            @Override
            public StreamFrameListener onSyn(Stream stream, SynInfo streamInfo)
            {
                Headers 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
                Headers replyHeaders = new Headers();
                replyHeaders.put(synHeaders.get("host"));
                // Sends a reply
                stream.reply(new ReplyInfo(replyHeaders, false));

                // Sends data
                StringDataInfo dataInfo = new StringDataInfo("foo", false);
                stream.data(dataInfo);
                // Stream is now closed
                return null;
            }
        };
    }

    @Test
    public void testServerInitiatesStreamAndPushesData() throws Exception
    {
        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(false), null, 0, TimeUnit.MILLISECONDS, new Handler.Adapter<Stream>()
                {
                    @Override
                    public void completed(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 Headers(), true));
                    }
                });
            }
        };
    }

    @Test
    public void testServerPush() throws Exception
    {
        new ServerSessionFrameListener.Adapter()
        {
            @Override
            public StreamFrameListener onSyn(Stream stream, SynInfo streamInfo)
            {
                // Need to send the reply first
                stream.reply(new ReplyInfo(false));

                Session session = stream.getSession();
                // Since it's unidirectional, no need to pass the listener
                session.syn(new SynInfo(new Headers(), false, (byte)0), null, 0, TimeUnit.MILLISECONDS, new Handler.Adapter<Stream>()
                {
                    @Override
                    public void completed(Stream pushStream)
                    {
                        pushStream.data(new StringDataInfo("foo", false));
                    }
                });
                return null;
            }
        };
    }
}

Back to the top