Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Łukasz Nowak
caddy
Commits
036633b6
Commit
036633b6
authored
8 years ago
by
Matt Holt
Committed by
GitHub
8 years ago
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1174 from tw4452852/1173
header: implement http.Hijacker for responseWriterWrapper
parents
d44016b9
550b1170
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
97 additions
and
9 deletions
+97
-9
caddyhttp/gzip/gzip.go
caddyhttp/gzip/gzip.go
+3
-4
caddyhttp/header/header.go
caddyhttp/header/header.go
+11
-0
caddyhttp/httpserver/error.go
caddyhttp/httpserver/error.go
+44
-0
caddyhttp/httpserver/recorder.go
caddyhttp/httpserver/recorder.go
+3
-4
caddyhttp/proxy/proxy_test.go
caddyhttp/proxy/proxy_test.go
+33
-0
caddyhttp/proxy/reverseproxy.go
caddyhttp/proxy/reverseproxy.go
+3
-1
No files found.
caddyhttp/gzip/gzip.go
View file @
036633b6
...
...
@@ -5,7 +5,6 @@ package gzip
import
(
"bufio"
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"net"
...
...
@@ -144,7 +143,7 @@ func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
if
hj
,
ok
:=
w
.
ResponseWriter
.
(
http
.
Hijacker
);
ok
{
return
hj
.
Hijack
()
}
return
nil
,
nil
,
fmt
.
Errorf
(
"not a Hijacker"
)
return
nil
,
nil
,
httpserver
.
NonHijackerError
{
Underlying
:
w
.
ResponseWriter
}
}
// Flush implements http.Flusher. It simply wraps the underlying
...
...
@@ -153,7 +152,7 @@ func (w *gzipResponseWriter) Flush() {
if
f
,
ok
:=
w
.
ResponseWriter
.
(
http
.
Flusher
);
ok
{
f
.
Flush
()
}
else
{
panic
(
"not a Flusher"
)
// should be recovered at the beginning of middleware stack
panic
(
httpserver
.
NonFlusherError
{
Underlying
:
w
.
ResponseWriter
}
)
// should be recovered at the beginning of middleware stack
}
}
...
...
@@ -163,5 +162,5 @@ func (w *gzipResponseWriter) CloseNotify() <-chan bool {
if
cn
,
ok
:=
w
.
ResponseWriter
.
(
http
.
CloseNotifier
);
ok
{
return
cn
.
CloseNotify
()
}
panic
(
"not a CloseNotifier"
)
panic
(
httpserver
.
NonCloseNotifierError
{
Underlying
:
w
.
ResponseWriter
}
)
}
This diff is collapsed.
Click to expand it.
caddyhttp/header/header.go
View file @
036633b6
...
...
@@ -4,6 +4,8 @@
package
header
import
(
"bufio"
"net"
"net/http"
"strings"
...
...
@@ -113,3 +115,12 @@ func (rww *responseWriterWrapper) setHeader(key, value string) {
h
.
Set
(
key
,
value
)
})
}
// Hijack implements http.Hijacker. It simply wraps the underlying
// ResponseWriter's Hijack method if there is one, or returns an error.
func
(
rww
*
responseWriterWrapper
)
Hijack
()
(
net
.
Conn
,
*
bufio
.
ReadWriter
,
error
)
{
if
hj
,
ok
:=
rww
.
w
.
(
http
.
Hijacker
);
ok
{
return
hj
.
Hijack
()
}
return
nil
,
nil
,
httpserver
.
NonHijackerError
{
Underlying
:
rww
.
w
}
}
This diff is collapsed.
Click to expand it.
caddyhttp/httpserver/error.go
0 → 100644
View file @
036633b6
package
httpserver
import
(
"fmt"
)
var
(
_
error
=
NonHijackerError
{}
_
error
=
NonFlusherError
{}
_
error
=
NonCloseNotifierError
{}
)
// NonHijackerError is more descriptive error caused by a non hijacker
type
NonHijackerError
struct
{
// underlying type which doesn't implement Hijack
Underlying
interface
{}
}
// Implement Error
func
(
h
NonHijackerError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"%T is not a hijacker"
,
h
.
Underlying
)
}
// NonFlusherError is more descriptive error caused by a non flusher
type
NonFlusherError
struct
{
// underlying type which doesn't implement Flush
Underlying
interface
{}
}
// Implement Error
func
(
f
NonFlusherError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"%T is not a flusher"
,
f
.
Underlying
)
}
// NonCloseNotifierError is more descriptive error caused by a non closeNotifier
type
NonCloseNotifierError
struct
{
// underlying type which doesn't implement CloseNotify
Underlying
interface
{}
}
// Implement Error
func
(
c
NonCloseNotifierError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"%T is not a closeNotifier"
,
c
.
Underlying
)
}
This diff is collapsed.
Click to expand it.
caddyhttp/httpserver/recorder.go
View file @
036633b6
...
...
@@ -2,7 +2,6 @@ package httpserver
import
(
"bufio"
"errors"
"net"
"net/http"
"time"
...
...
@@ -75,7 +74,7 @@ func (r *ResponseRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error) {
if
hj
,
ok
:=
r
.
ResponseWriter
.
(
http
.
Hijacker
);
ok
{
return
hj
.
Hijack
()
}
return
nil
,
nil
,
errors
.
New
(
"not a Hijacker"
)
return
nil
,
nil
,
NonHijackerError
{
Underlying
:
r
.
ResponseWriter
}
}
// Flush implements http.Flusher. It simply wraps the underlying
...
...
@@ -84,7 +83,7 @@ func (r *ResponseRecorder) Flush() {
if
f
,
ok
:=
r
.
ResponseWriter
.
(
http
.
Flusher
);
ok
{
f
.
Flush
()
}
else
{
panic
(
"not a Flusher"
)
// should be recovered at the beginning of middleware stack
panic
(
NonFlusherError
{
Underlying
:
r
.
ResponseWriter
}
)
// should be recovered at the beginning of middleware stack
}
}
...
...
@@ -94,5 +93,5 @@ func (r *ResponseRecorder) CloseNotify() <-chan bool {
if
cn
,
ok
:=
r
.
ResponseWriter
.
(
http
.
CloseNotifier
);
ok
{
return
cn
.
CloseNotify
()
}
panic
(
"not a CloseNotifier"
)
panic
(
NonCloseNotifierError
{
Underlying
:
r
.
ResponseWriter
}
)
}
This diff is collapsed.
Click to expand it.
caddyhttp/proxy/proxy_test.go
View file @
036633b6
...
...
@@ -97,6 +97,39 @@ func TestReverseProxyInsecureSkipVerify(t *testing.T) {
}
}
func
TestWebSocketReverseProxyNonHijackerPanic
(
t
*
testing
.
T
)
{
// Capture the expected panic
defer
func
()
{
r
:=
recover
()
if
_
,
ok
:=
r
.
(
httpserver
.
NonHijackerError
);
!
ok
{
t
.
Error
(
"not get the expected panic"
)
}
}()
var
connCount
int32
wsNop
:=
httptest
.
NewServer
(
websocket
.
Handler
(
func
(
ws
*
websocket
.
Conn
)
{
atomic
.
AddInt32
(
&
connCount
,
1
)
}))
defer
wsNop
.
Close
()
// Get proxy to use for the test
p
:=
newWebSocketTestProxy
(
wsNop
.
URL
)
// Create client request
r
,
err
:=
http
.
NewRequest
(
"GET"
,
"/"
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"Failed to create request: %v"
,
err
)
}
r
.
Header
=
http
.
Header
{
"Connection"
:
{
"Upgrade"
},
"Upgrade"
:
{
"websocket"
},
"Origin"
:
{
wsNop
.
URL
},
"Sec-WebSocket-Key"
:
{
"x3JJHMbDL1EzLkh9GBhXDw=="
},
"Sec-WebSocket-Version"
:
{
"13"
},
}
nonHijacker
:=
httptest
.
NewRecorder
()
p
.
ServeHTTP
(
nonHijacker
,
r
)
}
func
TestWebSocketReverseProxyServeHTTPHandler
(
t
*
testing
.
T
)
{
// No-op websocket backend simply allows the WS connection to be
// accepted then it will be immediately closed. Perfect for testing.
...
...
This diff is collapsed.
Click to expand it.
caddyhttp/proxy/reverseproxy.go
View file @
036633b6
...
...
@@ -21,6 +21,8 @@ import (
"strings"
"sync"
"time"
"github.com/mholt/caddy/caddyhttp/httpserver"
)
var
bufferPool
=
sync
.
Pool
{
New
:
createBuffer
}
...
...
@@ -195,7 +197,7 @@ func (rp *ReverseProxy) ServeHTTP(rw http.ResponseWriter, outreq *http.Request,
res
.
Body
.
Close
()
hj
,
ok
:=
rw
.
(
http
.
Hijacker
)
if
!
ok
{
return
nil
panic
(
httpserver
.
NonHijackerError
{
Underlying
:
rw
})
}
conn
,
_
,
err
:=
hj
.
Hijack
()
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment