Add models for the Echo framework

This commit is contained in:
Chris Smowton
2020-09-17 18:20:30 +01:00
parent bdb3e54299
commit 397282f41a
12 changed files with 865 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Added support for the Echo web framework

View File

@@ -27,6 +27,7 @@ import semmle.go.dataflow.GlobalValueNumbering
import semmle.go.dataflow.SSA
import semmle.go.dataflow.TaintTracking
import semmle.go.frameworks.Chi
import semmle.go.frameworks.Echo
import semmle.go.frameworks.Email
import semmle.go.frameworks.Encoding
import semmle.go.frameworks.Gin

View File

@@ -0,0 +1,122 @@
/**
* Provides classes for working with untrusted flow sources, taint propagators, and HTTP sinks
* from the `github.com/labstack/echo` package.
*/
import go
private module Echo {
/** Gets an Echo package name. */
bindingset[result]
private string packagePath() { result = package("github.com/labstack/echo", "") }
/**
* Data from a `Context` interface method, considered as a source of untrusted flow.
*/
private class EchoContextSource extends UntrustedFlowSource::Range {
EchoContextSource() {
exists(DataFlow::MethodCallNode call, string methodName |
methodName =
["Param", "ParamValues", "QueryParam", "QueryParams", "QueryString", "FormValue",
"FormParams", "FormFile", "MultipartForm", "Cookie", "Cookies"] and
call.getTarget().hasQualifiedName(packagePath(), "Context", methodName) and
this = call.getResult(0)
)
}
}
/**
* Data from a `Context` interface method that is not generally exploitable for open-redirect attacks.
*/
private class EchoContextRedirectUnexploitableSource extends HTTP::Redirect::UnexploitableSource {
EchoContextRedirectUnexploitableSource() {
exists(DataFlow::MethodCallNode call, string methodName |
methodName = ["FormValue", "FormParams", "FormFile", "MultipartForm", "Cookie", "Cookies"] and
call.getTarget().hasQualifiedName(packagePath(), "Context", methodName) and
this = call.getResult(0)
)
}
}
/**
* Models of `Context.Get/Set`. `Context` behaves like a map, with corresponding taint propagation.
*/
private class ContextMapModels extends TaintTracking::FunctionModel, Method {
string methodName;
FunctionInput input;
FunctionOutput output;
ContextMapModels() {
(
methodName = "Get" and input.isReceiver() and output.isResult()
or
methodName = "Set" and input.isParameter(1) and output.isReceiver()
) and
this.hasQualifiedName(packagePath(), "Context", methodName)
}
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
inp = input and outp = output
}
}
/**
* A call to a method on `Context` struct that unmarshals data into a target.
*/
private class EchoContextBinder extends UntrustedFlowSource::Range {
EchoContextBinder() {
exists(DataFlow::MethodCallNode call |
call.getTarget().hasQualifiedName(packagePath(), "Context", "Bind")
|
this = any(FunctionOutput output | output.isParameter(0)).getExitNode(call)
)
}
}
/**
* `echo.Context` methods which set the content-type to `text/html` and write a result in one operation.
*/
private class EchoHtmlOutputs extends HTTP::ResponseBody::Range {
EchoHtmlOutputs() {
exists(Method m | m.hasQualifiedName(packagePath(), "Context", ["HTML", "HTMLBlob"]) |
this = m.getACall().getArgument(1)
)
}
override HTTP::ResponseWriter getResponseWriter() { none() }
override string getAContentType() { result = "text/html" }
}
/**
* `echo.Context` methods which take a content-type as a parameter.
*/
private class EchoParameterizedOutputs extends HTTP::ResponseBody::Range {
DataFlow::CallNode callNode;
EchoParameterizedOutputs() {
exists(Method m | m.hasQualifiedName(packagePath(), "Context", ["Blob", "Stream"]) |
callNode = m.getACall() and this = callNode.getArgument(2)
)
}
override HTTP::ResponseWriter getResponseWriter() { none() }
override DataFlow::Node getAContentTypeNode() { result = callNode.getArgument(1) }
}
/**
* The `echo.Context.Redirect` method.
*/
private class EchoRedirectMethod extends HTTP::Redirect::Range, DataFlow::CallNode {
EchoRedirectMethod() {
exists(Method m | m.hasQualifiedName(packagePath(), "Context", "Redirect") |
this = m.getACall()
)
}
override DataFlow::Node getUrl() { result = this.getArgument(1) }
override HTTP::ResponseWriter getResponseWriter() { none() }
}
}

View File

@@ -0,0 +1,19 @@
edges
| test.go:170:11:170:32 | call to Param : string | test.go:171:20:171:24 | param |
| test.go:176:11:176:32 | call to Param : string | test.go:180:20:180:28 | ...+... |
| test.go:188:10:188:26 | selection of URL : pointer type | test.go:188:10:188:26 | selection of URL : pointer type |
| test.go:188:10:188:26 | selection of URL : pointer type | test.go:188:10:188:26 | selection of URL : pointer type |
| test.go:188:10:188:26 | selection of URL : pointer type | test.go:191:21:191:32 | call to String |
| test.go:188:10:188:26 | selection of URL : pointer type | test.go:191:21:191:32 | call to String |
nodes
| test.go:170:11:170:32 | call to Param : string | semmle.label | call to Param : string |
| test.go:171:20:171:24 | param | semmle.label | param |
| test.go:176:11:176:32 | call to Param : string | semmle.label | call to Param : string |
| test.go:180:20:180:28 | ...+... | semmle.label | ...+... |
| test.go:188:10:188:26 | selection of URL : pointer type | semmle.label | selection of URL : pointer type |
| test.go:188:10:188:26 | selection of URL : pointer type | semmle.label | selection of URL : pointer type |
| test.go:191:21:191:32 | call to String | semmle.label | call to String |
| test.go:191:21:191:32 | call to String | semmle.label | call to String |
#select
| test.go:171:20:171:24 | param | test.go:170:11:170:32 | call to Param : string | test.go:171:20:171:24 | param | Untrusted URL redirection due to $@. | test.go:170:11:170:32 | call to Param | user-provided value |
| test.go:180:20:180:28 | ...+... | test.go:176:11:176:32 | call to Param : string | test.go:180:20:180:28 | ...+... | Untrusted URL redirection due to $@. | test.go:176:11:176:32 | call to Param | user-provided value |

View File

@@ -0,0 +1 @@
Security/CWE-601/OpenUrlRedirect.ql

View File

@@ -0,0 +1,95 @@
edges
| test.go:13:11:13:32 | call to Param : string | test.go:14:16:14:20 | param |
| test.go:19:11:19:27 | call to ParamValues : slice type | test.go:20:16:20:20 | param |
| test.go:25:11:25:37 | call to QueryParam : string | test.go:26:16:26:20 | param |
| test.go:31:11:31:27 | call to QueryParams : Values | test.go:32:16:32:20 | param |
| test.go:37:10:37:26 | call to QueryString : string | test.go:38:16:38:19 | qstr |
| test.go:43:9:43:34 | call to FormValue : string | test.go:44:16:44:18 | val |
| test.go:49:2:49:30 | ... := ...[0] : Values | test.go:50:16:50:37 | index expression |
| test.go:55:2:55:46 | ... := ...[0] : pointer type | test.go:59:20:59:25 | buffer |
| test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:19 | implicit dereference : Form |
| test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:41 | index expression |
| test.go:65:16:65:19 | implicit dereference : Form | test.go:65:16:65:19 | implicit dereference : Form |
| test.go:65:16:65:19 | implicit dereference : Form | test.go:65:16:65:41 | index expression |
| test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:71:16:71:19 | implicit dereference : Form |
| test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:75:20:75:25 | buffer |
| test.go:71:16:71:19 | implicit dereference : Form | test.go:71:16:71:19 | implicit dereference : Form |
| test.go:71:16:71:19 | implicit dereference : Form | test.go:75:20:75:25 | buffer |
| test.go:80:2:80:32 | ... := ...[0] : pointer type | test.go:81:16:81:18 | implicit dereference : Cookie |
| test.go:80:2:80:32 | ... := ...[0] : pointer type | test.go:81:16:81:24 | selection of Value |
| test.go:81:16:81:18 | implicit dereference : Cookie | test.go:81:16:81:18 | implicit dereference : Cookie |
| test.go:81:16:81:18 | implicit dereference : Cookie | test.go:81:16:81:24 | selection of Value |
| test.go:86:13:86:25 | call to Cookies : slice type | test.go:87:16:87:25 | implicit dereference : Cookie |
| test.go:86:13:86:25 | call to Cookies : slice type | test.go:87:16:87:31 | selection of Value |
| test.go:87:16:87:25 | implicit dereference : Cookie | test.go:87:16:87:25 | implicit dereference : Cookie |
| test.go:87:16:87:25 | implicit dereference : Cookie | test.go:87:16:87:31 | selection of Value |
| test.go:97:11:97:15 | &... : pointer type | test.go:98:16:98:21 | selection of s |
| test.go:111:21:111:42 | call to Param : string | test.go:112:16:112:42 | type assertion |
| test.go:122:11:122:32 | call to Param : string | test.go:123:16:123:20 | param |
| test.go:128:11:128:32 | call to Param : string | test.go:129:20:129:32 | type conversion |
| test.go:134:11:134:32 | call to Param : string | test.go:135:29:135:41 | type conversion |
| test.go:146:11:146:32 | call to Param : string | test.go:148:31:148:36 | reader |
| test.go:162:11:162:32 | call to Param : string | test.go:163:23:163:35 | type conversion |
nodes
| test.go:13:11:13:32 | call to Param : string | semmle.label | call to Param : string |
| test.go:14:16:14:20 | param | semmle.label | param |
| test.go:19:11:19:27 | call to ParamValues : slice type | semmle.label | call to ParamValues : slice type |
| test.go:20:16:20:20 | param | semmle.label | param |
| test.go:25:11:25:37 | call to QueryParam : string | semmle.label | call to QueryParam : string |
| test.go:26:16:26:20 | param | semmle.label | param |
| test.go:31:11:31:27 | call to QueryParams : Values | semmle.label | call to QueryParams : Values |
| test.go:32:16:32:20 | param | semmle.label | param |
| test.go:37:10:37:26 | call to QueryString : string | semmle.label | call to QueryString : string |
| test.go:38:16:38:19 | qstr | semmle.label | qstr |
| test.go:43:9:43:34 | call to FormValue : string | semmle.label | call to FormValue : string |
| test.go:44:16:44:18 | val | semmle.label | val |
| test.go:49:2:49:30 | ... := ...[0] : Values | semmle.label | ... := ...[0] : Values |
| test.go:50:16:50:37 | index expression | semmle.label | index expression |
| test.go:55:2:55:46 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type |
| test.go:59:20:59:25 | buffer | semmle.label | buffer |
| test.go:64:2:64:31 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type |
| test.go:65:16:65:19 | implicit dereference : Form | semmle.label | implicit dereference : Form |
| test.go:65:16:65:41 | index expression | semmle.label | index expression |
| test.go:70:2:70:31 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type |
| test.go:71:16:71:19 | implicit dereference : Form | semmle.label | implicit dereference : Form |
| test.go:75:20:75:25 | buffer | semmle.label | buffer |
| test.go:80:2:80:32 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type |
| test.go:81:16:81:18 | implicit dereference : Cookie | semmle.label | implicit dereference : Cookie |
| test.go:81:16:81:24 | selection of Value | semmle.label | selection of Value |
| test.go:86:13:86:25 | call to Cookies : slice type | semmle.label | call to Cookies : slice type |
| test.go:87:16:87:25 | implicit dereference : Cookie | semmle.label | implicit dereference : Cookie |
| test.go:87:16:87:31 | selection of Value | semmle.label | selection of Value |
| test.go:97:11:97:15 | &... : pointer type | semmle.label | &... : pointer type |
| test.go:98:16:98:21 | selection of s | semmle.label | selection of s |
| test.go:111:21:111:42 | call to Param : string | semmle.label | call to Param : string |
| test.go:112:16:112:42 | type assertion | semmle.label | type assertion |
| test.go:122:11:122:32 | call to Param : string | semmle.label | call to Param : string |
| test.go:123:16:123:20 | param | semmle.label | param |
| test.go:128:11:128:32 | call to Param : string | semmle.label | call to Param : string |
| test.go:129:20:129:32 | type conversion | semmle.label | type conversion |
| test.go:134:11:134:32 | call to Param : string | semmle.label | call to Param : string |
| test.go:135:29:135:41 | type conversion | semmle.label | type conversion |
| test.go:146:11:146:32 | call to Param : string | semmle.label | call to Param : string |
| test.go:148:31:148:36 | reader | semmle.label | reader |
| test.go:162:11:162:32 | call to Param : string | semmle.label | call to Param : string |
| test.go:163:23:163:35 | type conversion | semmle.label | type conversion |
#select
| test.go:14:16:14:20 | param | test.go:13:11:13:32 | call to Param : string | test.go:14:16:14:20 | param | Cross-site scripting vulnerability due to $@. | test.go:13:11:13:32 | call to Param | user-provided value |
| test.go:20:16:20:20 | param | test.go:19:11:19:27 | call to ParamValues : slice type | test.go:20:16:20:20 | param | Cross-site scripting vulnerability due to $@. | test.go:19:11:19:27 | call to ParamValues | user-provided value |
| test.go:26:16:26:20 | param | test.go:25:11:25:37 | call to QueryParam : string | test.go:26:16:26:20 | param | Cross-site scripting vulnerability due to $@. | test.go:25:11:25:37 | call to QueryParam | user-provided value |
| test.go:32:16:32:20 | param | test.go:31:11:31:27 | call to QueryParams : Values | test.go:32:16:32:20 | param | Cross-site scripting vulnerability due to $@. | test.go:31:11:31:27 | call to QueryParams | user-provided value |
| test.go:38:16:38:19 | qstr | test.go:37:10:37:26 | call to QueryString : string | test.go:38:16:38:19 | qstr | Cross-site scripting vulnerability due to $@. | test.go:37:10:37:26 | call to QueryString | user-provided value |
| test.go:44:16:44:18 | val | test.go:43:9:43:34 | call to FormValue : string | test.go:44:16:44:18 | val | Cross-site scripting vulnerability due to $@. | test.go:43:9:43:34 | call to FormValue | user-provided value |
| test.go:50:16:50:37 | index expression | test.go:49:2:49:30 | ... := ...[0] : Values | test.go:50:16:50:37 | index expression | Cross-site scripting vulnerability due to $@. | test.go:49:2:49:30 | ... := ...[0] | user-provided value |
| test.go:59:20:59:25 | buffer | test.go:55:2:55:46 | ... := ...[0] : pointer type | test.go:59:20:59:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:55:2:55:46 | ... := ...[0] | user-provided value |
| test.go:65:16:65:41 | index expression | test.go:64:2:64:31 | ... := ...[0] : pointer type | test.go:65:16:65:41 | index expression | Cross-site scripting vulnerability due to $@. | test.go:64:2:64:31 | ... := ...[0] | user-provided value |
| test.go:75:20:75:25 | buffer | test.go:70:2:70:31 | ... := ...[0] : pointer type | test.go:75:20:75:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:70:2:70:31 | ... := ...[0] | user-provided value |
| test.go:81:16:81:24 | selection of Value | test.go:80:2:80:32 | ... := ...[0] : pointer type | test.go:81:16:81:24 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:80:2:80:32 | ... := ...[0] | user-provided value |
| test.go:87:16:87:31 | selection of Value | test.go:86:13:86:25 | call to Cookies : slice type | test.go:87:16:87:31 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:86:13:86:25 | call to Cookies | user-provided value |
| test.go:98:16:98:21 | selection of s | test.go:97:11:97:15 | &... : pointer type | test.go:98:16:98:21 | selection of s | Cross-site scripting vulnerability due to $@. | test.go:97:11:97:15 | &... | user-provided value |
| test.go:112:16:112:42 | type assertion | test.go:111:21:111:42 | call to Param : string | test.go:112:16:112:42 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:111:21:111:42 | call to Param | user-provided value |
| test.go:123:16:123:20 | param | test.go:122:11:122:32 | call to Param : string | test.go:123:16:123:20 | param | Cross-site scripting vulnerability due to $@. | test.go:122:11:122:32 | call to Param | user-provided value |
| test.go:129:20:129:32 | type conversion | test.go:128:11:128:32 | call to Param : string | test.go:129:20:129:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:128:11:128:32 | call to Param | user-provided value |
| test.go:135:29:135:41 | type conversion | test.go:134:11:134:32 | call to Param : string | test.go:135:29:135:41 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:134:11:134:32 | call to Param | user-provided value |
| test.go:148:31:148:36 | reader | test.go:146:11:146:32 | call to Param : string | test.go:148:31:148:36 | reader | Cross-site scripting vulnerability due to $@. | test.go:146:11:146:32 | call to Param | user-provided value |
| test.go:163:23:163:35 | type conversion | test.go:162:11:162:32 | call to Param : string | test.go:163:23:163:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:162:11:162:32 | call to Param | user-provided value |

View File

@@ -0,0 +1 @@
Security/CWE-079/ReflectedXss.ql

View File

@@ -0,0 +1,7 @@
go 1.14
module test
require (
github.com/labstack/echo/v4 v4.1.17
)

View File

@@ -0,0 +1,213 @@
package test
import (
"strings"
"github.com/labstack/echo/v4"
)
// Section: testing echo-specific user-controlled inputs, written as HTML.
// All are XSS vulnerabilities, except as specifically noted.
func testParam(ctx echo.Context) error {
param := ctx.Param("someParam")
ctx.HTML(200, param)
return nil
}
func testParamValues(ctx echo.Context) error {
param := ctx.ParamValues()[0]
ctx.HTML(200, param)
return nil
}
func testQueryParam(ctx echo.Context) error {
param := ctx.QueryParam("someParam")
ctx.HTML(200, param)
return nil
}
func testQueryParams(ctx echo.Context) error {
param := ctx.QueryParams()["someParam"][0]
ctx.HTML(200, param)
return nil
}
func testQueryString(ctx echo.Context) error {
qstr := ctx.QueryString()
ctx.HTML(200, qstr)
return nil
}
func testFormValue(ctx echo.Context) error {
val := ctx.FormValue("someField")
ctx.HTML(200, val)
return nil
}
func testFormParams(ctx echo.Context) error {
params, _ := ctx.FormParams()
ctx.HTML(200, params["someField"][0])
return nil
}
func testFormFile(ctx echo.Context) error {
fileHeader, _ := ctx.FormFile("someFilename")
file, _ := fileHeader.Open()
buffer := make([]byte, 100)
file.Read(buffer)
ctx.HTMLBlob(200, buffer)
return nil
}
func testMultipartFormValue(ctx echo.Context) error {
form, _ := ctx.MultipartForm()
ctx.HTML(200, form.Value["someField"][0])
return nil
}
func testMultipartFormFile(ctx echo.Context) error {
form, _ := ctx.MultipartForm()
fileHeader := form.File["someFilename"][0]
file, _ := fileHeader.Open()
buffer := make([]byte, 100)
file.Read(buffer)
ctx.HTMLBlob(200, buffer)
return nil
}
func testCookie(ctx echo.Context) error {
val, _ := ctx.Cookie("someKey")
ctx.HTML(200, val.Value)
return nil
}
func testCookies(ctx echo.Context) error {
cookies := ctx.Cookies()
ctx.HTML(200, cookies[0].Value)
return nil
}
type myStruct struct {
s string
}
func testBind(ctx echo.Context) error {
data := myStruct{}
ctx.Bind(&data)
ctx.HTML(200, data.s)
return nil
}
// Section: testing Context as a generic map. The empty context is clean;
// once tainted data is written to it it becomes a problem.
func testGetSetEmpty(ctx echo.Context) error {
ctx.HTML(200, ctx.Get("someKey").(string)) // OK, the context is empty
return nil
}
func testGetSet(ctx echo.Context) error {
ctx.Set("someKey", ctx.Param("someParam"))
ctx.HTML(200, ctx.Get("someKey").(string)) // BAD, the context is tainted
return nil
}
// Section: testing output methods defined on echo.Context. I only test HTML output methods,
// as we don't have any queries at the moment checking for data that shouldn't go to the user,
// even in JSON or text form.
// All are XSS vulnerabilities, except as specifically noted.
func testHTML(ctx echo.Context) error {
param := ctx.Param("someParam")
ctx.HTML(200, param)
return nil
}
func testHTMLBlob(ctx echo.Context) error {
param := ctx.Param("someParam")
ctx.HTMLBlob(200, []byte(param))
return nil
}
func testBlob(ctx echo.Context) error {
param := ctx.Param("someParam")
ctx.Blob(200, "text/html", []byte(param)) // BAD, the content-type is HTML
return nil
}
func testBlobSafe(ctx echo.Context) error {
param := ctx.Param("someParam")
ctx.Blob(200, "text/plain", []byte(param)) // OK, the content-type prevents XSS
return nil
}
func testStream(ctx echo.Context) error {
param := ctx.Param("someParam")
reader := strings.NewReader(param)
ctx.Stream(200, "text/html", reader) // BAD, the content-type is HTML
return nil
}
func testStreamSafe(ctx echo.Context) error {
param := ctx.Param("someParam")
reader := strings.NewReader(param)
ctx.Stream(200, "text/plain", reader) // OK, the content-type prevents XSS
return nil
}
// Section: testing output methods defined on Response (XSS vulnerability)
func testResponseWrite(ctx echo.Context) error {
param := ctx.Param("someParam")
ctx.Response().Write([]byte(param))
return nil
}
// Section: test detecting an open redirect using the Context.Redirect function:
func testRedirect(ctx echo.Context) error {
param := ctx.Param("someParam")
ctx.Redirect(301, param)
return nil
}
func testLocalRedirects(ctx echo.Context) error {
param := ctx.Param("someParam")
// GOOD: local redirects are unproblematic
ctx.Redirect(301, "/local"+param)
// BAD: this could be a non-local redirect
ctx.Redirect(301, "/"+param)
// GOOD: localhost redirects are unproblematic
ctx.Redirect(301, "//localhost/"+param)
return nil
}
func testSafeSchemeChange(ctx echo.Context) error {
// GOOD: Only safe parts of the URL are used
url := *ctx.Request().URL
if url.Scheme == "http" {
url.Scheme = "https"
ctx.Redirect(301, url.String())
}
return nil
}
func testNonExploitableFields(ctx echo.Context) error {
// GOOD: all these fields and methods is disregarded for OpenRedirect attacks:
ctx.Redirect(301, ctx.FormValue("someField"))
params, _ := ctx.FormParams()
ctx.Redirect(301, params["someField"][0])
fileHeader, _ := ctx.FormFile("someFile")
file, _ := fileHeader.Open()
buffer := make([]byte, 100)
file.Read(buffer)
ctx.Redirect(301, string(buffer))
form, _ := ctx.MultipartForm()
ctx.Redirect(301, form.Value["someField"][0])
val, _ := ctx.Cookie("someKey")
ctx.Redirect(301, val.Value)
cookies := ctx.Cookies()
ctx.Redirect(301, cookies[0].Value)
return nil
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017 LabStack
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,380 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for github.com/labstack/echo/v4, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: github.com/labstack/echo/v4 (exports: Context,Response; functions: )
// Package echo is a stub of github.com/labstack/echo/v4, generated by depstubber.
package echo
import (
bufio "bufio"
context "context"
io "io"
log "log"
multipart "mime/multipart"
net "net"
http "net/http"
url "net/url"
)
type Binder interface {
Bind(_ interface{}, _ Context) error
}
type Context interface {
Attachment(_ string, _ string) error
Bind(_ interface{}) error
Blob(_ int, _ string, _ []byte) error
Cookie(_ string) (*http.Cookie, error)
Cookies() []*http.Cookie
Echo() *Echo
Error(_ error)
File(_ string) error
FormFile(_ string) (*multipart.FileHeader, error)
FormParams() (url.Values, error)
FormValue(_ string) string
Get(_ string) interface{}
HTML(_ int, _ string) error
HTMLBlob(_ int, _ []byte) error
Handler() HandlerFunc
Inline(_ string, _ string) error
IsTLS() bool
IsWebSocket() bool
JSON(_ int, _ interface{}) error
JSONBlob(_ int, _ []byte) error
JSONP(_ int, _ string, _ interface{}) error
JSONPBlob(_ int, _ string, _ []byte) error
JSONPretty(_ int, _ interface{}, _ string) error
Logger() Logger
MultipartForm() (*multipart.Form, error)
NoContent(_ int) error
Param(_ string) string
ParamNames() []string
ParamValues() []string
Path() string
QueryParam(_ string) string
QueryParams() url.Values
QueryString() string
RealIP() string
Redirect(_ int, _ string) error
Render(_ int, _ string, _ interface{}) error
Request() *http.Request
Reset(_ *http.Request, _ http.ResponseWriter)
Response() *Response
Scheme() string
Set(_ string, _ interface{})
SetCookie(_ *http.Cookie)
SetHandler(_ HandlerFunc)
SetLogger(_ Logger)
SetParamNames(_ ...string)
SetParamValues(_ ...string)
SetPath(_ string)
SetRequest(_ *http.Request)
SetResponse(_ *Response)
Stream(_ int, _ string, _ io.Reader) error
String(_ int, _ string) error
Validate(_ interface{}) error
XML(_ int, _ interface{}) error
XMLBlob(_ int, _ []byte) error
XMLPretty(_ int, _ interface{}, _ string) error
}
type Echo struct {
StdLogger *log.Logger
Server *http.Server
TLSServer *http.Server
Listener net.Listener
TLSListener net.Listener
AutoTLSManager interface{}
DisableHTTP2 bool
Debug bool
HideBanner bool
HidePort bool
HTTPErrorHandler HTTPErrorHandler
Binder Binder
Validator Validator
Renderer Renderer
Logger Logger
IPExtractor IPExtractor
}
func (_ *Echo) AcquireContext() Context {
return nil
}
func (_ *Echo) Add(_ string, _ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) Any(_ string, _ HandlerFunc, _ ...MiddlewareFunc) []*Route {
return nil
}
func (_ *Echo) CONNECT(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) Close() error {
return nil
}
func (_ *Echo) DELETE(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) DefaultHTTPErrorHandler(_ error, _ Context) {}
func (_ *Echo) File(_ string, _ string, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) GET(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) Group(_ string, _ ...MiddlewareFunc) *Group {
return nil
}
func (_ *Echo) HEAD(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) Host(_ string, _ ...MiddlewareFunc) *Group {
return nil
}
func (_ *Echo) Match(_ []string, _ string, _ HandlerFunc, _ ...MiddlewareFunc) []*Route {
return nil
}
func (_ *Echo) NewContext(_ *http.Request, _ http.ResponseWriter) Context {
return nil
}
func (_ *Echo) OPTIONS(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) PATCH(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) POST(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) PUT(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) Pre(_ ...MiddlewareFunc) {}
func (_ *Echo) ReleaseContext(_ Context) {}
func (_ *Echo) Reverse(_ string, _ ...interface{}) string {
return ""
}
func (_ *Echo) Router() *Router {
return nil
}
func (_ *Echo) Routers() map[string]*Router {
return nil
}
func (_ *Echo) Routes() []*Route {
return nil
}
func (_ *Echo) ServeHTTP(_ http.ResponseWriter, _ *http.Request) {}
func (_ *Echo) Shutdown(_ context.Context) error {
return nil
}
func (_ *Echo) Start(_ string) error {
return nil
}
func (_ *Echo) StartAutoTLS(_ string) error {
return nil
}
func (_ *Echo) StartH2CServer(_ string, _ interface{}) error {
return nil
}
func (_ *Echo) StartServer(_ *http.Server) error {
return nil
}
func (_ *Echo) StartTLS(_ string, _ interface{}, _ interface{}) error {
return nil
}
func (_ *Echo) Static(_ string, _ string) *Route {
return nil
}
func (_ *Echo) TRACE(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Echo) URI(_ HandlerFunc, _ ...interface{}) string {
return ""
}
func (_ *Echo) URL(_ HandlerFunc, _ ...interface{}) string {
return ""
}
func (_ *Echo) Use(_ ...MiddlewareFunc) {}
type Group struct{}
func (_ *Group) Add(_ string, _ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Group) Any(_ string, _ HandlerFunc, _ ...MiddlewareFunc) []*Route {
return nil
}
func (_ *Group) CONNECT(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Group) DELETE(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Group) File(_ string, _ string) {}
func (_ *Group) GET(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Group) Group(_ string, _ ...MiddlewareFunc) *Group {
return nil
}
func (_ *Group) HEAD(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Group) Match(_ []string, _ string, _ HandlerFunc, _ ...MiddlewareFunc) []*Route {
return nil
}
func (_ *Group) OPTIONS(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Group) PATCH(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Group) POST(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Group) PUT(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Group) Static(_ string, _ string) {}
func (_ *Group) TRACE(_ string, _ HandlerFunc, _ ...MiddlewareFunc) *Route {
return nil
}
func (_ *Group) Use(_ ...MiddlewareFunc) {}
type HTTPErrorHandler func(error, Context)
type HandlerFunc func(Context) error
type IPExtractor func(*http.Request) string
type Logger interface {
Debug(_ ...interface{})
Debugf(_ string, _ ...interface{})
Debugj(_ interface{})
Error(_ ...interface{})
Errorf(_ string, _ ...interface{})
Errorj(_ interface{})
Fatal(_ ...interface{})
Fatalf(_ string, _ ...interface{})
Fatalj(_ interface{})
Info(_ ...interface{})
Infof(_ string, _ ...interface{})
Infoj(_ interface{})
Level() interface{}
Output() io.Writer
Panic(_ ...interface{})
Panicf(_ string, _ ...interface{})
Panicj(_ interface{})
Prefix() string
Print(_ ...interface{})
Printf(_ string, _ ...interface{})
Printj(_ interface{})
SetHeader(_ string)
SetLevel(_ interface{})
SetOutput(_ io.Writer)
SetPrefix(_ string)
Warn(_ ...interface{})
Warnf(_ string, _ ...interface{})
Warnj(_ interface{})
}
type MiddlewareFunc func(HandlerFunc) HandlerFunc
type Renderer interface {
Render(_ io.Writer, _ string, _ interface{}, _ Context) error
}
type Response struct {
Writer http.ResponseWriter
Status int
Size int64
Committed bool
}
func (_ *Response) After(_ func()) {}
func (_ *Response) Before(_ func()) {}
func (_ *Response) Flush() {}
func (_ *Response) Header() http.Header {
return nil
}
func (_ *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return nil, nil, nil
}
func (_ *Response) Write(_ []byte) (int, error) {
return 0, nil
}
func (_ *Response) WriteHeader(_ int) {}
type Route struct {
Method string
Path string
Name string
}
type Router struct{}
func (_ *Router) Add(_ string, _ string, _ HandlerFunc) {}
func (_ *Router) Find(_ string, _ string, _ Context) {}
type Validator interface {
Validate(_ interface{}) error
}

View File

@@ -0,0 +1,3 @@
# github.com/labstack/echo/v4 v4.1.17
## explicit
github.com/labstack/echo/v4