Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Go Httpbin
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Jira
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Container registry
Monitor
Service Desk
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
OSS
Nix
Go Httpbin
Commits
29d7c7ad
Unverified
Commit
29d7c7ad
authored
Oct 4, 2020
by
Will McCutchen
Committed by
GitHub
Oct 4, 2020
Browse files
Options
Downloads
Plain Diff
Merge pull request #43 from mccutchen/drip-compat
Make /drip more compatible with original httpbin's implementation
parents
c429c2d3
d917d404
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
httpbin/handlers.go
+22
-22
22 additions, 22 deletions
httpbin/handlers.go
httpbin/handlers_test.go
+28
-5
28 additions, 5 deletions
httpbin/handlers_test.go
httpbin/httpbin.go
+28
-2
28 additions, 2 deletions
httpbin/httpbin.go
with
78 additions
and
29 deletions
httpbin/handlers.go
+
22
−
22
View file @
29d7c7ad
...
...
@@ -481,15 +481,16 @@ func (h *HTTPBin) Delay(w http.ResponseWriter, r *http.Request) {
func
(
h
*
HTTPBin
)
Drip
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
q
:=
r
.
URL
.
Query
()
duration
:=
time
.
Duration
(
0
)
delay
:=
time
.
Duration
(
0
)
numbytes
:=
int64
(
10
)
code
:=
http
.
StatusOK
var
(
duration
=
h
.
DefaultParams
.
DripDuration
delay
=
h
.
DefaultParams
.
DripDelay
numBytes
=
h
.
DefaultParams
.
DripNumBytes
code
=
http
.
StatusOK
var
err
error
err
error
)
userDuration
:=
q
.
Get
(
"duration"
)
if
userDuration
!=
""
{
if
userDuration
:=
q
.
Get
(
"duration"
);
userDuration
!=
""
{
duration
,
err
=
parseBoundedDuration
(
userDuration
,
0
,
h
.
MaxDuration
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Invalid duration"
,
http
.
StatusBadRequest
)
...
...
@@ -497,8 +498,7 @@ func (h *HTTPBin) Drip(w http.ResponseWriter, r *http.Request) {
}
}
userDelay
:=
q
.
Get
(
"delay"
)
if
userDelay
!=
""
{
if
userDelay
:=
q
.
Get
(
"delay"
);
userDelay
!=
""
{
delay
,
err
=
parseBoundedDuration
(
userDelay
,
0
,
h
.
MaxDuration
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Invalid delay"
,
http
.
StatusBadRequest
)
...
...
@@ -506,17 +506,15 @@ func (h *HTTPBin) Drip(w http.ResponseWriter, r *http.Request) {
}
}
userNumBytes
:=
q
.
Get
(
"numbytes"
)
if
userNumBytes
!=
""
{
numbytes
,
err
=
strconv
.
ParseInt
(
userNumBytes
,
10
,
64
)
if
err
!=
nil
||
numbytes
<=
0
||
numbytes
>
h
.
MaxBodySize
{
if
userNumBytes
:=
q
.
Get
(
"numbytes"
);
userNumBytes
!=
""
{
numBytes
,
err
=
strconv
.
ParseInt
(
userNumBytes
,
10
,
64
)
if
err
!=
nil
||
numBytes
<=
0
||
numBytes
>
h
.
MaxBodySize
{
http
.
Error
(
w
,
"Invalid numbytes"
,
http
.
StatusBadRequest
)
return
}
}
userCode
:=
q
.
Get
(
"code"
)
if
userCode
!=
""
{
if
userCode
:=
q
.
Get
(
"code"
);
userCode
!=
""
{
code
,
err
=
strconv
.
Atoi
(
userCode
)
if
err
!=
nil
||
code
<
100
||
code
>=
600
{
http
.
Error
(
w
,
"Invalid code"
,
http
.
StatusBadRequest
)
...
...
@@ -529,7 +527,13 @@ func (h *HTTPBin) Drip(w http.ResponseWriter, r *http.Request) {
return
}
pause
:=
duration
/
time
.
Duration
(
numbytes
)
pause
:=
duration
/
time
.
Duration
(
numBytes
)
flusher
:=
w
.
(
http
.
Flusher
)
w
.
Header
()
.
Set
(
"Content-Type"
,
"application/octet-stream"
)
w
.
Header
()
.
Set
(
"Content-Length"
,
fmt
.
Sprintf
(
"%d"
,
numBytes
))
w
.
WriteHeader
(
code
)
flusher
.
Flush
()
select
{
case
<-
r
.
Context
()
.
Done
()
:
...
...
@@ -537,13 +541,9 @@ func (h *HTTPBin) Drip(w http.ResponseWriter, r *http.Request) {
case
<-
time
.
After
(
delay
)
:
}
w
.
WriteHeader
(
code
)
w
.
Header
()
.
Set
(
"Content-Type"
,
"application/octet-stream"
)
f
:=
w
.
(
http
.
Flusher
)
for
i
:=
int64
(
0
);
i
<
numbytes
;
i
++
{
for
i
:=
int64
(
0
);
i
<
numBytes
;
i
++
{
w
.
Write
([]
byte
(
"*"
))
f
.
Flush
()
f
lusher
.
Flush
()
select
{
case
<-
r
.
Context
()
.
Done
()
:
...
...
This diff is collapsed.
Click to expand it.
httpbin/handlers_test.go
+
28
−
5
View file @
29d7c7ad
...
...
@@ -27,7 +27,14 @@ const maxBodySize int64 = 1024 * 1024
const
maxDuration
time
.
Duration
=
1
*
time
.
Second
const
alphanumLetters
=
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var
testDefaultParams
=
DefaultParams
{
DripDelay
:
0
,
DripDuration
:
100
*
time
.
Millisecond
,
DripNumBytes
:
10
,
}
var
app
=
New
(
WithDefaultParams
(
testDefaultParams
),
WithMaxBodySize
(
maxBodySize
),
WithMaxDuration
(
maxDuration
),
WithObserver
(
StdLogObserver
(
log
.
New
(
ioutil
.
Discard
,
""
,
0
))),
...
...
@@ -1507,7 +1514,6 @@ func TestDrip(t *testing.T) {
for
_
,
test
:=
range
okTests
{
t
.
Run
(
fmt
.
Sprintf
(
"ok/%s"
,
test
.
params
.
Encode
()),
func
(
t
*
testing
.
T
)
{
url
:=
"/drip?"
+
test
.
params
.
Encode
()
start
:=
time
.
Now
()
r
,
_
:=
http
.
NewRequest
(
"GET"
,
url
,
nil
)
...
...
@@ -1516,8 +1522,9 @@ func TestDrip(t *testing.T) {
elapsed
:=
time
.
Since
(
start
)
assertHeader
(
t
,
w
,
"Content-Type"
,
"application/octet-stream"
)
assertStatusCode
(
t
,
w
,
test
.
code
)
assertHeader
(
t
,
w
,
"Content-Type"
,
"application/octet-stream"
)
assertHeader
(
t
,
w
,
"Content-Length"
,
strconv
.
Itoa
(
test
.
numbytes
))
if
len
(
w
.
Body
.
Bytes
())
!=
test
.
numbytes
{
t
.
Fatalf
(
"expected %d bytes, got %d"
,
test
.
numbytes
,
len
(
w
.
Body
.
Bytes
()))
}
...
...
@@ -1532,13 +1539,29 @@ func TestDrip(t *testing.T) {
srv
:=
httptest
.
NewServer
(
handler
)
defer
srv
.
Close
()
// For this test, we expect the client to time out and cancel the
// request after 10ms. The handler should immediately write a 200 OK
// status before the client timeout, preventing a client error, but it
// will wait 500ms to write anything to the response body.
//
// So, we're testing that a) the client got an immediate 200 OK but
// that b) the response body was empty.
client
:=
http
.
Client
{
Timeout
:
time
.
Duration
(
10
*
time
.
Millisecond
),
}
resp
,
err
:=
client
.
Get
(
srv
.
URL
+
"/drip?duration=500ms&delay=500ms"
)
if
err
==
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %s"
,
err
)
}
defer
resp
.
Body
.
Close
()
body
,
_
:=
ioutil
.
ReadAll
(
resp
.
Body
)
t
.
Fatalf
(
"expected timeout error, got %d %s"
,
resp
.
StatusCode
,
body
)
if
err
!=
nil
{
t
.
Fatalf
(
"error reading response body: %s"
,
err
)
}
if
len
(
body
)
!=
0
{
t
.
Fatalf
(
"expected client timeout before body was written, got body %q"
,
string
(
body
))
}
})
...
...
This diff is collapsed.
Click to expand it.
httpbin/httpbin.go
+
28
−
2
View file @
29d7c7ad
...
...
@@ -96,6 +96,24 @@ type HTTPBin struct {
// Observer called with the result of each handled request
Observer
Observer
// Default parameter values
DefaultParams
DefaultParams
}
// DefaultParams defines default parameter values
type
DefaultParams
struct
{
DripDuration
time
.
Duration
DripDelay
time
.
Duration
DripNumBytes
int64
}
// DefaultDefaultParams defines the DefaultParams that are used by default. In
// general, these should match the original httpbin.org's defaults.
var
DefaultDefaultParams
=
DefaultParams
{
DripDuration
:
2
*
time
.
Second
,
DripDelay
:
2
*
time
.
Second
,
DripNumBytes
:
10
,
}
// Handler returns an http.Handler that exposes all HTTPBin endpoints
...
...
@@ -199,6 +217,7 @@ func New(opts ...OptionFunc) *HTTPBin {
h
:=
&
HTTPBin
{
MaxBodySize
:
DefaultMaxBodySize
,
MaxDuration
:
DefaultMaxDuration
,
DefaultParams
:
DefaultDefaultParams
,
}
for
_
,
opt
:=
range
opts
{
opt
(
h
)
...
...
@@ -210,6 +229,13 @@ func New(opts ...OptionFunc) *HTTPBin {
// instance
type
OptionFunc
func
(
*
HTTPBin
)
// WithDefaultParams sets the default params handlers will use
func
WithDefaultParams
(
defaultParams
DefaultParams
)
OptionFunc
{
return
func
(
h
*
HTTPBin
)
{
h
.
DefaultParams
=
defaultParams
}
}
// WithMaxBodySize sets the maximum amount of memory
func
WithMaxBodySize
(
m
int64
)
OptionFunc
{
return
func
(
h
*
HTTPBin
)
{
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment