Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
B
beego
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
beego
Commits
25337aec
Commit
25337aec
authored
Dec 21, 2015
by
astaxie
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' of
https://github.com/astaxie/beego
into develop
parents
351dfac6
9105fee4
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
94 additions
and
123 deletions
+94
-123
config.go
config.go
+28
-44
input.go
context/input.go
+1
-1
controller.go
controller.go
+55
-67
namespace_test.go
namespace_test.go
+6
-6
types.go
orm/types.go
+0
-1
cors_test.go
plugins/cors/cors_test.go
+4
-4
No files found.
config.go
View file @
25337aec
...
...
@@ -177,8 +177,7 @@ func ParseConfig() (err error) {
if
utils
.
FileExists
(
filepath
.
Join
(
"conf"
,
"app.conf"
))
{
AppConfigPath
=
filepath
.
Join
(
"conf"
,
"app.conf"
)
}
else
{
ac
:=
config
.
NewFakeConfig
()
AppConfig
=
&
beegoAppConfig
{
ac
}
AppConfig
=
&
beegoAppConfig
{
config
.
NewFakeConfig
()}
return
}
}
...
...
@@ -186,9 +185,8 @@ func ParseConfig() (err error) {
if
err
!=
nil
{
return
err
}
envRunMode
:=
os
.
Getenv
(
"BEEGO_RUNMODE"
)
// set the runmode first
if
envRunMode
!=
""
{
if
envRunMode
:=
os
.
Getenv
(
"BEEGO_RUNMODE"
);
envRunMode
!=
""
{
BConfig
.
RunMode
=
envRunMode
}
else
if
runmode
:=
AppConfig
.
String
(
"RunMode"
);
runmode
!=
""
{
BConfig
.
RunMode
=
runmode
...
...
@@ -277,109 +275,95 @@ func newAppConfig(AppConfigProvider, AppConfigPath string) (*beegoAppConfig, err
if
err
!=
nil
{
return
nil
,
err
}
rac
:=
&
beegoAppConfig
{
ac
}
return
rac
,
nil
return
&
beegoAppConfig
{
ac
},
nil
}
func
(
b
*
beegoAppConfig
)
Set
(
key
,
val
string
)
error
{
err
:=
b
.
innerConfig
.
Set
(
BConfig
.
RunMode
+
"::"
+
key
,
val
)
if
err
==
nil
{
if
err
:=
b
.
innerConfig
.
Set
(
BConfig
.
RunMode
+
"::"
+
key
,
val
);
err
!=
nil
{
return
err
}
return
b
.
innerConfig
.
Set
(
key
,
val
)
}
func
(
b
*
beegoAppConfig
)
String
(
key
string
)
string
{
v
:=
b
.
innerConfig
.
String
(
BConfig
.
RunMode
+
"::"
+
key
)
if
v
==
""
{
return
b
.
innerConfig
.
String
(
key
)
if
v
:=
b
.
innerConfig
.
String
(
BConfig
.
RunMode
+
"::"
+
key
);
v
!=
""
{
return
v
}
return
v
return
b
.
innerConfig
.
String
(
key
)
}
func
(
b
*
beegoAppConfig
)
Strings
(
key
string
)
[]
string
{
v
:=
b
.
innerConfig
.
Strings
(
BConfig
.
RunMode
+
"::"
+
key
)
if
v
[
0
]
==
""
{
return
b
.
innerConfig
.
Strings
(
key
)
if
v
:=
b
.
innerConfig
.
Strings
(
BConfig
.
RunMode
+
"::"
+
key
);
v
[
0
]
!=
""
{
return
v
}
return
v
return
b
.
innerConfig
.
Strings
(
key
)
}
func
(
b
*
beegoAppConfig
)
Int
(
key
string
)
(
int
,
error
)
{
v
,
err
:=
b
.
innerConfig
.
Int
(
BConfig
.
RunMode
+
"::"
+
key
)
if
err
!=
nil
{
return
b
.
innerConfig
.
Int
(
key
)
if
v
,
err
:=
b
.
innerConfig
.
Int
(
BConfig
.
RunMode
+
"::"
+
key
);
err
==
nil
{
return
v
,
nil
}
return
v
,
nil
return
b
.
innerConfig
.
Int
(
key
)
}
func
(
b
*
beegoAppConfig
)
Int64
(
key
string
)
(
int64
,
error
)
{
v
,
err
:=
b
.
innerConfig
.
Int64
(
BConfig
.
RunMode
+
"::"
+
key
)
if
err
!=
nil
{
return
b
.
innerConfig
.
Int64
(
key
)
if
v
,
err
:=
b
.
innerConfig
.
Int64
(
BConfig
.
RunMode
+
"::"
+
key
);
err
==
nil
{
return
v
,
nil
}
return
v
,
nil
return
b
.
innerConfig
.
Int64
(
key
)
}
func
(
b
*
beegoAppConfig
)
Bool
(
key
string
)
(
bool
,
error
)
{
v
,
err
:=
b
.
innerConfig
.
Bool
(
BConfig
.
RunMode
+
"::"
+
key
)
if
err
!=
nil
{
return
b
.
innerConfig
.
Bool
(
key
)
if
v
,
err
:=
b
.
innerConfig
.
Bool
(
BConfig
.
RunMode
+
"::"
+
key
);
err
==
nil
{
return
v
,
nil
}
return
v
,
nil
return
b
.
innerConfig
.
Bool
(
key
)
}
func
(
b
*
beegoAppConfig
)
Float
(
key
string
)
(
float64
,
error
)
{
v
,
err
:=
b
.
innerConfig
.
Float
(
BConfig
.
RunMode
+
"::"
+
key
)
if
err
!=
nil
{
return
b
.
innerConfig
.
Float
(
key
)
if
v
,
err
:=
b
.
innerConfig
.
Float
(
BConfig
.
RunMode
+
"::"
+
key
);
err
==
nil
{
return
v
,
nil
}
return
v
,
nil
return
b
.
innerConfig
.
Float
(
key
)
}
func
(
b
*
beegoAppConfig
)
DefaultString
(
key
string
,
defaultval
string
)
string
{
v
:=
b
.
String
(
key
)
if
v
!=
""
{
if
v
:=
b
.
String
(
key
);
v
!=
""
{
return
v
}
return
defaultval
}
func
(
b
*
beegoAppConfig
)
DefaultStrings
(
key
string
,
defaultval
[]
string
)
[]
string
{
v
:=
b
.
Strings
(
key
)
if
len
(
v
)
!=
0
{
if
v
:=
b
.
Strings
(
key
);
len
(
v
)
!=
0
{
return
v
}
return
defaultval
}
func
(
b
*
beegoAppConfig
)
DefaultInt
(
key
string
,
defaultval
int
)
int
{
v
,
err
:=
b
.
Int
(
key
)
if
err
==
nil
{
if
v
,
err
:=
b
.
Int
(
key
);
err
==
nil
{
return
v
}
return
defaultval
}
func
(
b
*
beegoAppConfig
)
DefaultInt64
(
key
string
,
defaultval
int64
)
int64
{
v
,
err
:=
b
.
Int64
(
key
)
if
err
==
nil
{
if
v
,
err
:=
b
.
Int64
(
key
);
err
==
nil
{
return
v
}
return
defaultval
}
func
(
b
*
beegoAppConfig
)
DefaultBool
(
key
string
,
defaultval
bool
)
bool
{
v
,
err
:=
b
.
Bool
(
key
)
if
err
==
nil
{
if
v
,
err
:=
b
.
Bool
(
key
);
err
==
nil
{
return
v
}
return
defaultval
}
func
(
b
*
beegoAppConfig
)
DefaultFloat
(
key
string
,
defaultval
float64
)
float64
{
v
,
err
:=
b
.
Float
(
key
)
if
err
==
nil
{
if
v
,
err
:=
b
.
Float
(
key
);
err
==
nil
{
return
v
}
return
defaultval
...
...
context/input.go
View file @
25337aec
...
...
@@ -315,7 +315,7 @@ func (input *BeegoInput) Session(key interface{}) interface{} {
// CopyBody returns the raw request body data as bytes.
func
(
input
*
BeegoInput
)
CopyBody
(
MaxMemory
int64
)
[]
byte
{
safe
:=
&
io
.
LimitedReader
{
R
:
input
.
Context
.
Request
.
Body
,
N
:
MaxMemory
}
safe
:=
&
io
.
LimitedReader
{
R
:
input
.
Context
.
Request
.
Body
,
N
:
MaxMemory
}
requestbody
,
_
:=
ioutil
.
ReadAll
(
safe
)
input
.
Context
.
Request
.
Body
.
Close
()
bf
:=
bytes
.
NewBuffer
(
requestbody
)
...
...
controller.go
View file @
25337aec
...
...
@@ -19,7 +19,6 @@ import (
"errors"
"html/template"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"net/url"
...
...
@@ -57,22 +56,31 @@ type ControllerComments struct {
// Controller defines some basic http request handler operations, such as
// http context, template and view, session and xsrf.
type
Controller
struct
{
Ctx
*
context
.
Context
Data
map
[
interface
{}]
interface
{}
// context data
Ctx
*
context
.
Context
Data
map
[
interface
{}]
interface
{}
// route controller info
controllerName
string
actionName
string
methodMapping
map
[
string
]
func
()
//method:routertree
gotofunc
string
AppController
interface
{}
// template data
TplNames
string
Layout
string
LayoutSections
map
[
string
]
string
// the key is the section name and the value is the template name
TplExt
string
_xsrfToken
string
gotofunc
string
CruSession
session
.
Store
XSRFExpire
int
AppController
interface
{}
EnableRender
bool
EnableXSRF
bool
methodMapping
map
[
string
]
func
()
//method:routertree
// xsrf data
_xsrfToken
string
XSRFExpire
int
EnableXSRF
bool
// session
CruSession
session
.
Store
}
// ControllerInterface is an interface to uniform all controller handler.
...
...
@@ -110,14 +118,10 @@ func (c *Controller) Init(ctx *context.Context, controllerName, actionName strin
}
// Prepare runs after Init before request function execution.
func
(
c
*
Controller
)
Prepare
()
{
}
func
(
c
*
Controller
)
Prepare
()
{}
// Finish runs after request function execution.
func
(
c
*
Controller
)
Finish
()
{
}
func
(
c
*
Controller
)
Finish
()
{}
// Get adds a request function to handle GET request.
func
(
c
*
Controller
)
Get
()
{
...
...
@@ -164,8 +168,7 @@ func (c *Controller) HandlerFunc(fnname string) bool {
}
// URLMapping register the internal Controller router.
func
(
c
*
Controller
)
URLMapping
()
{
}
func
(
c
*
Controller
)
URLMapping
()
{}
// Mapping the method to function
func
(
c
*
Controller
)
Mapping
(
method
string
,
fn
func
())
{
...
...
@@ -195,14 +198,14 @@ func (c *Controller) RenderString() (string, error) {
// RenderBytes returns the bytes of rendered template string. Do not send out response.
func
(
c
*
Controller
)
RenderBytes
()
([]
byte
,
error
)
{
//if the controller has set layout, then first get the tplname's content set the content to the layout
var
buf
bytes
.
Buffer
if
c
.
Layout
!=
""
{
if
c
.
TplNames
==
""
{
c
.
TplNames
=
strings
.
ToLower
(
c
.
controllerName
)
+
"/"
+
strings
.
ToLower
(
c
.
actionName
)
+
"."
+
c
.
TplExt
}
if
BConfig
.
RunMode
==
"dev"
{
buildFiles
:=
make
([]
string
,
1
)
buildFiles
=
append
(
buildFiles
,
c
.
TplNames
)
buildFiles
:=
[]
string
{
c
.
TplNames
}
if
c
.
LayoutSections
!=
nil
{
for
_
,
sectionTpl
:=
range
c
.
LayoutSections
{
if
sectionTpl
==
""
{
...
...
@@ -213,17 +216,15 @@ func (c *Controller) RenderBytes() ([]byte, error) {
}
BuildTemplate
(
BConfig
.
WebConfig
.
ViewsPath
,
buildFiles
...
)
}
newbytes
:=
bytes
.
NewBufferString
(
""
)
if
_
,
ok
:=
BeeTemplates
[
c
.
TplNames
];
!
ok
{
panic
(
"can't find templatefile in the path:"
+
c
.
TplNames
)
}
err
:=
BeeTemplates
[
c
.
TplNames
]
.
ExecuteTemplate
(
newbytes
,
c
.
TplNames
,
c
.
Data
)
err
:=
BeeTemplates
[
c
.
TplNames
]
.
ExecuteTemplate
(
&
buf
,
c
.
TplNames
,
c
.
Data
)
if
err
!=
nil
{
Trace
(
"template Execute err:"
,
err
)
return
nil
,
err
}
tplcontent
,
_
:=
ioutil
.
ReadAll
(
newbytes
)
c
.
Data
[
"LayoutContent"
]
=
template
.
HTML
(
string
(
tplcontent
))
c
.
Data
[
"LayoutContent"
]
=
template
.
HTML
(
buf
.
String
())
if
c
.
LayoutSections
!=
nil
{
for
sectionName
,
sectionTpl
:=
range
c
.
LayoutSections
{
...
...
@@ -232,25 +233,23 @@ func (c *Controller) RenderBytes() ([]byte, error) {
continue
}
sectionBytes
:=
bytes
.
NewBufferString
(
""
)
err
=
BeeTemplates
[
sectionTpl
]
.
ExecuteTemplate
(
sectionBytes
,
sectionTpl
,
c
.
Data
)
buf
.
Reset
(
)
err
=
BeeTemplates
[
sectionTpl
]
.
ExecuteTemplate
(
&
buf
,
sectionTpl
,
c
.
Data
)
if
err
!=
nil
{
Trace
(
"template Execute err:"
,
err
)
return
nil
,
err
}
sectionContent
,
_
:=
ioutil
.
ReadAll
(
sectionBytes
)
c
.
Data
[
sectionName
]
=
template
.
HTML
(
string
(
sectionContent
))
c
.
Data
[
sectionName
]
=
template
.
HTML
(
buf
.
String
())
}
}
ibytes
:=
bytes
.
NewBufferString
(
""
)
err
=
BeeTemplates
[
c
.
Layout
]
.
ExecuteTemplate
(
ibytes
,
c
.
Layout
,
c
.
Data
)
buf
.
Reset
(
)
err
=
BeeTemplates
[
c
.
Layout
]
.
ExecuteTemplate
(
&
buf
,
c
.
Layout
,
c
.
Data
)
if
err
!=
nil
{
Trace
(
"template Execute err:"
,
err
)
return
nil
,
err
}
icontent
,
_
:=
ioutil
.
ReadAll
(
ibytes
)
return
icontent
,
nil
return
buf
.
Bytes
(),
nil
}
if
c
.
TplNames
==
""
{
...
...
@@ -259,17 +258,16 @@ func (c *Controller) RenderBytes() ([]byte, error) {
if
BConfig
.
RunMode
==
"dev"
{
BuildTemplate
(
BConfig
.
WebConfig
.
ViewsPath
,
c
.
TplNames
)
}
ibytes
:=
bytes
.
NewBufferString
(
""
)
if
_
,
ok
:=
BeeTemplates
[
c
.
TplNames
];
!
ok
{
panic
(
"can't find templatefile in the path:"
+
c
.
TplNames
)
}
err
:=
BeeTemplates
[
c
.
TplNames
]
.
ExecuteTemplate
(
ibytes
,
c
.
TplNames
,
c
.
Data
)
buf
.
Reset
()
err
:=
BeeTemplates
[
c
.
TplNames
]
.
ExecuteTemplate
(
&
buf
,
c
.
TplNames
,
c
.
Data
)
if
err
!=
nil
{
Trace
(
"template Execute err:"
,
err
)
return
nil
,
err
}
icontent
,
_
:=
ioutil
.
ReadAll
(
ibytes
)
return
icontent
,
nil
return
buf
.
Bytes
(),
nil
}
// Redirect sends the redirection response to url with status code.
...
...
@@ -306,7 +304,7 @@ func (c *Controller) StopRun() {
// URLFor does another controller handler in this request function.
// it goes to this controller method if endpoint is not clear.
func
(
c
*
Controller
)
URLFor
(
endpoint
string
,
values
...
interface
{})
string
{
if
len
(
endpoint
)
<
=
0
{
if
len
(
endpoint
)
=
=
0
{
return
""
}
if
endpoint
[
0
]
==
'.'
{
...
...
@@ -317,37 +315,33 @@ func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
// ServeJSON sends a json response with encoding charset.
func
(
c
*
Controller
)
ServeJSON
(
encoding
...
bool
)
{
var
hasIndent
bool
var
hasencoding
bool
var
(
hasIndent
=
true
hasEncoding
=
false
)
if
BConfig
.
RunMode
==
"prod"
{
hasIndent
=
false
}
else
{
hasIndent
=
true
}
if
len
(
encoding
)
>
0
&&
encoding
[
0
]
==
true
{
has
e
ncoding
=
true
has
E
ncoding
=
true
}
c
.
Ctx
.
Output
.
JSON
(
c
.
Data
[
"json"
],
hasIndent
,
has
e
ncoding
)
c
.
Ctx
.
Output
.
JSON
(
c
.
Data
[
"json"
],
hasIndent
,
has
E
ncoding
)
}
// ServeJSONP sends a jsonp response.
func
(
c
*
Controller
)
ServeJSONP
()
{
var
hasIndent
bool
hasIndent
:=
true
if
BConfig
.
RunMode
==
"prod"
{
hasIndent
=
false
}
else
{
hasIndent
=
true
}
c
.
Ctx
.
Output
.
JSONP
(
c
.
Data
[
"jsonp"
],
hasIndent
)
}
// ServeXML sends xml response.
func
(
c
*
Controller
)
ServeXML
()
{
var
hasIndent
bool
hasIndent
:=
true
if
BConfig
.
RunMode
==
"prod"
{
hasIndent
=
false
}
else
{
hasIndent
=
true
}
c
.
Ctx
.
Output
.
XML
(
c
.
Data
[
"xml"
],
hasIndent
)
}
...
...
@@ -380,15 +374,13 @@ func (c *Controller) ParseForm(obj interface{}) error {
// GetString returns the input value by key string or the default value while it's present and input is blank
func
(
c
*
Controller
)
GetString
(
key
string
,
def
...
string
)
string
{
var
defv
string
if
len
(
def
)
>
0
{
defv
=
def
[
0
]
}
if
v
:=
c
.
Ctx
.
Input
.
Query
(
key
);
v
!=
""
{
return
v
}
return
defv
if
len
(
def
)
>
0
{
return
def
[
0
]
}
return
""
}
// GetStrings returns the input string slice by key string or the default value while it's present and input is blank
...
...
@@ -399,15 +391,14 @@ func (c *Controller) GetStrings(key string, def ...[]string) []string {
defv
=
def
[
0
]
}
f
:=
c
.
Input
()
if
f
==
nil
{
if
f
:=
c
.
Input
();
f
==
nil
{
return
defv
}
else
{
if
vs
:=
f
[
key
];
len
(
vs
)
>
0
{
return
vs
}
}
vs
:=
f
[
key
]
if
len
(
vs
)
>
0
{
return
vs
}
return
defv
}
...
...
@@ -511,8 +502,7 @@ func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader,
// }
// }
func
(
c
*
Controller
)
GetFiles
(
key
string
)
([]
*
multipart
.
FileHeader
,
error
)
{
files
,
ok
:=
c
.
Ctx
.
Request
.
MultipartForm
.
File
[
key
]
if
ok
{
if
files
,
ok
:=
c
.
Ctx
.
Request
.
MultipartForm
.
File
[
key
];
ok
{
return
files
,
nil
}
return
nil
,
http
.
ErrMissingFile
...
...
@@ -601,11 +591,9 @@ func (c *Controller) SetSecureCookie(Secret, name, value string, others ...inter
// XSRFToken creates a CSRF token string and returns.
func
(
c
*
Controller
)
XSRFToken
()
string
{
if
c
.
_xsrfToken
==
""
{
var
expire
int64
expire
:=
int64
(
BConfig
.
WebConfig
.
XSRFExpire
)
if
c
.
XSRFExpire
>
0
{
expire
=
int64
(
c
.
XSRFExpire
)
}
else
{
expire
=
int64
(
BConfig
.
WebConfig
.
XSRFExpire
)
}
c
.
_xsrfToken
=
c
.
Ctx
.
XSRFToken
(
BConfig
.
WebConfig
.
XSRFKEY
,
expire
)
}
...
...
@@ -629,6 +617,6 @@ func (c *Controller) XSRFFormHTML() string {
}
// GetControllerAndAction gets the executing controller name and action name.
func
(
c
*
Controller
)
GetControllerAndAction
()
(
controllerName
,
actionName
string
)
{
func
(
c
*
Controller
)
GetControllerAndAction
()
(
string
,
string
)
{
return
c
.
controllerName
,
c
.
actionName
}
namespace_test.go
View file @
25337aec
...
...
@@ -61,8 +61,8 @@ func TestNamespaceNest(t *testing.T) {
ns
.
Namespace
(
NewNamespace
(
"/admin"
)
.
Get
(
"/order"
,
func
(
ctx
*
context
.
Context
)
{
ctx
.
Output
.
Body
([]
byte
(
"order"
))
}),
ctx
.
Output
.
Body
([]
byte
(
"order"
))
}),
)
AddNamespace
(
ns
)
BeeApp
.
Handlers
.
ServeHTTP
(
w
,
r
)
...
...
@@ -79,8 +79,8 @@ func TestNamespaceNestParam(t *testing.T) {
ns
.
Namespace
(
NewNamespace
(
"/admin"
)
.
Get
(
"/order/:id"
,
func
(
ctx
*
context
.
Context
)
{
ctx
.
Output
.
Body
([]
byte
(
ctx
.
Input
.
Param
(
":id"
)))
}),
ctx
.
Output
.
Body
([]
byte
(
ctx
.
Input
.
Param
(
":id"
)))
}),
)
AddNamespace
(
ns
)
BeeApp
.
Handlers
.
ServeHTTP
(
w
,
r
)
...
...
@@ -124,8 +124,8 @@ func TestNamespaceFilter(t *testing.T) {
ctx
.
Output
.
Body
([]
byte
(
"this is Filter"
))
})
.
Get
(
"/user/:id"
,
func
(
ctx
*
context
.
Context
)
{
ctx
.
Output
.
Body
([]
byte
(
ctx
.
Input
.
Param
(
":id"
)))
})
ctx
.
Output
.
Body
([]
byte
(
ctx
.
Input
.
Param
(
":id"
)))
})
AddNamespace
(
ns
)
BeeApp
.
Handlers
.
ServeHTTP
(
w
,
r
)
if
w
.
Body
.
String
()
!=
"this is Filter"
{
...
...
orm/types.go
View file @
25337aec
...
...
@@ -275,7 +275,6 @@ type QueryM2Mer interface {
Count
()
(
int64
,
error
)
}
// RawPreparer raw query statement
type
RawPreparer
interface
{
Exec
(
...
interface
{})
(
sql
.
Result
,
error
)
...
...
plugins/cors/cors_test.go
View file @
25337aec
...
...
@@ -225,8 +225,8 @@ func Benchmark_WithoutCORS(b *testing.B) {
ctx
.
Output
.
SetStatus
(
500
)
})
b
.
ResetTimer
()
for
i
:=
0
;
i
<
100
;
i
++
{
r
,
_
:=
http
.
NewRequest
(
"PUT"
,
"/foo"
,
nil
)
r
,
_
:=
http
.
NewRequest
(
"PUT"
,
"/foo"
,
nil
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
handler
.
ServeHTTP
(
recorder
,
r
)
}
}
...
...
@@ -246,8 +246,8 @@ func Benchmark_WithCORS(b *testing.B) {
ctx
.
Output
.
SetStatus
(
500
)
})
b
.
ResetTimer
()
for
i
:=
0
;
i
<
100
;
i
++
{
r
,
_
:=
http
.
NewRequest
(
"PUT"
,
"/foo"
,
nil
)
r
,
_
:=
http
.
NewRequest
(
"PUT"
,
"/foo"
,
nil
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
handler
.
ServeHTTP
(
recorder
,
r
)
}
}
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