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
nexedi
caddy
Commits
e363491a
Commit
e363491a
authored
Dec 07, 2016
by
Matt Holt
Committed by
GitHub
Dec 07, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1284 from mholt/fastcgi-send-timeout
Add send_timeout property to fastcgi directive
parents
b0685a64
9f16ac84
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
220 additions
and
79 deletions
+220
-79
caddyhttp/fastcgi/dialer.go
caddyhttp/fastcgi/dialer.go
+6
-3
caddyhttp/fastcgi/fastcgi.go
caddyhttp/fastcgi/fastcgi.go
+15
-4
caddyhttp/fastcgi/fastcgi_test.go
caddyhttp/fastcgi/fastcgi_test.go
+112
-26
caddyhttp/fastcgi/fcgiclient.go
caddyhttp/fastcgi/fcgiclient.go
+28
-44
caddyhttp/fastcgi/fcgiclient_test.go
caddyhttp/fastcgi/fcgiclient_test.go
+1
-1
caddyhttp/fastcgi/setup.go
caddyhttp/fastcgi/setup.go
+10
-1
caddyhttp/fastcgi/setup_test.go
caddyhttp/fastcgi/setup_test.go
+48
-0
No files found.
caddyhttp/fastcgi/dialer.go
View file @
e363491a
...
@@ -19,8 +19,11 @@ type basicDialer struct {
...
@@ -19,8 +19,11 @@ type basicDialer struct {
timeout
time
.
Duration
timeout
time
.
Duration
}
}
func
(
b
basicDialer
)
Dial
()
(
Client
,
error
)
{
return
Dial
(
b
.
network
,
b
.
address
,
b
.
timeout
)
}
func
(
b
basicDialer
)
Dial
()
(
Client
,
error
)
{
func
(
b
basicDialer
)
Close
(
c
Client
)
error
{
return
c
.
Close
()
}
return
DialTimeout
(
b
.
network
,
b
.
address
,
b
.
timeout
)
}
func
(
b
basicDialer
)
Close
(
c
Client
)
error
{
return
c
.
Close
()
}
// persistentDialer keeps a pool of fcgi connections.
// persistentDialer keeps a pool of fcgi connections.
// connections are not closed after use, rather added back to the pool for reuse.
// connections are not closed after use, rather added back to the pool for reuse.
...
@@ -47,7 +50,7 @@ func (p *persistentDialer) Dial() (Client, error) {
...
@@ -47,7 +50,7 @@ func (p *persistentDialer) Dial() (Client, error) {
p
.
Unlock
()
p
.
Unlock
()
// no connection available, create new one
// no connection available, create new one
return
Dial
(
p
.
network
,
p
.
address
,
p
.
timeout
)
return
Dial
Timeout
(
p
.
network
,
p
.
address
,
p
.
timeout
)
}
}
func
(
p
*
persistentDialer
)
Close
(
client
Client
)
error
{
func
(
p
*
persistentDialer
)
Close
(
client
Client
)
error
{
...
...
caddyhttp/fastcgi/fastcgi.go
View file @
e363491a
...
@@ -6,6 +6,7 @@ package fastcgi
...
@@ -6,6 +6,7 @@ package fastcgi
import
(
import
(
"errors"
"errors"
"io"
"io"
"net"
"net/http"
"net/http"
"os"
"os"
"path"
"path"
...
@@ -80,9 +81,14 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
...
@@ -80,9 +81,14 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
// Connect to FastCGI gateway
// Connect to FastCGI gateway
fcgiBackend
,
err
:=
rule
.
dialer
.
Dial
()
fcgiBackend
,
err
:=
rule
.
dialer
.
Dial
()
if
err
!=
nil
{
if
err
!=
nil
{
if
err
,
ok
:=
err
.
(
net
.
Error
);
ok
&&
err
.
Timeout
()
{
return
http
.
StatusGatewayTimeout
,
err
}
return
http
.
StatusBadGateway
,
err
return
http
.
StatusBadGateway
,
err
}
}
defer
fcgiBackend
.
Close
()
fcgiBackend
.
SetReadTimeout
(
rule
.
ReadTimeout
)
fcgiBackend
.
SetReadTimeout
(
rule
.
ReadTimeout
)
fcgiBackend
.
SetSendTimeout
(
rule
.
SendTimeout
)
var
resp
*
http
.
Response
var
resp
*
http
.
Response
contentLength
,
_
:=
strconv
.
Atoi
(
r
.
Header
.
Get
(
"Content-Length"
))
contentLength
,
_
:=
strconv
.
Atoi
(
r
.
Header
.
Get
(
"Content-Length"
))
...
@@ -97,8 +103,12 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
...
@@ -97,8 +103,12 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
resp
,
err
=
fcgiBackend
.
Post
(
env
,
r
.
Method
,
r
.
Header
.
Get
(
"Content-Type"
),
r
.
Body
,
contentLength
)
resp
,
err
=
fcgiBackend
.
Post
(
env
,
r
.
Method
,
r
.
Header
.
Get
(
"Content-Type"
),
r
.
Body
,
contentLength
)
}
}
if
err
!=
nil
&&
err
!=
io
.
EOF
{
if
err
!=
nil
{
return
http
.
StatusBadGateway
,
err
if
err
,
ok
:=
err
.
(
net
.
Error
);
ok
&&
err
.
Timeout
()
{
return
http
.
StatusGatewayTimeout
,
err
}
else
if
err
!=
io
.
EOF
{
return
http
.
StatusBadGateway
,
err
}
}
}
// Write response header
// Write response header
...
@@ -110,8 +120,6 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
...
@@ -110,8 +120,6 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
return
http
.
StatusBadGateway
,
err
return
http
.
StatusBadGateway
,
err
}
}
defer
rule
.
dialer
.
Close
(
fcgiBackend
)
// Log any stderr output from upstream
// Log any stderr output from upstream
if
stderr
:=
fcgiBackend
.
StdErr
();
stderr
.
Len
()
!=
0
{
if
stderr
:=
fcgiBackend
.
StdErr
();
stderr
.
Len
()
!=
0
{
// Remove trailing newline, error logger already does this.
// Remove trailing newline, error logger already does this.
...
@@ -306,6 +314,9 @@ type Rule struct {
...
@@ -306,6 +314,9 @@ type Rule struct {
// The duration used to set a deadline when reading from the FastCGI server.
// The duration used to set a deadline when reading from the FastCGI server.
ReadTimeout
time
.
Duration
ReadTimeout
time
.
Duration
// The duration used to set a deadline when sending to the FastCGI server.
SendTimeout
time
.
Duration
// FCGI dialer
// FCGI dialer
dialer
dialer
dialer
dialer
}
}
...
...
caddyhttp/fastcgi/fastcgi_test.go
View file @
e363491a
...
@@ -327,38 +327,124 @@ func TestBuildEnv(t *testing.T) {
...
@@ -327,38 +327,124 @@ func TestBuildEnv(t *testing.T) {
}
}
func
TestReadTimeout
(
t
*
testing
.
T
)
{
func
TestReadTimeout
(
t
*
testing
.
T
)
{
listener
,
err
:=
net
.
Listen
(
"tcp"
,
"127.0.0.1:0"
)
tests
:=
[]
struct
{
if
err
!=
nil
{
sleep
time
.
Duration
t
.
Fatalf
(
"Unable to create listener for test: %v"
,
err
)
readTimeout
time
.
Duration
shouldErr
bool
}{
{
75
*
time
.
Millisecond
,
50
*
time
.
Millisecond
,
true
},
{
0
,
-
1
*
time
.
Second
,
true
},
{
0
,
time
.
Minute
,
false
},
}
}
defer
listener
.
Close
()
network
,
address
:=
parseAddress
(
listener
.
Addr
()
.
String
())
var
wg
sync
.
WaitGroup
handler
:=
Handler
{
Next
:
nil
,
for
i
,
test
:=
range
tests
{
Rules
:
[]
Rule
{
listener
,
err
:=
net
.
Listen
(
"tcp"
,
"127.0.0.1:0"
)
{
if
err
!=
nil
{
Path
:
"/"
,
t
.
Fatalf
(
"Test %d: Unable to create listener for test: %v"
,
i
,
err
)
Address
:
listener
.
Addr
()
.
String
(),
}
dialer
:
basicDialer
{
network
:
network
,
address
:
address
},
defer
listener
.
Close
()
ReadTimeout
:
time
.
Millisecond
*
100
,
network
,
address
:=
parseAddress
(
listener
.
Addr
()
.
String
())
handler
:=
Handler
{
Next
:
nil
,
Rules
:
[]
Rule
{
{
Path
:
"/"
,
Address
:
listener
.
Addr
()
.
String
(),
dialer
:
basicDialer
{
network
:
network
,
address
:
address
},
ReadTimeout
:
test
.
readTimeout
,
},
},
},
},
}
r
,
err
:=
http
.
NewRequest
(
"GET"
,
"/"
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"Test %d: Unable to create request: %v"
,
i
,
err
)
}
w
:=
httptest
.
NewRecorder
()
wg
.
Add
(
1
)
go
fcgi
.
Serve
(
listener
,
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
time
.
Sleep
(
test
.
sleep
)
w
.
WriteHeader
(
http
.
StatusOK
)
wg
.
Done
()
}))
got
,
err
:=
handler
.
ServeHTTP
(
w
,
r
)
if
test
.
shouldErr
{
if
err
==
nil
{
t
.
Errorf
(
"Test %d: Expected i/o timeout error but had none"
,
i
)
}
else
if
err
,
ok
:=
err
.
(
net
.
Error
);
!
ok
||
!
err
.
Timeout
()
{
t
.
Errorf
(
"Test %d: Expected i/o timeout error, got: '%s'"
,
i
,
err
.
Error
())
}
want
:=
http
.
StatusGatewayTimeout
if
got
!=
want
{
t
.
Errorf
(
"Test %d: Expected returned status code to be %d, got: %d"
,
i
,
want
,
got
)
}
}
else
if
err
!=
nil
{
t
.
Errorf
(
"Test %d: Expected nil error, got: %v"
,
i
,
err
)
}
wg
.
Wait
()
}
}
r
,
err
:=
http
.
NewRequest
(
"GET"
,
"/"
,
nil
)
}
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to create request: %v"
,
err
)
func
TestSendTimeout
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
sendTimeout
time
.
Duration
shouldErr
bool
}{
{
-
1
*
time
.
Second
,
true
},
{
time
.
Minute
,
false
},
}
}
w
:=
httptest
.
NewRecorder
()
go
fcgi
.
Serve
(
listener
,
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
for
i
,
test
:=
range
tests
{
time
.
Sleep
(
time
.
Millisecond
*
130
)
listener
,
err
:=
net
.
Listen
(
"tcp"
,
"127.0.0.1:0"
)
}))
if
err
!=
nil
{
t
.
Fatalf
(
"Test %d: Unable to create listener for test: %v"
,
i
,
err
)
}
defer
listener
.
Close
()
_
,
err
=
handler
.
ServeHTTP
(
w
,
r
)
network
,
address
:=
parseAddress
(
listener
.
Addr
()
.
String
())
if
err
==
nil
{
handler
:=
Handler
{
t
.
Error
(
"Expected i/o timeout error but had none"
)
Next
:
nil
,
}
else
if
err
,
ok
:=
err
.
(
net
.
Error
);
!
ok
||
!
err
.
Timeout
()
{
Rules
:
[]
Rule
{
t
.
Errorf
(
"Expected i/o timeout error, got: '%s'"
,
err
.
Error
())
{
Path
:
"/"
,
Address
:
listener
.
Addr
()
.
String
(),
dialer
:
basicDialer
{
network
:
network
,
address
:
address
},
SendTimeout
:
test
.
sendTimeout
,
},
},
}
r
,
err
:=
http
.
NewRequest
(
"GET"
,
"/"
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"Test %d: Unable to create request: %v"
,
i
,
err
)
}
w
:=
httptest
.
NewRecorder
()
go
fcgi
.
Serve
(
listener
,
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
WriteHeader
(
http
.
StatusOK
)
}))
got
,
err
:=
handler
.
ServeHTTP
(
w
,
r
)
if
test
.
shouldErr
{
if
err
==
nil
{
t
.
Errorf
(
"Test %d: Expected i/o timeout error but had none"
,
i
)
}
else
if
err
,
ok
:=
err
.
(
net
.
Error
);
!
ok
||
!
err
.
Timeout
()
{
t
.
Errorf
(
"Test %d: Expected i/o timeout error, got: '%s'"
,
i
,
err
.
Error
())
}
want
:=
http
.
StatusGatewayTimeout
if
got
!=
want
{
t
.
Errorf
(
"Test %d: Expected returned status code to be %d, got: %d"
,
i
,
want
,
got
)
}
}
else
if
err
!=
nil
{
t
.
Errorf
(
"Test %d: Expected nil error, got: %v"
,
i
,
err
)
}
}
}
}
}
caddyhttp/fastcgi/fcgiclient.go
View file @
e363491a
...
@@ -15,7 +15,6 @@ import (
...
@@ -15,7 +15,6 @@ import (
"bytes"
"bytes"
"encoding/binary"
"encoding/binary"
"errors"
"errors"
"fmt"
"io"
"io"
"io/ioutil"
"io/ioutil"
"mime/multipart"
"mime/multipart"
...
@@ -116,8 +115,8 @@ type Client interface {
...
@@ -116,8 +115,8 @@ type Client interface {
Post
(
pairs
map
[
string
]
string
,
method
string
,
bodyType
string
,
body
io
.
Reader
,
contentLength
int
)
(
response
*
http
.
Response
,
err
error
)
Post
(
pairs
map
[
string
]
string
,
method
string
,
bodyType
string
,
body
io
.
Reader
,
contentLength
int
)
(
response
*
http
.
Response
,
err
error
)
Close
()
error
Close
()
error
StdErr
()
bytes
.
Buffer
StdErr
()
bytes
.
Buffer
ReadTimeout
()
time
.
Duration
SetReadTimeout
(
time
.
Duration
)
error
SetReadTimeout
(
time
.
Duration
)
error
SetSendTimeout
(
time
.
Duration
)
error
}
}
type
header
struct
{
type
header
struct
{
...
@@ -174,57 +173,32 @@ func (rec *record) read(r io.Reader) (buf []byte, err error) {
...
@@ -174,57 +173,32 @@ func (rec *record) read(r io.Reader) (buf []byte, err error) {
// interfacing external applications with Web servers.
// interfacing external applications with Web servers.
type
FCGIClient
struct
{
type
FCGIClient
struct
{
mutex
sync
.
Mutex
mutex
sync
.
Mutex
rwc
io
.
ReadWriteCloser
conn
net
.
Conn
h
header
h
header
buf
bytes
.
Buffer
buf
bytes
.
Buffer
stderr
bytes
.
Buffer
stderr
bytes
.
Buffer
keepAlive
bool
keepAlive
bool
reqID
uint16
reqID
uint16
readTimeout
time
.
Duration
readTimeout
time
.
Duration
sendTimeout
time
.
Duration
}
}
// Dial
WithDialer connects to the fcgi responder at the specified network address, using custom
net.Dialer.
// Dial
Timeout connects to the fcgi responder at the specified network address, using default
net.Dialer.
// See func net.Dial for a description of the network and address parameters.
// See func net.Dial for a description of the network and address parameters.
func
DialWithDialer
(
network
,
address
string
,
dialer
net
.
Dialer
)
(
fcgi
*
FCGIClient
,
err
error
)
{
func
DialTimeout
(
network
string
,
address
string
,
timeout
time
.
Duration
)
(
fcgi
*
FCGIClient
,
err
error
)
{
var
conn
net
.
Conn
conn
,
err
:=
net
.
DialTimeout
(
network
,
address
,
timeout
)
conn
,
err
=
dialer
.
Dial
(
network
,
address
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
fcgi
=
&
FCGIClient
{
fcgi
=
&
FCGIClient
{
conn
:
conn
,
keepAlive
:
false
,
reqID
:
1
}
rwc
:
conn
,
keepAlive
:
false
,
reqID
:
1
,
}
return
}
// Dial connects to the fcgi responder at the specified network address, using default net.Dialer.
return
fcgi
,
nil
// See func net.Dial for a description of the network and address parameters.
func
Dial
(
network
string
,
address
string
,
timeout
time
.
Duration
)
(
fcgi
*
FCGIClient
,
err
error
)
{
return
DialWithDialer
(
network
,
address
,
net
.
Dialer
{
Timeout
:
timeout
})
}
}
// Close closes fcgi connnection.
// Close closes fcgi connnection.
func
(
c
*
FCGIClient
)
Close
()
error
{
func
(
c
*
FCGIClient
)
Close
()
error
{
return
c
.
rwc
.
Close
()
return
c
.
conn
.
Close
()
}
// setReadDeadline sets a read deadline on FCGIClient based on the configured
// readTimeout. A zero value for readTimeout means no deadline will be set.
func
(
c
*
FCGIClient
)
setReadDeadline
()
error
{
if
c
.
readTimeout
>
0
{
conn
,
ok
:=
c
.
rwc
.
(
net
.
Conn
)
if
ok
{
conn
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
c
.
readTimeout
))
}
else
{
return
fmt
.
Errorf
(
"Could not set Client ReadTimeout"
)
}
}
return
nil
}
}
func
(
c
*
FCGIClient
)
writeRecord
(
recType
uint8
,
content
[]
byte
)
error
{
func
(
c
*
FCGIClient
)
writeRecord
(
recType
uint8
,
content
[]
byte
)
error
{
...
@@ -245,7 +219,13 @@ func (c *FCGIClient) writeRecord(recType uint8, content []byte) error {
...
@@ -245,7 +219,13 @@ func (c *FCGIClient) writeRecord(recType uint8, content []byte) error {
return
err
return
err
}
}
if
_
,
err
:=
c
.
rwc
.
Write
(
c
.
buf
.
Bytes
());
err
!=
nil
{
if
c
.
sendTimeout
!=
0
{
if
err
:=
c
.
conn
.
SetWriteDeadline
(
time
.
Now
()
.
Add
(
c
.
sendTimeout
));
err
!=
nil
{
return
err
}
}
if
_
,
err
:=
c
.
conn
.
Write
(
c
.
buf
.
Bytes
());
err
!=
nil
{
return
err
return
err
}
}
...
@@ -369,7 +349,7 @@ func (w *streamReader) Read(p []byte) (n int, err error) {
...
@@ -369,7 +349,7 @@ func (w *streamReader) Read(p []byte) (n int, err error) {
for
{
for
{
rec
:=
&
record
{}
rec
:=
&
record
{}
var
buf
[]
byte
var
buf
[]
byte
buf
,
err
=
rec
.
read
(
w
.
c
.
rwc
)
buf
,
err
=
rec
.
read
(
w
.
c
.
conn
)
if
err
==
errInvalidHeaderVersion
{
if
err
==
errInvalidHeaderVersion
{
continue
continue
}
else
if
err
!=
nil
{
}
else
if
err
!=
nil
{
...
@@ -436,7 +416,6 @@ func (c clientCloser) Close() error { return c.f.Close() }
...
@@ -436,7 +416,6 @@ func (c clientCloser) Close() error { return c.f.Close() }
// Request returns a HTTP Response with Header and Body
// Request returns a HTTP Response with Header and Body
// from fcgi responder
// from fcgi responder
func
(
c
*
FCGIClient
)
Request
(
p
map
[
string
]
string
,
req
io
.
Reader
)
(
resp
*
http
.
Response
,
err
error
)
{
func
(
c
*
FCGIClient
)
Request
(
p
map
[
string
]
string
,
req
io
.
Reader
)
(
resp
*
http
.
Response
,
err
error
)
{
r
,
err
:=
c
.
Do
(
p
,
req
)
r
,
err
:=
c
.
Do
(
p
,
req
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
...
@@ -446,8 +425,10 @@ func (c *FCGIClient) Request(p map[string]string, req io.Reader) (resp *http.Res
...
@@ -446,8 +425,10 @@ func (c *FCGIClient) Request(p map[string]string, req io.Reader) (resp *http.Res
tp
:=
textproto
.
NewReader
(
rb
)
tp
:=
textproto
.
NewReader
(
rb
)
resp
=
new
(
http
.
Response
)
resp
=
new
(
http
.
Response
)
if
err
=
c
.
setReadDeadline
();
err
!=
nil
{
if
c
.
readTimeout
!=
0
{
return
if
err
=
c
.
conn
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
c
.
readTimeout
));
err
!=
nil
{
return
}
}
}
// Parse the response headers.
// Parse the response headers.
...
@@ -582,10 +563,6 @@ func (c *FCGIClient) PostFile(p map[string]string, data url.Values, file map[str
...
@@ -582,10 +563,6 @@ func (c *FCGIClient) PostFile(p map[string]string, data url.Values, file map[str
return
c
.
Post
(
p
,
"POST"
,
bodyType
,
buf
,
buf
.
Len
())
return
c
.
Post
(
p
,
"POST"
,
bodyType
,
buf
,
buf
.
Len
())
}
}
// ReadTimeout returns the read timeout for future calls that read from the
// fcgi responder.
func
(
c
*
FCGIClient
)
ReadTimeout
()
time
.
Duration
{
return
c
.
readTimeout
}
// SetReadTimeout sets the read timeout for future calls that read from the
// SetReadTimeout sets the read timeout for future calls that read from the
// fcgi responder. A zero value for t means no timeout will be set.
// fcgi responder. A zero value for t means no timeout will be set.
func
(
c
*
FCGIClient
)
SetReadTimeout
(
t
time
.
Duration
)
error
{
func
(
c
*
FCGIClient
)
SetReadTimeout
(
t
time
.
Duration
)
error
{
...
@@ -593,6 +570,13 @@ func (c *FCGIClient) SetReadTimeout(t time.Duration) error {
...
@@ -593,6 +570,13 @@ func (c *FCGIClient) SetReadTimeout(t time.Duration) error {
return
nil
return
nil
}
}
// SetSendTimeout sets the read timeout for future calls that send data to
// the fcgi responder. A zero value for t means no timeout will be set.
func
(
c
*
FCGIClient
)
SetSendTimeout
(
t
time
.
Duration
)
error
{
c
.
sendTimeout
=
t
return
nil
}
// Checks whether chunked is part of the encodings stack
// Checks whether chunked is part of the encodings stack
func
chunked
(
te
[]
string
)
bool
{
return
len
(
te
)
>
0
&&
te
[
0
]
==
"chunked"
}
func
chunked
(
te
[]
string
)
bool
{
return
len
(
te
)
>
0
&&
te
[
0
]
==
"chunked"
}
...
...
caddyhttp/fastcgi/fcgiclient_test.go
View file @
e363491a
...
@@ -103,7 +103,7 @@ func (s FastCGIServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
...
@@ -103,7 +103,7 @@ func (s FastCGIServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
}
}
func
sendFcgi
(
reqType
int
,
fcgiParams
map
[
string
]
string
,
data
[]
byte
,
posts
map
[
string
]
string
,
files
map
[
string
]
string
)
(
content
[]
byte
)
{
func
sendFcgi
(
reqType
int
,
fcgiParams
map
[
string
]
string
,
data
[]
byte
,
posts
map
[
string
]
string
,
files
map
[
string
]
string
)
(
content
[]
byte
)
{
fcgi
,
err
:=
Dial
(
"tcp"
,
ipPort
,
0
)
fcgi
,
err
:=
Dial
Timeout
(
"tcp"
,
ipPort
,
0
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Println
(
"err:"
,
err
)
log
.
Println
(
"err:"
,
err
)
return
return
...
...
caddyhttp/fastcgi/setup.go
View file @
e363491a
...
@@ -59,7 +59,7 @@ func fastcgiParse(c *caddy.Controller) ([]Rule, error) {
...
@@ -59,7 +59,7 @@ func fastcgiParse(c *caddy.Controller) ([]Rule, error) {
return
rules
,
c
.
ArgErr
()
return
rules
,
c
.
ArgErr
()
}
}
rule
:=
Rule
{
Path
:
args
[
0
],
ReadTimeout
:
60
*
time
.
Second
}
rule
:=
Rule
{
Path
:
args
[
0
],
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
}
upstreams
:=
[]
string
{
args
[
1
]}
upstreams
:=
[]
string
{
args
[
1
]}
if
len
(
args
)
==
3
{
if
len
(
args
)
==
3
{
...
@@ -144,6 +144,15 @@ func fastcgiParse(c *caddy.Controller) ([]Rule, error) {
...
@@ -144,6 +144,15 @@ func fastcgiParse(c *caddy.Controller) ([]Rule, error) {
return
rules
,
err
return
rules
,
err
}
}
rule
.
ReadTimeout
=
readTimeout
rule
.
ReadTimeout
=
readTimeout
case
"send_timeout"
:
if
!
c
.
NextArg
()
{
return
rules
,
c
.
ArgErr
()
}
sendTimeout
,
err
:=
time
.
ParseDuration
(
c
.
Val
())
if
err
!=
nil
{
return
rules
,
err
}
rule
.
SendTimeout
=
sendTimeout
}
}
}
}
...
...
caddyhttp/fastcgi/setup_test.go
View file @
e363491a
...
@@ -80,6 +80,7 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -80,6 +80,7 @@ func TestFastcgiParse(t *testing.T) {
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
"tcp"
,
address
:
"127.0.0.1:9000"
,
timeout
:
60
*
time
.
Second
}}},
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
"tcp"
,
address
:
"127.0.0.1:9000"
,
timeout
:
60
*
time
.
Second
}}},
IndexFiles
:
[]
string
{
"index.php"
},
IndexFiles
:
[]
string
{
"index.php"
},
ReadTimeout
:
60
*
time
.
Second
,
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
,
}}},
}}},
{
`fastcgi /blog 127.0.0.1:9000 php {
{
`fastcgi /blog 127.0.0.1:9000 php {
upstream 127.0.0.1:9001
upstream 127.0.0.1:9001
...
@@ -92,6 +93,7 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -92,6 +93,7 @@ func TestFastcgiParse(t *testing.T) {
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
"tcp"
,
address
:
"127.0.0.1:9000"
,
timeout
:
60
*
time
.
Second
},
basicDialer
{
network
:
"tcp"
,
address
:
"127.0.0.1:9001"
,
timeout
:
60
*
time
.
Second
}}},
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
"tcp"
,
address
:
"127.0.0.1:9000"
,
timeout
:
60
*
time
.
Second
},
basicDialer
{
network
:
"tcp"
,
address
:
"127.0.0.1:9001"
,
timeout
:
60
*
time
.
Second
}}},
IndexFiles
:
[]
string
{
"index.php"
},
IndexFiles
:
[]
string
{
"index.php"
},
ReadTimeout
:
60
*
time
.
Second
,
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
,
}}},
}}},
{
`fastcgi /blog 127.0.0.1:9000 {
{
`fastcgi /blog 127.0.0.1:9000 {
upstream 127.0.0.1:9001
upstream 127.0.0.1:9001
...
@@ -104,6 +106,7 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -104,6 +106,7 @@ func TestFastcgiParse(t *testing.T) {
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
"tcp"
,
address
:
"127.0.0.1:9000"
,
timeout
:
60
*
time
.
Second
},
basicDialer
{
network
:
"tcp"
,
address
:
"127.0.0.1:9001"
,
timeout
:
60
*
time
.
Second
}}},
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
"tcp"
,
address
:
"127.0.0.1:9000"
,
timeout
:
60
*
time
.
Second
},
basicDialer
{
network
:
"tcp"
,
address
:
"127.0.0.1:9001"
,
timeout
:
60
*
time
.
Second
}}},
IndexFiles
:
[]
string
{},
IndexFiles
:
[]
string
{},
ReadTimeout
:
60
*
time
.
Second
,
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
,
}}},
}}},
{
`fastcgi / `
+
defaultAddress
+
` {
{
`fastcgi / `
+
defaultAddress
+
` {
split .html
split .html
...
@@ -116,6 +119,7 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -116,6 +119,7 @@ func TestFastcgiParse(t *testing.T) {
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
network
,
address
:
address
,
timeout
:
60
*
time
.
Second
}}},
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
network
,
address
:
address
,
timeout
:
60
*
time
.
Second
}}},
IndexFiles
:
[]
string
{},
IndexFiles
:
[]
string
{},
ReadTimeout
:
60
*
time
.
Second
,
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
,
}}},
}}},
{
`fastcgi / `
+
defaultAddress
+
` {
{
`fastcgi / `
+
defaultAddress
+
` {
split .html
split .html
...
@@ -130,6 +134,7 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -130,6 +134,7 @@ func TestFastcgiParse(t *testing.T) {
IndexFiles
:
[]
string
{},
IndexFiles
:
[]
string
{},
IgnoredSubPaths
:
[]
string
{
"/admin"
,
"/user"
},
IgnoredSubPaths
:
[]
string
{
"/admin"
,
"/user"
},
ReadTimeout
:
60
*
time
.
Second
,
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
,
}}},
}}},
{
`fastcgi / `
+
defaultAddress
+
` {
{
`fastcgi / `
+
defaultAddress
+
` {
pool 0
pool 0
...
@@ -142,6 +147,7 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -142,6 +147,7 @@ func TestFastcgiParse(t *testing.T) {
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
&
persistentDialer
{
size
:
0
,
network
:
network
,
address
:
address
,
timeout
:
60
*
time
.
Second
}}},
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
&
persistentDialer
{
size
:
0
,
network
:
network
,
address
:
address
,
timeout
:
60
*
time
.
Second
}}},
IndexFiles
:
[]
string
{},
IndexFiles
:
[]
string
{},
ReadTimeout
:
60
*
time
.
Second
,
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
,
}}},
}}},
{
`fastcgi / 127.0.0.1:8080 {
{
`fastcgi / 127.0.0.1:8080 {
upstream 127.0.0.1:9000
upstream 127.0.0.1:9000
...
@@ -155,6 +161,7 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -155,6 +161,7 @@ func TestFastcgiParse(t *testing.T) {
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
&
persistentDialer
{
size
:
5
,
network
:
"tcp"
,
address
:
"127.0.0.1:8080"
,
timeout
:
60
*
time
.
Second
},
&
persistentDialer
{
size
:
5
,
network
:
"tcp"
,
address
:
"127.0.0.1:9000"
,
timeout
:
60
*
time
.
Second
}}},
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
&
persistentDialer
{
size
:
5
,
network
:
"tcp"
,
address
:
"127.0.0.1:8080"
,
timeout
:
60
*
time
.
Second
},
&
persistentDialer
{
size
:
5
,
network
:
"tcp"
,
address
:
"127.0.0.1:9000"
,
timeout
:
60
*
time
.
Second
}}},
IndexFiles
:
[]
string
{},
IndexFiles
:
[]
string
{},
ReadTimeout
:
60
*
time
.
Second
,
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
,
}}},
}}},
{
`fastcgi / `
+
defaultAddress
+
` {
{
`fastcgi / `
+
defaultAddress
+
` {
split .php
split .php
...
@@ -167,6 +174,7 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -167,6 +174,7 @@ func TestFastcgiParse(t *testing.T) {
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
network
,
address
:
address
,
timeout
:
60
*
time
.
Second
}}},
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
network
,
address
:
address
,
timeout
:
60
*
time
.
Second
}}},
IndexFiles
:
[]
string
{},
IndexFiles
:
[]
string
{},
ReadTimeout
:
60
*
time
.
Second
,
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
,
}}},
}}},
{
`fastcgi / `
+
defaultAddress
+
` {
{
`fastcgi / `
+
defaultAddress
+
` {
connect_timeout 5s
connect_timeout 5s
...
@@ -179,7 +187,13 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -179,7 +187,13 @@ func TestFastcgiParse(t *testing.T) {
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
network
,
address
:
address
,
timeout
:
5
*
time
.
Second
}}},
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
network
,
address
:
address
,
timeout
:
5
*
time
.
Second
}}},
IndexFiles
:
[]
string
{},
IndexFiles
:
[]
string
{},
ReadTimeout
:
60
*
time
.
Second
,
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
,
}}},
}}},
{
`fastcgi / `
+
defaultAddress
+
` { connect_timeout BADVALUE }`
,
true
,
[]
Rule
{},
},
{
`fastcgi / `
+
defaultAddress
+
` {
{
`fastcgi / `
+
defaultAddress
+
` {
read_timeout 5s
read_timeout 5s
}`
,
}`
,
...
@@ -191,7 +205,31 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -191,7 +205,31 @@ func TestFastcgiParse(t *testing.T) {
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
network
,
address
:
address
,
timeout
:
60
*
time
.
Second
}}},
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
network
,
address
:
address
,
timeout
:
60
*
time
.
Second
}}},
IndexFiles
:
[]
string
{},
IndexFiles
:
[]
string
{},
ReadTimeout
:
5
*
time
.
Second
,
ReadTimeout
:
5
*
time
.
Second
,
SendTimeout
:
60
*
time
.
Second
,
}}},
{
`fastcgi / `
+
defaultAddress
+
` { read_timeout BADVALUE }`
,
true
,
[]
Rule
{},
},
{
`fastcgi / `
+
defaultAddress
+
` {
send_timeout 5s
}`
,
false
,
[]
Rule
{{
Path
:
"/"
,
Address
:
defaultAddress
,
Ext
:
""
,
SplitPath
:
""
,
dialer
:
&
loadBalancingDialer
{
dialers
:
[]
dialer
{
basicDialer
{
network
:
network
,
address
:
address
,
timeout
:
60
*
time
.
Second
}}},
IndexFiles
:
[]
string
{},
ReadTimeout
:
60
*
time
.
Second
,
SendTimeout
:
5
*
time
.
Second
,
}}},
}}},
{
`fastcgi / `
+
defaultAddress
+
` { send_timeout BADVALUE }`
,
true
,
[]
Rule
{},
},
{
`fastcgi / {
{
`fastcgi / {
}`
,
}`
,
...
@@ -251,6 +289,16 @@ func TestFastcgiParse(t *testing.T) {
...
@@ -251,6 +289,16 @@ func TestFastcgiParse(t *testing.T) {
t
.
Errorf
(
"Test %d expected %dth FastCGI IgnoredSubPaths to be %s , but got %s"
,
t
.
Errorf
(
"Test %d expected %dth FastCGI IgnoredSubPaths to be %s , but got %s"
,
i
,
j
,
test
.
expectedFastcgiConfig
[
j
]
.
IgnoredSubPaths
,
actualFastcgiConfig
.
IgnoredSubPaths
)
i
,
j
,
test
.
expectedFastcgiConfig
[
j
]
.
IgnoredSubPaths
,
actualFastcgiConfig
.
IgnoredSubPaths
)
}
}
if
fmt
.
Sprint
(
actualFastcgiConfig
.
ReadTimeout
)
!=
fmt
.
Sprint
(
test
.
expectedFastcgiConfig
[
j
]
.
ReadTimeout
)
{
t
.
Errorf
(
"Test %d expected %dth FastCGI ReadTimeout to be %s , but got %s"
,
i
,
j
,
test
.
expectedFastcgiConfig
[
j
]
.
ReadTimeout
,
actualFastcgiConfig
.
ReadTimeout
)
}
if
fmt
.
Sprint
(
actualFastcgiConfig
.
SendTimeout
)
!=
fmt
.
Sprint
(
test
.
expectedFastcgiConfig
[
j
]
.
SendTimeout
)
{
t
.
Errorf
(
"Test %d expected %dth FastCGI SendTimeout to be %s , but got %s"
,
i
,
j
,
test
.
expectedFastcgiConfig
[
j
]
.
SendTimeout
,
actualFastcgiConfig
.
SendTimeout
)
}
}
}
}
}
}
}
...
...
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