git.iko.soy/typeable/oauth2-proxy
on bee7879 help sign in
967 lines 30 kB history raw
1package http
3import (
4 "context"
5 "errors"
6 "fmt"
7 "io"
8 "net/http"
10 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
11 . "github.com/onsi/ginkgo"
12 . "github.com/onsi/ginkgo/extensions/table"
13 . "github.com/onsi/gomega"
16const hello = "Hello World!"
18var _ = Describe("Server", func() {
19 handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
20 rw.Write([]byte(hello))
21 })
23 Context("NewServer", func() {
24 type newServerTableInput struct {
25 opts Opts
26 expectedErr error
27 expectHTTPListener bool
28 expectTLSListener bool
29 }
31 DescribeTable("When creating the new server from the options", func(in *newServerTableInput) {
32 srv, err := NewServer(in.opts)
33 if in.expectedErr != nil {
34 Expect(err).To(MatchError(ContainSubstring(in.expectedErr.Error())))
35 Expect(srv).To(BeNil())
36 return
37 }
39 Expect(err).ToNot(HaveOccurred())
41 s, ok := srv.(*server)
42 Expect(ok).To(BeTrue())
44 Expect(s.listener != nil).To(Equal(in.expectHTTPListener))
45 if in.expectHTTPListener {
46 Expect(s.listener.Close()).To(Succeed())
47 }
48 Expect(s.tlsListener != nil).To(Equal(in.expectTLSListener))
49 if in.expectTLSListener {
50 Expect(s.tlsListener.Close()).To(Succeed())
51 }
52 },
53 Entry("with an ipv4 valid http bind address", &newServerTableInput{
54 opts: Opts{
55 Handler: handler,
56 BindAddress: "127.0.0.1:0",
57 },
58 expectedErr: nil,
59 expectHTTPListener: true,
60 expectTLSListener: false,
61 }),
62 Entry("with an ipv4 valid https bind address, with no TLS config", &newServerTableInput{
63 opts: Opts{
64 Handler: handler,
65 SecureBindAddress: "127.0.0.1:0",
66 },
67 expectedErr: errors.New("error setting up TLS listener: no TLS config provided"),
68 expectHTTPListener: false,
69 expectTLSListener: false,
70 }),
71 Entry("with an ipv4 valid https bind address, and valid TLS config", &newServerTableInput{
72 opts: Opts{
73 Handler: handler,
74 SecureBindAddress: "127.0.0.1:0",
75 TLS: &options.TLS{
76 Key: &ipv4KeyDataSource,
77 Cert: &ipv4CertDataSource,
78 },
79 },
80 expectedErr: nil,
81 expectHTTPListener: false,
82 expectTLSListener: true,
83 }),
84 Entry("with a both a ipv4 valid http and ipv4 valid https bind address, and valid TLS config", &newServerTableInput{
85 opts: Opts{
86 Handler: handler,
87 BindAddress: "127.0.0.1:0",
88 SecureBindAddress: "127.0.0.1:0",
89 TLS: &options.TLS{
90 Key: &ipv4KeyDataSource,
91 Cert: &ipv4CertDataSource,
92 },
93 },
94 expectedErr: nil,
95 expectHTTPListener: true,
96 expectTLSListener: true,
97 }),
98 Entry("with a \"-\" for the bind address", &newServerTableInput{
99 opts: Opts{
100 Handler: handler,
101 BindAddress: "-",
102 },
103 expectedErr: nil,
104 expectHTTPListener: false,
105 expectTLSListener: false,
106 }),
107 Entry("with a \"-\" for the secure bind address", &newServerTableInput{
108 opts: Opts{
109 Handler: handler,
110 SecureBindAddress: "-",
111 },
112 expectedErr: nil,
113 expectHTTPListener: false,
114 expectTLSListener: false,
115 }),
116 Entry("with an ipv4 invalid bind address scheme", &newServerTableInput{
117 opts: Opts{
118 Handler: handler,
119 BindAddress: "invalid://127.0.0.1:0",
120 },
121 expectedErr: errors.New("error setting up listener: listen (invalid, 127.0.0.1:0) failed: listen invalid: unknown network invalid"),
122 expectHTTPListener: false,
123 expectTLSListener: false,
124 }),
125 Entry("with an ipv4 invalid secure bind address scheme", &newServerTableInput{
126 opts: Opts{
127 Handler: handler,
128 SecureBindAddress: "invalid://127.0.0.1:0",
129 TLS: &options.TLS{
130 Key: &ipv4KeyDataSource,
131 Cert: &ipv4CertDataSource,
132 },
133 },
134 expectedErr: nil,
135 expectHTTPListener: false,
136 expectTLSListener: true,
137 }),
138 Entry("with an ipv4 invalid bind address port", &newServerTableInput{
139 opts: Opts{
140 Handler: handler,
141 BindAddress: "127.0.0.1:a",
142 },
143 expectedErr: errors.New("error setting up listener: listen (tcp, 127.0.0.1:a) failed: listen tcp: "),
144 expectHTTPListener: false,
145 expectTLSListener: false,
146 }),
147 Entry("with an ipv4 invalid secure bind address port", &newServerTableInput{
148 opts: Opts{
149 Handler: handler,
150 SecureBindAddress: "127.0.0.1:a",
151 TLS: &options.TLS{
152 Key: &ipv4KeyDataSource,
153 Cert: &ipv4CertDataSource,
154 },
155 },
156 expectedErr: errors.New("error setting up TLS listener: listen (127.0.0.1:a) failed: listen tcp: "),
157 expectHTTPListener: false,
158 expectTLSListener: false,
159 }),
160 Entry("with an ipv4 invalid TLS key", &newServerTableInput{
161 opts: Opts{
162 Handler: handler,
163 SecureBindAddress: "127.0.0.1:0",
164 TLS: &options.TLS{
165 Key: &options.SecretSource{
166 Value: []byte("invalid"),
167 },
168 Cert: &ipv4CertDataSource,
169 },
170 },
171 expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not parse certificate data: tls: failed to find any PEM data in key input"),
172 expectHTTPListener: false,
173 expectTLSListener: false,
174 }),
175 Entry("with an ipv4 invalid TLS cert", &newServerTableInput{
176 opts: Opts{
177 Handler: handler,
178 SecureBindAddress: "127.0.0.1:0",
179 TLS: &options.TLS{
180 Key: &ipv4KeyDataSource,
181 Cert: &options.SecretSource{
182 Value: []byte("invalid"),
183 },
184 },
185 },
186 expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not parse certificate data: tls: failed to find any PEM data in certificate input"),
187 expectHTTPListener: false,
188 expectTLSListener: false,
189 }),
190 Entry("with an ipv4 address, with no TLS key", &newServerTableInput{
191 opts: Opts{
192 Handler: handler,
193 SecureBindAddress: "127.0.0.1:0",
194 TLS: &options.TLS{
195 Cert: &ipv4CertDataSource,
196 },
197 },
198 expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not load key data: no configuration provided"),
199 expectHTTPListener: false,
200 expectTLSListener: false,
201 }),
202 Entry("with an ipv4 address, with no TLS cert", &newServerTableInput{
203 opts: Opts{
204 Handler: handler,
205 SecureBindAddress: "127.0.0.1:0",
206 TLS: &options.TLS{
207 Key: &ipv4KeyDataSource,
208 },
209 },
210 expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not load cert data: no configuration provided"),
211 expectHTTPListener: false,
212 expectTLSListener: false,
213 }),
214 Entry("when the ipv4 bind address is prefixed with the http scheme", &newServerTableInput{
215 opts: Opts{
216 Handler: handler,
217 BindAddress: "http://127.0.0.1:0",
218 },
219 expectedErr: nil,
220 expectHTTPListener: true,
221 expectTLSListener: false,
222 }),
223 Entry("when the ipv4 secure bind address is prefixed with the https scheme", &newServerTableInput{
224 opts: Opts{
225 Handler: handler,
226 SecureBindAddress: "https://127.0.0.1:0",
227 TLS: &options.TLS{
228 Key: &ipv4KeyDataSource,
229 Cert: &ipv4CertDataSource,
230 },
231 },
232 expectedErr: nil,
233 expectHTTPListener: false,
234 expectTLSListener: true,
235 }),
236 Entry("with an ipv4 valid https bind address, and valid TLS config with MinVersion", &newServerTableInput{
237 opts: Opts{
238 Handler: handler,
239 SecureBindAddress: "127.0.0.1:0",
240 TLS: &options.TLS{
241 Key: &ipv4KeyDataSource,
242 Cert: &ipv4CertDataSource,
243 MinVersion: "TLS1.3",
244 },
245 },
246 expectedErr: nil,
247 expectHTTPListener: false,
248 expectTLSListener: true,
249 }),
250 Entry("with an ipv4 valid https bind address, and invalid TLS config with unknown MinVersion", &newServerTableInput{
251 opts: Opts{
252 Handler: handler,
253 SecureBindAddress: "127.0.0.1:0",
254 TLS: &options.TLS{
255 Key: &ipv4KeyDataSource,
256 Cert: &ipv4CertDataSource,
257 MinVersion: "TLS1.42",
258 },
259 },
260 expectedErr: errors.New("error setting up TLS listener: unknown TLS MinVersion config provided"),
261 expectHTTPListener: false,
262 expectTLSListener: true,
263 }),
264 Entry("with an ipv4 valid https bind address, and valid TLS config with CipherSuites", &newServerTableInput{
265 opts: Opts{
266 Handler: handler,
267 SecureBindAddress: "127.0.0.1:0",
268 TLS: &options.TLS{
269 Key: &ipv4KeyDataSource,
270 Cert: &ipv4CertDataSource,
271 CipherSuites: []string{
272 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
273 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
274 },
275 },
276 },
277 expectedErr: nil,
278 expectHTTPListener: false,
279 expectTLSListener: true,
280 }),
281 Entry("with an ipv4 valid https bind address, and invalid TLS config with unknown CipherSuites", &newServerTableInput{
282 opts: Opts{
283 Handler: handler,
284 SecureBindAddress: "127.0.0.1:0",
285 TLS: &options.TLS{
286 Key: &ipv4KeyDataSource,
287 Cert: &ipv4CertDataSource,
288 CipherSuites: []string{
289 "TLS_RSA_WITH_RC4_64_SHA",
290 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
291 },
292 },
293 },
294 expectedErr: errors.New("error setting up TLS listener: could not parse cipher suites: unknown TLS cipher suite name specified \"TLS_RSA_WITH_RC4_64_SHA\""),
295 expectHTTPListener: false,
296 expectTLSListener: true,
297 }),
298 Entry("with an ipv6 valid http bind address", &newServerTableInput{
299 opts: Opts{
300 Handler: handler,
301 BindAddress: "[::1]:0",
302 },
303 expectedErr: nil,
304 expectHTTPListener: true,
305 expectTLSListener: false,
306 }),
307 Entry("with an ipv6 valid https bind address, with no TLS config", &newServerTableInput{
308 opts: Opts{
309 Handler: handler,
310 SecureBindAddress: "[::1]:0",
311 },
312 expectedErr: errors.New("error setting up TLS listener: no TLS config provided"),
313 expectHTTPListener: false,
314 expectTLSListener: false,
315 }),
316 Entry("with an ipv6 valid https bind address, and valid TLS config", &newServerTableInput{
317 opts: Opts{
318 Handler: handler,
319 SecureBindAddress: "[::1]:0",
320 TLS: &options.TLS{
321 Key: &ipv6KeyDataSource,
322 Cert: &ipv6CertDataSource,
323 },
324 },
325 expectedErr: nil,
326 expectHTTPListener: false,
327 expectTLSListener: true,
328 }),
329 Entry("with a both a ipv6 valid http and ipv6 valid https bind address, and valid TLS config", &newServerTableInput{
330 opts: Opts{
331 Handler: handler,
332 BindAddress: "[::1]:0",
333 SecureBindAddress: "[::1]:0",
334 TLS: &options.TLS{
335 Key: &ipv6KeyDataSource,
336 Cert: &ipv6CertDataSource,
337 },
338 },
339 expectedErr: nil,
340 expectHTTPListener: true,
341 expectTLSListener: true,
342 }),
343 Entry("with an ipv6 invalid bind address scheme", &newServerTableInput{
344 opts: Opts{
345 Handler: handler,
346 BindAddress: "invalid://[::1]:0",
347 },
348 expectedErr: errors.New("error setting up listener: listen (invalid, [::1]:0) failed: listen invalid: unknown network invalid"),
349 expectHTTPListener: false,
350 expectTLSListener: false,
351 }),
352 Entry("with an ipv6 invalid secure bind address scheme", &newServerTableInput{
353 opts: Opts{
354 Handler: handler,
355 SecureBindAddress: "invalid://[::1]:0",
356 TLS: &options.TLS{
357 Key: &ipv6KeyDataSource,
358 Cert: &ipv6CertDataSource,
359 },
360 },
361 expectedErr: nil,
362 expectHTTPListener: false,
363 expectTLSListener: true,
364 }),
365 Entry("with an ipv6 invalid bind address port", &newServerTableInput{
366 opts: Opts{
367 Handler: handler,
368 BindAddress: "[::1]:a",
369 },
370 expectedErr: errors.New("error setting up listener: listen (tcp, [::1]:a) failed: listen tcp: "),
371 expectHTTPListener: false,
372 expectTLSListener: false,
373 }),
374 Entry("with an ipv6 invalid secure bind address port", &newServerTableInput{
375 opts: Opts{
376 Handler: handler,
377 SecureBindAddress: "[::1]:a",
378 TLS: &options.TLS{
379 Key: &ipv6KeyDataSource,
380 Cert: &ipv6CertDataSource,
381 },
382 },
383 expectedErr: errors.New("error setting up TLS listener: listen ([::1]:a) failed: listen tcp: "),
384 expectHTTPListener: false,
385 expectTLSListener: false,
386 }),
387 Entry("with an ipv6 invalid TLS key", &newServerTableInput{
388 opts: Opts{
389 Handler: handler,
390 SecureBindAddress: "[::1]:0",
391 TLS: &options.TLS{
392 Key: &options.SecretSource{
393 Value: []byte("invalid"),
394 },
395 Cert: &ipv6CertDataSource,
396 },
397 },
398 expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not parse certificate data: tls: failed to find any PEM data in key input"),
399 expectHTTPListener: false,
400 expectTLSListener: false,
401 }),
402 Entry("with an ipv6 invalid TLS cert", &newServerTableInput{
403 opts: Opts{
404 Handler: handler,
405 SecureBindAddress: "[::1]:0",
406 TLS: &options.TLS{
407 Key: &ipv6KeyDataSource,
408 Cert: &options.SecretSource{
409 Value: []byte("invalid"),
410 },
411 },
412 },
413 expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not parse certificate data: tls: failed to find any PEM data in certificate input"),
414 expectHTTPListener: false,
415 expectTLSListener: false,
416 }),
417 Entry("with an ipv6 address, with no TLS key", &newServerTableInput{
418 opts: Opts{
419 Handler: handler,
420 SecureBindAddress: "[::1]:0",
421 TLS: &options.TLS{
422 Cert: &ipv6CertDataSource,
423 },
424 },
425 expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not load key data: no configuration provided"),
426 expectHTTPListener: false,
427 expectTLSListener: false,
428 }),
429 Entry("with an ipv6 address, with no TLS cert", &newServerTableInput{
430 opts: Opts{
431 Handler: handler,
432 SecureBindAddress: "[::1]:0",
433 TLS: &options.TLS{
434 Key: &ipv6KeyDataSource,
435 },
436 },
437 expectedErr: errors.New("error setting up TLS listener: could not load certificate: could not load cert data: no configuration provided"),
438 expectHTTPListener: false,
439 expectTLSListener: false,
440 }),
441 Entry("when the ipv6 bind address is prefixed with the http scheme", &newServerTableInput{
442 opts: Opts{
443 Handler: handler,
444 BindAddress: "http://[::1]:0",
445 },
446 expectedErr: nil,
447 expectHTTPListener: true,
448 expectTLSListener: false,
449 }),
450 Entry("when the ipv6 secure bind address is prefixed with the https scheme", &newServerTableInput{
451 opts: Opts{
452 Handler: handler,
453 SecureBindAddress: "https://[::1]:0",
454 TLS: &options.TLS{
455 Key: &ipv6KeyDataSource,
456 Cert: &ipv6CertDataSource,
457 },
458 },
459 expectedErr: nil,
460 expectHTTPListener: false,
461 expectTLSListener: true,
462 }),
463 Entry("with an ipv6 valid https bind address, and valid TLS config with MinVersion", &newServerTableInput{
464 opts: Opts{
465 Handler: handler,
466 SecureBindAddress: "[::1]:0",
467 TLS: &options.TLS{
468 Key: &ipv6KeyDataSource,
469 Cert: &ipv6CertDataSource,
470 MinVersion: "TLS1.3",
471 },
472 },
473 expectedErr: nil,
474 expectHTTPListener: false,
475 expectTLSListener: true,
476 }),
477 Entry("with an ipv6 valid https bind address, and invalid TLS config with unknown MinVersion", &newServerTableInput{
478 opts: Opts{
479 Handler: handler,
480 SecureBindAddress: "[::1]:0",
481 TLS: &options.TLS{
482 Key: &ipv6KeyDataSource,
483 Cert: &ipv6CertDataSource,
484 MinVersion: "TLS1.42",
485 },
486 },
487 expectedErr: errors.New("error setting up TLS listener: unknown TLS MinVersion config provided"),
488 expectHTTPListener: false,
489 expectTLSListener: true,
490 }),
491 Entry("with an ipv6 valid https bind address, and valid TLS config with CipherSuites", &newServerTableInput{
492 opts: Opts{
493 Handler: handler,
494 SecureBindAddress: "[::1]:0",
495 TLS: &options.TLS{
496 Key: &ipv4KeyDataSource,
497 Cert: &ipv4CertDataSource,
498 CipherSuites: []string{
499 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
500 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
501 },
502 },
503 },
504 expectedErr: nil,
505 expectHTTPListener: false,
506 expectTLSListener: true,
507 }),
508 Entry("with an ipv6 valid https bind address, and invalid TLS config with unknown CipherSuites", &newServerTableInput{
509 opts: Opts{
510 Handler: handler,
511 SecureBindAddress: "[::1]:0",
512 TLS: &options.TLS{
513 Key: &ipv4KeyDataSource,
514 Cert: &ipv4CertDataSource,
515 CipherSuites: []string{
516 "TLS_RSA_WITH_RC4_64_SHA",
517 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
518 },
519 },
520 },
521 expectedErr: errors.New("error setting up TLS listener: could not parse cipher suites: unknown TLS cipher suite name specified \"TLS_RSA_WITH_RC4_64_SHA\""),
522 expectHTTPListener: false,
523 expectTLSListener: true,
524 }),
525 )
526 })
528 Context("Start", func() {
529 var srv Server
530 var ctx context.Context
531 var cancel context.CancelFunc
533 BeforeEach(func() {
534 ctx, cancel = context.WithCancel(context.Background())
535 })
537 AfterEach(func() {
538 cancel()
539 })
541 Context("with an ipv4 http server", func() {
542 var listenAddr string
544 BeforeEach(func() {
545 var err error
546 srv, err = NewServer(Opts{
547 Handler: handler,
548 BindAddress: "127.0.0.1:0",
549 })
550 Expect(err).ToNot(HaveOccurred())
552 s, ok := srv.(*server)
553 Expect(ok).To(BeTrue())
555 listenAddr = fmt.Sprintf("http://%s/", s.listener.Addr().String())
556 })
558 It("Starts the server and serves the handler", func() {
559 go func() {
560 defer GinkgoRecover()
561 Expect(srv.Start(ctx)).To(Succeed())
562 }()
564 resp, err := client.Get(listenAddr)
565 Expect(err).ToNot(HaveOccurred())
566 Expect(resp.StatusCode).To(Equal(http.StatusOK))
568 body, err := io.ReadAll(resp.Body)
569 Expect(err).ToNot(HaveOccurred())
570 Expect(string(body)).To(Equal(hello))
571 })
573 It("Stops the server when the context is cancelled", func() {
574 go func() {
575 defer GinkgoRecover()
576 Expect(srv.Start(ctx)).To(Succeed())
577 }()
579 _, err := client.Get(listenAddr)
580 Expect(err).ToNot(HaveOccurred())
582 cancel()
584 Eventually(func() error {
585 _, err := client.Get(listenAddr)
586 return err
587 }).Should(HaveOccurred())
588 })
589 })
591 Context("with an ipv4 https server", func() {
592 var secureListenAddr string
594 BeforeEach(func() {
595 var err error
596 srv, err = NewServer(Opts{
597 Handler: handler,
598 SecureBindAddress: "127.0.0.1:0",
599 TLS: &options.TLS{
600 Key: &ipv4KeyDataSource,
601 Cert: &ipv4CertDataSource,
602 },
603 })
604 Expect(err).ToNot(HaveOccurred())
606 s, ok := srv.(*server)
607 Expect(ok).To(BeTrue())
609 secureListenAddr = fmt.Sprintf("https://%s/", s.tlsListener.Addr().String())
610 })
612 It("Starts the server and serves the handler", func() {
613 go func() {
614 defer GinkgoRecover()
615 Expect(srv.Start(ctx)).To(Succeed())
616 }()
618 resp, err := client.Get(secureListenAddr)
619 Expect(err).ToNot(HaveOccurred())
620 Expect(resp.StatusCode).To(Equal(http.StatusOK))
622 body, err := io.ReadAll(resp.Body)
623 Expect(err).ToNot(HaveOccurred())
624 Expect(string(body)).To(Equal(hello))
625 })
627 It("Stops the server when the context is cancelled", func() {
628 go func() {
629 defer GinkgoRecover()
630 Expect(srv.Start(ctx)).To(Succeed())
631 }()
633 _, err := client.Get(secureListenAddr)
634 Expect(err).ToNot(HaveOccurred())
636 cancel()
638 Eventually(func() error {
639 _, err := client.Get(secureListenAddr)
640 return err
641 }).Should(HaveOccurred())
642 })
644 It("Serves the certificate provided", func() {
645 go func() {
646 defer GinkgoRecover()
647 Expect(srv.Start(ctx)).To(Succeed())
648 }()
650 resp, err := client.Get(secureListenAddr)
651 Expect(err).ToNot(HaveOccurred())
652 Expect(resp.StatusCode).To(Equal(http.StatusOK))
654 Expect(resp.TLS.VerifiedChains).Should(HaveLen(1))
655 Expect(resp.TLS.VerifiedChains[0]).Should(HaveLen(1))
656 Expect(resp.TLS.VerifiedChains[0][0].Raw).Should(Equal(ipv4CertData))
657 })
658 })
660 Context("with both an ipv4 http and an ipv4 https server", func() {
661 var listenAddr, secureListenAddr string
663 BeforeEach(func() {
664 var err error
665 srv, err = NewServer(Opts{
666 Handler: handler,
667 BindAddress: "127.0.0.1:0",
668 SecureBindAddress: "127.0.0.1:0",
669 TLS: &options.TLS{
670 Key: &ipv4KeyDataSource,
671 Cert: &ipv4CertDataSource,
672 },
673 })
674 Expect(err).ToNot(HaveOccurred())
676 s, ok := srv.(*server)
677 Expect(ok).To(BeTrue())
679 listenAddr = fmt.Sprintf("http://%s/", s.listener.Addr().String())
680 secureListenAddr = fmt.Sprintf("https://%s/", s.tlsListener.Addr().String())
681 })
683 It("Starts the server and serves the handler on http", func() {
684 go func() {
685 defer GinkgoRecover()
686 Expect(srv.Start(ctx)).To(Succeed())
687 }()
689 resp, err := client.Get(listenAddr)
690 Expect(err).ToNot(HaveOccurred())
691 Expect(resp.StatusCode).To(Equal(http.StatusOK))
693 body, err := io.ReadAll(resp.Body)
694 Expect(err).ToNot(HaveOccurred())
695 Expect(string(body)).To(Equal(hello))
696 })
698 It("Starts the server and serves the handler on https", func() {
699 go func() {
700 defer GinkgoRecover()
701 Expect(srv.Start(ctx)).To(Succeed())
702 }()
704 resp, err := client.Get(secureListenAddr)
705 Expect(err).ToNot(HaveOccurred())
706 Expect(resp.StatusCode).To(Equal(http.StatusOK))
708 body, err := io.ReadAll(resp.Body)
709 Expect(err).ToNot(HaveOccurred())
710 Expect(string(body)).To(Equal(hello))
711 })
713 It("Stops both servers when the context is cancelled", func() {
714 go func() {
715 defer GinkgoRecover()
716 Expect(srv.Start(ctx)).To(Succeed())
717 }()
719 _, err := client.Get(listenAddr)
720 Expect(err).ToNot(HaveOccurred())
721 _, err = client.Get(secureListenAddr)
722 Expect(err).ToNot(HaveOccurred())
724 cancel()
726 Eventually(func() error {
727 _, err := client.Get(listenAddr)
728 return err
729 }).Should(HaveOccurred())
730 Eventually(func() error {
731 _, err := client.Get(secureListenAddr)
732 return err
733 }).Should(HaveOccurred())
734 })
735 })
737 Context("with an ipv6 http server", func() {
738 var listenAddr string
740 BeforeEach(func() {
741 var err error
742 srv, err = NewServer(Opts{
743 Handler: handler,
744 BindAddress: "[::1]:0",
745 })
746 Expect(err).ToNot(HaveOccurred())
748 s, ok := srv.(*server)
749 Expect(ok).To(BeTrue())
751 listenAddr = fmt.Sprintf("http://%s/", s.listener.Addr().String())
752 })
754 It("Starts the server and serves the handler", func() {
755 go func() {
756 defer GinkgoRecover()
757 Expect(srv.Start(ctx)).To(Succeed())
758 }()
760 resp, err := client.Get(listenAddr)
761 Expect(err).ToNot(HaveOccurred())
762 Expect(resp.StatusCode).To(Equal(http.StatusOK))
764 body, err := io.ReadAll(resp.Body)
765 Expect(err).ToNot(HaveOccurred())
766 Expect(string(body)).To(Equal(hello))
767 })
769 It("Stops the server when the context is cancelled", func() {
770 go func() {
771 defer GinkgoRecover()
772 Expect(srv.Start(ctx)).To(Succeed())
773 }()
775 _, err := client.Get(listenAddr)
776 Expect(err).ToNot(HaveOccurred())
778 cancel()
780 Eventually(func() error {
781 _, err := client.Get(listenAddr)
782 return err
783 }).Should(HaveOccurred())
784 })
785 })
787 Context("with an ipv6 https server", func() {
788 var secureListenAddr string
790 BeforeEach(func() {
791 var err error
792 srv, err = NewServer(Opts{
793 Handler: handler,
794 SecureBindAddress: "[::1]:0",
795 TLS: &options.TLS{
796 Key: &ipv6KeyDataSource,
797 Cert: &ipv6CertDataSource,
798 },
799 })
800 Expect(err).ToNot(HaveOccurred())
802 s, ok := srv.(*server)
803 Expect(ok).To(BeTrue())
805 secureListenAddr = fmt.Sprintf("https://%s/", s.tlsListener.Addr().String())
806 })
808 It("Starts the server and serves the handler", func() {
809 go func() {
810 defer GinkgoRecover()
811 Expect(srv.Start(ctx)).To(Succeed())
812 }()
814 resp, err := client.Get(secureListenAddr)
815 Expect(err).ToNot(HaveOccurred())
816 Expect(resp.StatusCode).To(Equal(http.StatusOK))
818 body, err := io.ReadAll(resp.Body)
819 Expect(err).ToNot(HaveOccurred())
820 Expect(string(body)).To(Equal(hello))
821 })
823 It("Stops the server when the context is cancelled", func() {
824 go func() {
825 defer GinkgoRecover()
826 Expect(srv.Start(ctx)).To(Succeed())
827 }()
829 _, err := client.Get(secureListenAddr)
830 Expect(err).ToNot(HaveOccurred())
832 cancel()
834 Eventually(func() error {
835 _, err := client.Get(secureListenAddr)
836 return err
837 }).Should(HaveOccurred())
838 })
840 It("Serves the certificate provided", func() {
841 go func() {
842 defer GinkgoRecover()
843 Expect(srv.Start(ctx)).To(Succeed())
844 }()
846 resp, err := client.Get(secureListenAddr)
847 Expect(err).ToNot(HaveOccurred())
848 Expect(resp.StatusCode).To(Equal(http.StatusOK))
850 Expect(resp.TLS.VerifiedChains).Should(HaveLen(1))
851 Expect(resp.TLS.VerifiedChains[0]).Should(HaveLen(1))
852 Expect(resp.TLS.VerifiedChains[0][0].Raw).Should(Equal(ipv6CertData))
853 })
854 })
856 Context("with both an ipv6 http and an ipv6 https server", func() {
857 var listenAddr, secureListenAddr string
859 BeforeEach(func() {
860 var err error
861 srv, err = NewServer(Opts{
862 Handler: handler,
863 BindAddress: "[::1]:0",
864 SecureBindAddress: "[::1]:0",
865 TLS: &options.TLS{
866 Key: &ipv6KeyDataSource,
867 Cert: &ipv6CertDataSource,
868 },
869 })
870 Expect(err).ToNot(HaveOccurred())
872 s, ok := srv.(*server)
873 Expect(ok).To(BeTrue())
875 listenAddr = fmt.Sprintf("http://%s/", s.listener.Addr().String())
876 secureListenAddr = fmt.Sprintf("https://%s/", s.tlsListener.Addr().String())
877 })
879 It("Starts the server and serves the handler on http", func() {
880 go func() {
881 defer GinkgoRecover()
882 Expect(srv.Start(ctx)).To(Succeed())
883 }()
885 resp, err := client.Get(listenAddr)
886 Expect(err).ToNot(HaveOccurred())
887 Expect(resp.StatusCode).To(Equal(http.StatusOK))
889 body, err := io.ReadAll(resp.Body)
890 Expect(err).ToNot(HaveOccurred())
891 Expect(string(body)).To(Equal(hello))
892 })
894 It("Starts the server and serves the handler on https", func() {
895 go func() {
896 defer GinkgoRecover()
897 Expect(srv.Start(ctx)).To(Succeed())
898 }()
900 resp, err := client.Get(secureListenAddr)
901 Expect(err).ToNot(HaveOccurred())
902 Expect(resp.StatusCode).To(Equal(http.StatusOK))
904 body, err := io.ReadAll(resp.Body)
905 Expect(err).ToNot(HaveOccurred())
906 Expect(string(body)).To(Equal(hello))
907 })
909 It("Stops both servers when the context is cancelled", func() {
910 go func() {
911 defer GinkgoRecover()
912 Expect(srv.Start(ctx)).To(Succeed())
913 }()
915 _, err := client.Get(listenAddr)
916 Expect(err).ToNot(HaveOccurred())
917 _, err = client.Get(secureListenAddr)
918 Expect(err).ToNot(HaveOccurred())
920 cancel()
922 Eventually(func() error {
923 _, err := client.Get(listenAddr)
924 return err
925 }).Should(HaveOccurred())
926 Eventually(func() error {
927 _, err := client.Get(secureListenAddr)
928 return err
929 }).Should(HaveOccurred())
930 })
931 })
932 })
934 Context("getNetworkScheme", func() {
935 DescribeTable("should return the scheme", func(in, expected string) {
936 Expect(getNetworkScheme(in)).To(Equal(expected))
937 },
938 Entry("ipv4 address with no scheme", "127.0.0.1:0", "tcp"),
939 Entry("ipv4 address with a tcp scheme", "tcp://127.0.0.1:0", "tcp"),
940 Entry("ipv4 address with a http scheme", "http://192.168.0.1:1", "tcp"),
941 Entry("ipv4 address with a unix scheme", "unix://172.168.16.2:2", "unix"),
942 Entry("ipv4 address with a random scheme", "random://10.10.10.10:10", "random"),
943 Entry("ipv6 address with no scheme", "[::1]:0", "tcp"),
944 Entry("ipv6 address with a tcp scheme", "tcp://[::1]:0", "tcp"),
945 Entry("ipv6 address with a http scheme", "http://[::ffff:c0a8:1]:1", "tcp"),
946 Entry("ipv6 address with a unix scheme", "unix://[::ffff:aca8:1002]:2", "unix"),
947 Entry("ipv6 address with a random scheme", "random://[::ffff:a0a:a0a]:10", "random"),
948 )
949 })
951 Context("getListenAddress", func() {
952 DescribeTable("should remove the scheme", func(in, expected string) {
953 Expect(getListenAddress(in)).To(Equal(expected))
954 },
955 Entry("ipv4 address with no scheme", "127.0.0.1:0", "127.0.0.1:0"),
956 Entry("ipv4 address with a tcp scheme", "tcp://127.0.0.1:0", "127.0.0.1:0"),
957 Entry("ipv4 address with a http scheme", "http://192.168.0.1:1", "192.168.0.1:1"),
958 Entry("ipv4 address with a unix scheme", "unix://172.168.16.2:2", "172.168.16.2:2"),
959 Entry("ipv4 address with a random scheme", "random://10.10.10.10:10", "10.10.10.10:10"),
960 Entry("ipv6 address with no scheme", "[::1]:0", "[::1]:0"),
961 Entry("ipv6 address with a tcp scheme", "tcp://[::1]:0", "[::1]:0"),
962 Entry("ipv6 address with a http scheme", "http://[::ffff:c0a8:1]:1", "[::ffff:c0a8:1]:1"),
963 Entry("ipv6 address with a unix scheme", "unix://[::ffff:aca8:1002]:2", "[::ffff:aca8:1002]:2"),
964 Entry("ipv6 address with a random scheme", "random://[::ffff:a0a:a0a]:10", "[::ffff:a0a:a0a]:10"),
965 )
966 })
967})