add query string in the request log
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
5346e68c5c
commit
d84612a425
|
@ -1,5 +1,9 @@
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## v1.1.0
|
||||||
|
### Added
|
||||||
|
- add query string in the request log
|
||||||
|
|
||||||
## v1.0.0
|
## v1.0.0
|
||||||
### Added
|
### Added
|
||||||
- remove "retry" button and add a button for each request in the list
|
- remove "retry" button and add a button for each request in the list
|
||||||
|
|
15
capture.go
15
capture.go
|
@ -27,12 +27,13 @@ type Capture struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Req struct {
|
type Req struct {
|
||||||
Proto string
|
Proto string `json:"proto"`
|
||||||
Method string
|
Method string `json:"method"`
|
||||||
Url string
|
Url string `json:"url"`
|
||||||
Path string
|
Path string `json:"path"`
|
||||||
Header http.Header
|
Query string `json:"query"`
|
||||||
Body []byte
|
Header http.Header `json:"header"`
|
||||||
|
Body []byte `json:"body"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Res struct {
|
type Res struct {
|
||||||
|
@ -54,6 +55,7 @@ type CaptureInfo struct {
|
||||||
type DashboardItem struct {
|
type DashboardItem struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
|
Query string `json:"query"`
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
|
|
||||||
|
@ -115,6 +117,7 @@ func (s *CaptureService) DashboardItems() []DashboardItem {
|
||||||
metadatas[i] = DashboardItem{
|
metadatas[i] = DashboardItem{
|
||||||
ID: capture.ID,
|
ID: capture.ID,
|
||||||
Path: capture.Req.Path,
|
Path: capture.Req.Path,
|
||||||
|
Query: capture.Req.Query,
|
||||||
Method: capture.Req.Method,
|
Method: capture.Req.Method,
|
||||||
Status: capture.Res.Code,
|
Status: capture.Res.Code,
|
||||||
Elapsed: capture.Elapsed,
|
Elapsed: capture.Elapsed,
|
||||||
|
|
|
@ -185,6 +185,14 @@
|
||||||
color: var(--disabled);
|
color: var(--disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.query {
|
||||||
|
padding: 1rem;
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.2em;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
@ -330,11 +338,11 @@
|
||||||
<div class="list-inner">
|
<div class="list-inner">
|
||||||
<div class="list-item" v-for="item in items" :key="item.id" @click="show(item)"
|
<div class="list-item" v-for="item in items" :key="item.id" @click="show(item)"
|
||||||
:class="{selected: selectedItem.id == item.id}">
|
:class="{selected: selectedItem.id == item.id}">
|
||||||
<span class="method" :class="item.method">{{item.method}}</span>
|
<span class="method" :class="item.method">{{ item.method }}</span>
|
||||||
<span class="path">‎{{item.path}}‎</span>
|
<span class="path">‎{{ item.path }}‎</span>
|
||||||
<span class="time">{{item.elapsed}}ms</span>
|
<span class="time">{{ item.elapsed }}ms</span>
|
||||||
<span class="status" :class="statusColor(item)">
|
<span class="status" :class="statusColor(item)">
|
||||||
{{item.status == 999 ? 'failed' : item.status}}
|
{{ item.status == 999 ? 'failed' : item.status }}
|
||||||
</span>
|
</span>
|
||||||
<button class="retry" @click="retry(item.id)">
|
<button class="retry" @click="retry(item.id)">
|
||||||
<svg stroke-width="3" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M21.888 13.5C21.164 18.311 17.013 22 12 22 6.477 22 2 17.523 2 12S6.477 2 12 2c4.1 0 7.625 2.468 9.168 6" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"></path><path d="M17 8h4.4a.6.6 0 00.6-.6V3" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"></path></svg>
|
<svg stroke-width="3" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M21.888 13.5C21.164 18.311 17.013 22 12 22 6.477 22 2 17.523 2 12S6.477 2 12 2c4.1 0 7.625 2.468 9.168 6" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"></path><path d="M17 8h4.4a.6.6 0 00.6-.6V3" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"></path></svg>
|
||||||
|
@ -350,7 +358,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="req-inner">
|
<div class="req-inner">
|
||||||
<div class="corner">req</div>
|
<div class="corner">req</div>
|
||||||
<pre>{{selectedItem.request}}</pre>
|
<pre>{{ selectedItem.request }}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -360,14 +368,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="res-inner">
|
<div class="res-inner">
|
||||||
<div class="corner">res</div>
|
<div class="corner">res</div>
|
||||||
<pre :class="{error: selectedItem.status == 999}">{{selectedItem.response}}</pre>
|
<pre :class="{error: selectedItem.status == 999}">{{ selectedItem.response }}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="welcome" v-show="items.length == 0">
|
<div class="welcome" v-show="items.length == 0">
|
||||||
<p>
|
<p>
|
||||||
Waiting for requests on http://localhost:{{proxyPort}}/<br>
|
Waiting for requests on http://localhost:{{proxyPort}}/<br>
|
||||||
<span>Proxying {{targetURL}}</span>
|
<span>Proxying {{ targetURL }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
20
main.go
20
main.go
|
@ -212,9 +212,11 @@ func NewRecorderHandler(srv *CaptureService, next http.HandlerFunc) http.Handler
|
||||||
Method: r.Method,
|
Method: r.Method,
|
||||||
Url: r.URL.String(),
|
Url: r.URL.String(),
|
||||||
Path: r.URL.Path,
|
Path: r.URL.Path,
|
||||||
|
Query: extractQueryString(r.RequestURI),
|
||||||
Header: r.Header,
|
Header: r.Header,
|
||||||
Body: reqBody.Bytes(),
|
Body: reqBody.Bytes(),
|
||||||
}
|
}
|
||||||
|
|
||||||
res := Res{
|
res := Res{
|
||||||
Proto: rec.Result().Proto,
|
Proto: rec.Result().Proto,
|
||||||
Status: rec.Result().Status,
|
Status: rec.Result().Status,
|
||||||
|
@ -246,8 +248,14 @@ func NewProxyHandler(URL string) http.HandlerFunc {
|
||||||
func dump(c *Capture) CaptureInfo {
|
func dump(c *Capture) CaptureInfo {
|
||||||
req := c.Req
|
req := c.Req
|
||||||
res := c.Res
|
res := c.Res
|
||||||
|
query := ""
|
||||||
|
|
||||||
|
if len(req.Query) > 1 {
|
||||||
|
query = "?" + req.Query
|
||||||
|
}
|
||||||
|
|
||||||
return CaptureInfo{
|
return CaptureInfo{
|
||||||
Request: dumpContent(req.Header, req.Body, "%s %s %s\n\n", req.Method, req.Path, req.Proto),
|
Request: dumpContent(req.Header, req.Body, "%s %s%s %s\n\n", req.Method, req.Path, query, req.Proto),
|
||||||
Response: dumpContent(res.Header, res.Body, "%s %s\n\n", res.Proto, res.Status),
|
Response: dumpContent(res.Header, res.Body, "%s %s\n\n", res.Proto, res.Status),
|
||||||
Curl: dumpCurl(req),
|
Curl: dumpCurl(req),
|
||||||
}
|
}
|
||||||
|
@ -296,3 +304,13 @@ func dumpCurl(req Req) string {
|
||||||
}
|
}
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractQueryString(uri string) string {
|
||||||
|
parts := strings.SplitN(uri, "?", 2)
|
||||||
|
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts[1]
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue