/
RequestLineSpec.groovy
105 lines (91 loc) · 3.89 KB
/
RequestLineSpec.groovy
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
package io.micronaut.http.server.netty
import io.micronaut.context.ApplicationContext
import io.micronaut.context.annotation.Requires
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.runtime.server.EmbeddedServer
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.ChannelOutboundHandlerAdapter
import io.netty.channel.ChannelPromise
import io.netty.channel.embedded.EmbeddedChannel
import io.netty.handler.codec.http.DefaultHttpRequest
import io.netty.handler.codec.http.FullHttpResponse
import io.netty.handler.codec.http.HttpClientCodec
import io.netty.handler.codec.http.HttpHeaderNames
import io.netty.handler.codec.http.HttpHeaderValues
import io.netty.handler.codec.http.HttpMethod
import io.netty.handler.codec.http.HttpObjectAggregator
import io.netty.handler.codec.http.HttpResponseStatus
import io.netty.handler.codec.http.HttpVersion
import jakarta.inject.Singleton
import spock.lang.Issue
import spock.lang.Specification
import java.nio.charset.StandardCharsets
class RequestLineSpec extends Specification {
@Issue('https://github.com/micronaut-projects/micronaut-core/issues/7193')
def 'test different request lines http 1'() {
given:
ApplicationContext ctx = ApplicationContext.run([
'spec.name': 'RequestLineSpec',
])
def embeddedServer = (NettyHttpServer) ctx.getBean(EmbeddedServer)
def serverEmbeddedChannel = embeddedServer.buildEmbeddedChannel(false)
def clientEmbeddedChannel = new EmbeddedChannel()
serverEmbeddedChannel.pipeline()
.addFirst(new ChannelOutboundHandlerAdapter() {
@Override
void write(ChannelHandlerContext ctx_, Object msg, ChannelPromise promise) throws Exception {
// forward to client
clientEmbeddedChannel.writeOneInbound(msg)
}
@Override
void flush(ChannelHandlerContext ctx_) throws Exception {
clientEmbeddedChannel.flushInbound()
}
})
clientEmbeddedChannel.pipeline()
.addLast(new ChannelOutboundHandlerAdapter() {
@Override
void write(ChannelHandlerContext ctx_, Object msg, ChannelPromise promise) throws Exception {
// forward to server
serverEmbeddedChannel.writeOneInbound(msg)
}
@Override
void flush(ChannelHandlerContext ctx_) throws Exception {
serverEmbeddedChannel.flushInbound()
}
})
.addLast(new HttpClientCodec())
.addLast(new HttpObjectAggregator(1024))
def request1 = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri)
request1.headers().add(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE)
when:
clientEmbeddedChannel.writeOneOutbound(request1)
clientEmbeddedChannel.flushOutbound()
serverEmbeddedChannel.runPendingTasks()
then:
FullHttpResponse response = clientEmbeddedChannel.readInbound()
response.status() == HttpResponseStatus.OK
response.content().toString(StandardCharsets.UTF_8) == 'bar'
cleanup:
response.release()
clientEmbeddedChannel.close()
serverEmbeddedChannel.close()
ctx.close()
where:
uri << [
'/foo', // origin-form
'http://example.com/foo', // absolute-form
'http:///foo', // weird form
]
}
@Singleton
@Controller
@Requires(property = 'spec.name', value = 'RequestLineSpec')
public static class SimpleController {
@Get('/foo')
public String foo() {
return "bar"
}
}
}