mirror of
https://github.com/chainreactors/spray.git
synced 2025-06-21 18:30:49 +00:00
commit
2f28b0ec3c
9
go.mod
9
go.mod
@ -6,9 +6,8 @@ require (
|
|||||||
github.com/chainreactors/files v0.0.0-20240716182835-7884ee1e77f0
|
github.com/chainreactors/files v0.0.0-20240716182835-7884ee1e77f0
|
||||||
github.com/chainreactors/fingers v0.0.0-20240716172449-2fc3147b9c2a
|
github.com/chainreactors/fingers v0.0.0-20240716172449-2fc3147b9c2a
|
||||||
github.com/chainreactors/logs v0.0.0-20240207121836-c946f072f81f
|
github.com/chainreactors/logs v0.0.0-20240207121836-c946f072f81f
|
||||||
github.com/chainreactors/parsers v0.0.0-20240829055950-923f89a92b84
|
github.com/chainreactors/parsers v0.0.0-20240910081704-fd57f462fc65
|
||||||
github.com/chainreactors/utils v0.0.0-20240805193040-ff3b97aa3c3f
|
github.com/chainreactors/utils v0.0.0-20240805193040-ff3b97aa3c3f
|
||||||
github.com/chainreactors/words v0.4.1-0.20240510105042-5ba5c2edc508
|
|
||||||
github.com/expr-lang/expr v1.16.9
|
github.com/expr-lang/expr v1.16.9
|
||||||
github.com/gookit/config/v2 v2.2.5
|
github.com/gookit/config/v2 v2.2.5
|
||||||
github.com/jessevdk/go-flags v1.5.0
|
github.com/jessevdk/go-flags v1.5.0
|
||||||
@ -25,6 +24,10 @@ require (
|
|||||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
|
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
|
||||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
|
github.com/chainreactors/words v0.0.0-20240910083848-19a289e8984b // indirect
|
||||||
|
github.com/charmbracelet/lipgloss v0.13.0 // indirect
|
||||||
|
github.com/charmbracelet/x/ansi v0.1.4 // indirect
|
||||||
github.com/facebookincubator/nvdtools v0.1.5 // indirect
|
github.com/facebookincubator/nvdtools v0.1.5 // indirect
|
||||||
github.com/fatih/color v1.17.0 // indirect
|
github.com/fatih/color v1.17.0 // indirect
|
||||||
github.com/go-dedup/megophone v0.0.0-20170830025436-f01be21026f5 // indirect
|
github.com/go-dedup/megophone v0.0.0-20170830025436-f01be21026f5 // indirect
|
||||||
@ -37,10 +40,12 @@ require (
|
|||||||
github.com/gookit/goutil v0.6.15 // indirect
|
github.com/gookit/goutil v0.6.15 // indirect
|
||||||
github.com/klauspost/compress v1.17.8 // indirect
|
github.com/klauspost/compress v1.17.8 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/muesli/termenv v0.15.2 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||||
|
18
go.sum
18
go.sum
@ -70,6 +70,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
|
|||||||
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
@ -97,14 +99,26 @@ github.com/chainreactors/parsers v0.0.0-20240825154421-240ad7eba29d h1:/rtYIkD9F
|
|||||||
github.com/chainreactors/parsers v0.0.0-20240825154421-240ad7eba29d/go.mod h1:7rXdYz6jrdjF0WUH1ICcAXKIKKjKmJo2PU8u43V7jkA=
|
github.com/chainreactors/parsers v0.0.0-20240825154421-240ad7eba29d/go.mod h1:7rXdYz6jrdjF0WUH1ICcAXKIKKjKmJo2PU8u43V7jkA=
|
||||||
github.com/chainreactors/parsers v0.0.0-20240829055950-923f89a92b84 h1:F6umsdHLxKILxrH5wY2zVYwxMmb8XdCEc9apf7GWpOk=
|
github.com/chainreactors/parsers v0.0.0-20240829055950-923f89a92b84 h1:F6umsdHLxKILxrH5wY2zVYwxMmb8XdCEc9apf7GWpOk=
|
||||||
github.com/chainreactors/parsers v0.0.0-20240829055950-923f89a92b84/go.mod h1:7rXdYz6jrdjF0WUH1ICcAXKIKKjKmJo2PU8u43V7jkA=
|
github.com/chainreactors/parsers v0.0.0-20240829055950-923f89a92b84/go.mod h1:7rXdYz6jrdjF0WUH1ICcAXKIKKjKmJo2PU8u43V7jkA=
|
||||||
|
github.com/chainreactors/parsers v0.0.0-20240910081704-fd57f462fc65 h1:subSvyczsErYMRnCD07s4Ub6zOSaw2xZ1/O9t3tHkuw=
|
||||||
|
github.com/chainreactors/parsers v0.0.0-20240910081704-fd57f462fc65/go.mod h1:7rXdYz6jrdjF0WUH1ICcAXKIKKjKmJo2PU8u43V7jkA=
|
||||||
github.com/chainreactors/utils v0.0.0-20240528085651-ba1b255482c1/go.mod h1:JA4eiQZm+7AsfjXBcIzIdVKBEhDCb16eNtWFCGTxlvs=
|
github.com/chainreactors/utils v0.0.0-20240528085651-ba1b255482c1/go.mod h1:JA4eiQZm+7AsfjXBcIzIdVKBEhDCb16eNtWFCGTxlvs=
|
||||||
github.com/chainreactors/utils v0.0.0-20240704062557-662d623b74f4/go.mod h1:JA4eiQZm+7AsfjXBcIzIdVKBEhDCb16eNtWFCGTxlvs=
|
github.com/chainreactors/utils v0.0.0-20240704062557-662d623b74f4/go.mod h1:JA4eiQZm+7AsfjXBcIzIdVKBEhDCb16eNtWFCGTxlvs=
|
||||||
github.com/chainreactors/utils v0.0.0-20240715080349-d2d0484c95ed/go.mod h1:LajXuvESQwP+qCMAvlcoSXppQCjuLlBrnQpu9XQ1HtU=
|
github.com/chainreactors/utils v0.0.0-20240715080349-d2d0484c95ed/go.mod h1:LajXuvESQwP+qCMAvlcoSXppQCjuLlBrnQpu9XQ1HtU=
|
||||||
github.com/chainreactors/utils v0.0.0-20240716182459-e85f2b01ee16/go.mod h1:LajXuvESQwP+qCMAvlcoSXppQCjuLlBrnQpu9XQ1HtU=
|
github.com/chainreactors/utils v0.0.0-20240716182459-e85f2b01ee16/go.mod h1:LajXuvESQwP+qCMAvlcoSXppQCjuLlBrnQpu9XQ1HtU=
|
||||||
github.com/chainreactors/utils v0.0.0-20240805193040-ff3b97aa3c3f h1:2NKmadFYP9vCwC0YrazgttFACleOhxScTPzg0i76YAY=
|
github.com/chainreactors/utils v0.0.0-20240805193040-ff3b97aa3c3f h1:2NKmadFYP9vCwC0YrazgttFACleOhxScTPzg0i76YAY=
|
||||||
github.com/chainreactors/utils v0.0.0-20240805193040-ff3b97aa3c3f/go.mod h1:LajXuvESQwP+qCMAvlcoSXppQCjuLlBrnQpu9XQ1HtU=
|
github.com/chainreactors/utils v0.0.0-20240805193040-ff3b97aa3c3f/go.mod h1:LajXuvESQwP+qCMAvlcoSXppQCjuLlBrnQpu9XQ1HtU=
|
||||||
|
github.com/chainreactors/words v0.0.0-20240910083135-4b34aa283ee2 h1:7hVdyBKy8Obs4faaVhnQX1cUwZizeIA6wKHHX5OZTjA=
|
||||||
|
github.com/chainreactors/words v0.0.0-20240910083135-4b34aa283ee2/go.mod h1:zfz367PUmyaX6oAqV9SktVqyRXKlEh0sel9Wsq9dd2c=
|
||||||
|
github.com/chainreactors/words v0.0.0-20240910083848-19a289e8984b h1:OsZ1fyarW4NwK/Oi+Yf3nm/dTW0uX0UfxFjyky5Mb60=
|
||||||
|
github.com/chainreactors/words v0.0.0-20240910083848-19a289e8984b/go.mod h1:zfz367PUmyaX6oAqV9SktVqyRXKlEh0sel9Wsq9dd2c=
|
||||||
github.com/chainreactors/words v0.4.1-0.20240510105042-5ba5c2edc508 h1:iT4HWkoZzUAfQYcQMRH8XyrMau9tCVE0zSuFQnkhrqw=
|
github.com/chainreactors/words v0.4.1-0.20240510105042-5ba5c2edc508 h1:iT4HWkoZzUAfQYcQMRH8XyrMau9tCVE0zSuFQnkhrqw=
|
||||||
github.com/chainreactors/words v0.4.1-0.20240510105042-5ba5c2edc508/go.mod h1:DUDx7PdsMEm5PvVhzkFyppzpiUhQb8dOJaWjVc1SMVk=
|
github.com/chainreactors/words v0.4.1-0.20240510105042-5ba5c2edc508/go.mod h1:DUDx7PdsMEm5PvVhzkFyppzpiUhQb8dOJaWjVc1SMVk=
|
||||||
|
github.com/chainreactors/words v0.4.1-0.20240910075300-24fe4facd5a6 h1:QpUlRyzw5wn9avRbTHBKRhV06X79Yj/ghGKn2Gyb9v4=
|
||||||
|
github.com/chainreactors/words v0.4.1-0.20240910075300-24fe4facd5a6/go.mod h1:zfz367PUmyaX6oAqV9SktVqyRXKlEh0sel9Wsq9dd2c=
|
||||||
|
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
|
||||||
|
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
|
||||||
|
github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM=
|
||||||
|
github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
@ -324,6 +338,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
|
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
|
||||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
@ -361,6 +377,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
|||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||||
|
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/panjf2000/ants/v2 v2.9.1 h1:Q5vh5xohbsZXGcD6hhszzGqB7jSSc2/CRr3QKIga8Kw=
|
github.com/panjf2000/ants/v2 v2.9.1 h1:Q5vh5xohbsZXGcD6hhszzGqB7jSSc2/CRr3QKIga8Kw=
|
||||||
github.com/panjf2000/ants/v2 v2.9.1/go.mod h1:7ZxyxsqE4vvW0M7LSD8aI3cKwgFhBHbxnlN8mDqHa1I=
|
github.com/panjf2000/ants/v2 v2.9.1/go.mod h1:7ZxyxsqE4vvW0M7LSD8aI3cKwgFhBHbxnlN8mDqHa1I=
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package ihttp
|
package ihttp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/chainreactors/logs"
|
"github.com/chainreactors/logs"
|
||||||
@ -56,7 +55,7 @@ func NewClient(config *ClientConfig) *Client {
|
|||||||
DisablePathNormalizing: true,
|
DisablePathNormalizing: true,
|
||||||
DisableHeaderNamesNormalizing: true,
|
DisableHeaderNamesNormalizing: true,
|
||||||
},
|
},
|
||||||
Config: config,
|
ClientConfig: config,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
client = &Client{
|
client = &Client{
|
||||||
@ -76,7 +75,7 @@ func NewClient(config *ClientConfig) *Client {
|
|||||||
return http.ErrUseLastResponse
|
return http.ErrUseLastResponse
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Config: config,
|
ClientConfig: config,
|
||||||
}
|
}
|
||||||
if config.ProxyAddr != "" {
|
if config.ProxyAddr != "" {
|
||||||
client.standardClient.Transport.(*http.Transport).Proxy = func(_ *http.Request) (*url.URL, error) {
|
client.standardClient.Transport.(*http.Transport).Proxy = func(_ *http.Request) (*url.URL, error) {
|
||||||
@ -97,7 +96,7 @@ type ClientConfig struct {
|
|||||||
type Client struct {
|
type Client struct {
|
||||||
fastClient *fasthttp.Client
|
fastClient *fasthttp.Client
|
||||||
standardClient *http.Client
|
standardClient *http.Client
|
||||||
Config *ClientConfig
|
*ClientConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) TransToCheck() {
|
func (c *Client) TransToCheck() {
|
||||||
@ -108,22 +107,22 @@ func (c *Client) TransToCheck() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) FastDo(ctx context.Context, req *fasthttp.Request) (*fasthttp.Response, error) {
|
func (c *Client) FastDo(req *fasthttp.Request) (*fasthttp.Response, error) {
|
||||||
resp := fasthttp.AcquireResponse()
|
resp := fasthttp.AcquireResponse()
|
||||||
err := c.fastClient.Do(req, resp)
|
err := c.fastClient.DoTimeout(req, resp, c.Timeout)
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) StandardDo(ctx context.Context, req *http.Request) (*http.Response, error) {
|
func (c *Client) StandardDo(req *http.Request) (*http.Response, error) {
|
||||||
return c.standardClient.Do(req)
|
return c.standardClient.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Do(ctx context.Context, req *Request) (*Response, error) {
|
func (c *Client) Do(req *Request) (*Response, error) {
|
||||||
if c.fastClient != nil {
|
if c.fastClient != nil {
|
||||||
resp, err := c.FastDo(ctx, req.FastRequest)
|
resp, err := c.FastDo(req.FastRequest)
|
||||||
return &Response{FastResponse: resp, ClientType: FAST}, err
|
return &Response{FastResponse: resp, ClientType: FAST}, err
|
||||||
} else if c.standardClient != nil {
|
} else if c.standardClient != nil {
|
||||||
resp, err := c.StandardDo(ctx, req.StandardRequest)
|
resp, err := c.StandardDo(req.StandardRequest)
|
||||||
return &Response{StandardResponse: resp, ClientType: STANDARD}, err
|
return &Response{StandardResponse: resp, ClientType: STANDARD}, err
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("not found client")
|
return nil, fmt.Errorf("not found client")
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package ihttp
|
package ihttp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BuildRequest(clientType int, base, path, host, method string) (*Request, error) {
|
func BuildRequest(ctx context.Context, clientType int, base, path, host, method string) (*Request, error) {
|
||||||
if clientType == FAST {
|
if clientType == FAST {
|
||||||
req := fasthttp.AcquireRequest()
|
req := fasthttp.AcquireRequest()
|
||||||
req.Header.SetMethod(method)
|
req.Header.SetMethod(method)
|
||||||
@ -15,7 +16,7 @@ func BuildRequest(clientType int, base, path, host, method string) (*Request, er
|
|||||||
}
|
}
|
||||||
return &Request{FastRequest: req, ClientType: FAST}, nil
|
return &Request{FastRequest: req, ClientType: FAST}, nil
|
||||||
} else {
|
} else {
|
||||||
req, err := http.NewRequest(method, base+path, nil)
|
req, err := http.NewRequestWithContext(ctx, method, base+path, nil)
|
||||||
if host != "" {
|
if host != "" {
|
||||||
req.Host = host
|
req.Host = host
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/chainreactors/utils/iutils"
|
"github.com/chainreactors/utils/iutils"
|
||||||
"github.com/chainreactors/words/mask"
|
"github.com/chainreactors/words/mask"
|
||||||
"github.com/chainreactors/words/rule"
|
"github.com/chainreactors/words/rule"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
"github.com/expr-lang/expr"
|
"github.com/expr-lang/expr"
|
||||||
"github.com/vbauerster/mpb/v8"
|
"github.com/vbauerster/mpb/v8"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -30,7 +31,6 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
DefaultThreads = 20
|
DefaultThreads = 20
|
||||||
SkipChar = "%SKIP%"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Option struct {
|
type Option struct {
|
||||||
@ -305,10 +305,6 @@ func (opt *Option) NewRunner() (*Runner, error) {
|
|||||||
r.ClientType = ihttp.STANDARD
|
r.ClientType = ihttp.STANDARD
|
||||||
}
|
}
|
||||||
|
|
||||||
if opt.Threads == DefaultThreads && len(opt.Dictionaries) == 0 {
|
|
||||||
r.Threads = 1000
|
|
||||||
}
|
|
||||||
|
|
||||||
err = opt.BuildPlugin(r)
|
err = opt.BuildPlugin(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -319,6 +315,10 @@ func (opt *Option) NewRunner() (*Runner, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opt.Threads == DefaultThreads && r.bruteMod {
|
||||||
|
r.Threads = 1000
|
||||||
|
}
|
||||||
|
|
||||||
pkg.DefaultStatistor = pkg.Statistor{
|
pkg.DefaultStatistor = pkg.Statistor{
|
||||||
Word: opt.Word,
|
Word: opt.Word,
|
||||||
WordCount: len(r.Wordlist),
|
WordCount: len(r.Wordlist),
|
||||||
@ -393,6 +393,8 @@ func (opt *Option) NewRunner() (*Runner, error) {
|
|||||||
r.Probes = strings.Split(opt.OutputProbe, ",")
|
r.Probes = strings.Split(opt.OutputProbe, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Println(opt.PrintConfig(r))
|
||||||
|
|
||||||
// init output file
|
// init output file
|
||||||
if opt.OutputFile != "" {
|
if opt.OutputFile != "" {
|
||||||
r.OutputFile, err = files.NewFile(opt.OutputFile, false, false, true)
|
r.OutputFile, err = files.NewFile(opt.OutputFile, false, false, true)
|
||||||
@ -436,30 +438,136 @@ func (opt *Option) NewRunner() (*Runner, error) {
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opt *Option) PrintPlugin() {
|
func (opt *Option) PrintConfig(r *Runner) string {
|
||||||
var s strings.Builder
|
// 定义颜色样式
|
||||||
if opt.CrawlPlugin {
|
keyStyle := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#FFFFFF")).Width(20) // Key 加粗并设定宽度
|
||||||
s.WriteString("crawl enable; ")
|
stringValueStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#FFA07A")) // 字符串样式
|
||||||
}
|
arrayValueStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#98FB98")) // 数组样式
|
||||||
if opt.Finger {
|
numberValueStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#ADD8E6")) // 数字样式
|
||||||
s.WriteString("active fingerprint enable; ")
|
panelWidth := 60 // 调整 panelWidth 使内容稍微靠左
|
||||||
}
|
padding := 2 // 减少 padding 以调整布局靠左
|
||||||
if opt.BakPlugin {
|
|
||||||
s.WriteString("bak file enable; ")
|
// 分割线样式和终端宽度计算
|
||||||
}
|
divider := strings.Repeat("─", panelWidth) // 使用"─"符号生成更加连贯的分割线
|
||||||
if opt.CommonPlugin {
|
|
||||||
s.WriteString("common file enable; ")
|
// 处理不同类型的值
|
||||||
}
|
formatValue := func(value interface{}) string {
|
||||||
if opt.ReconPlugin {
|
switch v := value.(type) {
|
||||||
s.WriteString("recon enable; ")
|
case string:
|
||||||
}
|
return stringValueStyle.Render(v)
|
||||||
if opt.RetryCount > 0 {
|
case []string:
|
||||||
s.WriteString("Retry Count: " + strconv.Itoa(opt.RetryCount))
|
return arrayValueStyle.Render(fmt.Sprintf("%v", v))
|
||||||
|
case int, int64, float64:
|
||||||
|
return numberValueStyle.Render(fmt.Sprintf("%v", v))
|
||||||
|
default:
|
||||||
|
return stringValueStyle.Render(fmt.Sprintf("%v", v)) // 默认为字符串样式
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Len() > 0 {
|
// 处理互斥参数,选择输出有值的那一个
|
||||||
logs.Log.Important(s.String())
|
inputSource := ""
|
||||||
|
if opt.ResumeFrom != "" {
|
||||||
|
inputSource = lipgloss.JoinHorizontal(lipgloss.Left, "🌀 ", keyStyle.Render("ResumeFrom: "), formatValue(opt.ResumeFrom))
|
||||||
|
} else if len(opt.URL) > 0 {
|
||||||
|
inputSource = lipgloss.JoinHorizontal(lipgloss.Left, "🌐 ", keyStyle.Render("URL: "), formatValue(opt.URL))
|
||||||
|
} else if opt.URLFile != "" {
|
||||||
|
inputSource = lipgloss.JoinHorizontal(lipgloss.Left, "📂 ", keyStyle.Render("URLFile: "), formatValue(opt.URLFile))
|
||||||
|
} else if len(opt.CIDRs) > 0 {
|
||||||
|
inputSource = lipgloss.JoinHorizontal(lipgloss.Left, "📡 ", keyStyle.Render("CIDRs: "), formatValue(opt.CIDRs))
|
||||||
|
} else if opt.RawFile != "" {
|
||||||
|
inputSource = lipgloss.JoinHorizontal(lipgloss.Left, "📄 ", keyStyle.Render("RawFile: "), formatValue(opt.RawFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Input Options
|
||||||
|
inputOptions := lipgloss.JoinVertical(lipgloss.Left,
|
||||||
|
inputSource, // 互斥量处理
|
||||||
|
|
||||||
|
// PortRange 展示
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🔢 ", keyStyle.Render("PortRange: "), formatValue(opt.PortRange)),
|
||||||
|
|
||||||
|
// Dictionaries 展示
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "📚 ", keyStyle.Render("Dictionaries: "), formatValue(opt.Dictionaries)),
|
||||||
|
|
||||||
|
// Word, Rules, FilterRule 展开为单独的行
|
||||||
|
lipgloss.JoinVertical(lipgloss.Left,
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "💡 ", keyStyle.Render("Word: "), formatValue(r.Word)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "📜 ", keyStyle.Render("Rules: "), formatValue(opt.Rules)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🔍 ", keyStyle.Render("FilterRule: "), formatValue(opt.FilterRule)),
|
||||||
|
),
|
||||||
|
|
||||||
|
// AppendRule 和 AppendWords 展开为单独的行
|
||||||
|
lipgloss.JoinVertical(lipgloss.Left,
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🔧 ", keyStyle.Render("AppendRule: "), formatValue(r.AppendRule)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🧩 ", keyStyle.Render("AppendWords: "), formatValue(len(r.AppendWords))),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Output Options
|
||||||
|
outputOptions := lipgloss.JoinVertical(lipgloss.Left,
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "📊 ", keyStyle.Render("Match: "), formatValue(opt.Match)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "⚙️ ", keyStyle.Render("Filter: "), formatValue(opt.Filter)),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Plugin Options
|
||||||
|
pluginValues := []string{}
|
||||||
|
if opt.ActivePlugin {
|
||||||
|
pluginValues = append(pluginValues, "active")
|
||||||
|
}
|
||||||
|
if opt.ReconPlugin {
|
||||||
|
pluginValues = append(pluginValues, "recon")
|
||||||
|
}
|
||||||
|
if opt.BakPlugin {
|
||||||
|
pluginValues = append(pluginValues, "bak")
|
||||||
|
}
|
||||||
|
if opt.CommonPlugin {
|
||||||
|
pluginValues = append(pluginValues, "common")
|
||||||
|
}
|
||||||
|
if opt.CrawlPlugin {
|
||||||
|
pluginValues = append(pluginValues, "crawl")
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginOptions := lipgloss.JoinVertical(lipgloss.Left,
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🔎 ", keyStyle.Render("Extracts: "), formatValue(opt.Extracts)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🔌 ", keyStyle.Render("Plugins: "), formatValue(strings.Join(pluginValues, ", "))),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mode Options
|
||||||
|
modeOptions := lipgloss.JoinVertical(lipgloss.Left,
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🛑 ", keyStyle.Render("BlackStatus: "), formatValue(pkg.BlackStatus)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "✅ ", keyStyle.Render("WhiteStatus: "), formatValue(pkg.WhiteStatus)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🔄 ", keyStyle.Render("FuzzyStatus: "), formatValue(pkg.FuzzyStatus)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🔒 ", keyStyle.Render("UniqueStatus: "), formatValue(pkg.UniqueStatus)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🔑 ", keyStyle.Render("Unique: "), formatValue(opt.Unique)),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Misc Options
|
||||||
|
miscOptions := lipgloss.JoinVertical(lipgloss.Left,
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "⏱ ", keyStyle.Render("Timeout: "), formatValue(opt.Timeout)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "📈 ", keyStyle.Render("PoolSize: "), formatValue(opt.PoolSize)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🧵 ", keyStyle.Render("Threads: "), formatValue(opt.Threads)),
|
||||||
|
lipgloss.JoinHorizontal(lipgloss.Left, "🌍 ", keyStyle.Render("Proxy: "), formatValue(opt.Proxy)),
|
||||||
|
)
|
||||||
|
|
||||||
|
// 将所有内容拼接在一起
|
||||||
|
content := lipgloss.JoinVertical(lipgloss.Left,
|
||||||
|
inputOptions,
|
||||||
|
outputOptions,
|
||||||
|
pluginOptions,
|
||||||
|
modeOptions,
|
||||||
|
miscOptions,
|
||||||
|
)
|
||||||
|
|
||||||
|
// 使用正确的方式添加 padding,并居中显示内容
|
||||||
|
contentWithPadding := lipgloss.NewStyle().PaddingLeft(padding).Render(content)
|
||||||
|
|
||||||
|
// 使用 Place 方法来将整个内容居中显示
|
||||||
|
return lipgloss.Place(panelWidth+padding*2, 0, lipgloss.Center, lipgloss.Center,
|
||||||
|
lipgloss.JoinVertical(lipgloss.Center,
|
||||||
|
divider, // 顶部分割线
|
||||||
|
contentWithPadding,
|
||||||
|
divider, // 底部分割线
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opt *Option) BuildPlugin(r *Runner) error {
|
func (opt *Option) BuildPlugin(r *Runner) error {
|
||||||
@ -502,7 +610,6 @@ func (opt *Option) BuildPlugin(r *Runner) error {
|
|||||||
r.bruteMod = true
|
r.bruteMod = true
|
||||||
}
|
}
|
||||||
|
|
||||||
opt.PrintPlugin()
|
|
||||||
if r.bruteMod {
|
if r.bruteMod {
|
||||||
logs.Log.Important("enabling brute mod, because of enabled brute plugin")
|
logs.Log.Important("enabling brute mod, because of enabled brute plugin")
|
||||||
}
|
}
|
||||||
@ -614,19 +721,10 @@ func (opt *Option) BuildWords(r *Runner) error {
|
|||||||
|
|
||||||
// 类似dirsearch中的
|
// 类似dirsearch中的
|
||||||
if opt.Extensions != "" {
|
if opt.Extensions != "" {
|
||||||
r.AppendFunction(func(s string) []string {
|
r.AppendFunction(pkg.ParseEXTPlaceholderFunc(strings.Split(opt.Extensions, ",")))
|
||||||
exts := strings.Split(opt.Extensions, ",")
|
|
||||||
ss := make([]string, len(exts))
|
|
||||||
for i, e := range exts {
|
|
||||||
if strings.Contains(s, "%EXT%") {
|
|
||||||
ss[i] = strings.Replace(s, "%EXT%", e, -1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ss
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
r.AppendFunction(func(s string) []string {
|
r.AppendFunction(func(s string) []string {
|
||||||
if strings.Contains(s, "%EXT%") {
|
if strings.Contains(s, pkg.EXTChar) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return []string{s}
|
return []string{s}
|
||||||
@ -669,13 +767,6 @@ func (opt *Option) BuildWords(r *Runner) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// default skip function, skip %EXT%
|
|
||||||
r.AppendFunction(func(s string) []string {
|
|
||||||
if strings.Contains(s, "%EXT%") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return []string{s}
|
|
||||||
})
|
|
||||||
if len(opt.Skips) > 0 {
|
if len(opt.Skips) > 0 {
|
||||||
r.AppendFunction(func(s string) []string {
|
r.AppendFunction(func(s string) []string {
|
||||||
for _, skip := range opt.Skips {
|
for _, skip := range opt.Skips {
|
||||||
@ -687,7 +778,6 @@ func (opt *Option) BuildWords(r *Runner) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
logs.Log.Importantf("%s mod, Loaded %d dictionaries, %d rules and %d decorators", opt.Mod, len(opt.Dictionaries), len(opt.Rules), len(r.Fns))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"github.com/chainreactors/spray/internal/ihttp"
|
"github.com/chainreactors/spray/internal/ihttp"
|
||||||
"github.com/chainreactors/spray/pkg"
|
"github.com/chainreactors/spray/pkg"
|
||||||
"github.com/chainreactors/utils/iutils"
|
"github.com/chainreactors/utils/iutils"
|
||||||
"github.com/chainreactors/words"
|
|
||||||
"github.com/chainreactors/words/rule"
|
"github.com/chainreactors/words/rule"
|
||||||
"github.com/panjf2000/ants/v2"
|
"github.com/panjf2000/ants/v2"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
@ -48,7 +47,7 @@ func NewBrutePool(ctx context.Context, config *Config) (*BrutePool, error) {
|
|||||||
client: ihttp.NewClient(&ihttp.ClientConfig{
|
client: ihttp.NewClient(&ihttp.ClientConfig{
|
||||||
Thread: config.Thread,
|
Thread: config.Thread,
|
||||||
Type: config.ClientType,
|
Type: config.ClientType,
|
||||||
Timeout: time.Duration(config.Timeout) * time.Second,
|
Timeout: config.Timeout,
|
||||||
ProxyAddr: config.ProxyAddr,
|
ProxyAddr: config.ProxyAddr,
|
||||||
}),
|
}),
|
||||||
additionCh: make(chan *Unit, config.Thread),
|
additionCh: make(chan *Unit, config.Thread),
|
||||||
@ -167,7 +166,7 @@ func (pool *BrutePool) Init() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pool *BrutePool) Run(ctx context.Context, offset, limit int) {
|
func (pool *BrutePool) Run(offset, limit int) {
|
||||||
pool.Worder.Run()
|
pool.Worder.Run()
|
||||||
if pool.Active {
|
if pool.Active {
|
||||||
pool.wg.Add(1)
|
pool.wg.Add(1)
|
||||||
@ -200,7 +199,7 @@ func (pool *BrutePool) Run(ctx context.Context, offset, limit int) {
|
|||||||
Loop:
|
Loop:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case w, ok := <-pool.Worder.C:
|
case w, ok := <-pool.Worder.Output:
|
||||||
if !ok {
|
if !ok {
|
||||||
done = true
|
done = true
|
||||||
continue
|
continue
|
||||||
@ -250,8 +249,6 @@ Loop:
|
|||||||
}
|
}
|
||||||
case <-pool.closeCh:
|
case <-pool.closeCh:
|
||||||
break Loop
|
break Loop
|
||||||
case <-ctx.Done():
|
|
||||||
break Loop
|
|
||||||
case <-pool.ctx.Done():
|
case <-pool.ctx.Done():
|
||||||
break Loop
|
break Loop
|
||||||
}
|
}
|
||||||
@ -271,7 +268,7 @@ func (pool *BrutePool) Invoke(v interface{}) {
|
|||||||
var req *ihttp.Request
|
var req *ihttp.Request
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
req, err = ihttp.BuildRequest(pool.ClientType, pool.BaseURL, unit.path, unit.host, pool.Method)
|
req, err = ihttp.BuildRequest(pool.ctx, pool.ClientType, pool.BaseURL, unit.path, unit.host, pool.Method)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Log.Error(err.Error())
|
logs.Log.Error(err.Error())
|
||||||
return
|
return
|
||||||
@ -283,7 +280,7 @@ func (pool *BrutePool) Invoke(v interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
resp, reqerr := pool.client.Do(pool.ctx, req)
|
resp, reqerr := pool.client.Do(req)
|
||||||
if pool.ClientType == ihttp.FAST {
|
if pool.ClientType == ihttp.FAST {
|
||||||
defer fasthttp.ReleaseResponse(resp.FastResponse)
|
defer fasthttp.ReleaseResponse(resp.FastResponse)
|
||||||
defer fasthttp.ReleaseRequest(req.FastRequest)
|
defer fasthttp.ReleaseRequest(req.FastRequest)
|
||||||
@ -334,21 +331,28 @@ func (pool *BrutePool) Invoke(v interface{}) {
|
|||||||
bl.Spended = time.Since(start).Milliseconds()
|
bl.Spended = time.Since(start).Milliseconds()
|
||||||
switch unit.source {
|
switch unit.source {
|
||||||
case parsers.InitRandomSource:
|
case parsers.InitRandomSource:
|
||||||
bl.Collect()
|
defer pool.initwg.Done()
|
||||||
pool.locker.Lock()
|
pool.locker.Lock()
|
||||||
pool.random = bl
|
pool.random = bl
|
||||||
pool.addFuzzyBaseline(bl)
|
if !bl.IsValid {
|
||||||
|
return
|
||||||
|
}
|
||||||
pool.locker.Unlock()
|
pool.locker.Unlock()
|
||||||
pool.initwg.Done()
|
|
||||||
case parsers.InitIndexSource:
|
|
||||||
bl.Collect()
|
bl.Collect()
|
||||||
|
pool.addFuzzyBaseline(bl)
|
||||||
|
|
||||||
|
case parsers.InitIndexSource:
|
||||||
|
defer pool.initwg.Done()
|
||||||
pool.locker.Lock()
|
pool.locker.Lock()
|
||||||
pool.index = bl
|
pool.index = bl
|
||||||
pool.locker.Unlock()
|
pool.locker.Unlock()
|
||||||
|
if !bl.IsValid {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bl.Collect()
|
||||||
pool.doCrawl(bl)
|
pool.doCrawl(bl)
|
||||||
pool.doAppend(bl)
|
pool.doAppend(bl)
|
||||||
pool.putToOutput(bl)
|
pool.putToOutput(bl)
|
||||||
pool.initwg.Done()
|
|
||||||
case parsers.CheckSource:
|
case parsers.CheckSource:
|
||||||
if bl.ErrString != "" {
|
if bl.ErrString != "" {
|
||||||
logs.Log.Warnf("[check.error] %s maybe ip had banned, break (%d/%d), error: %s", pool.BaseURL, pool.failedCount, pool.BreakThreshold, bl.ErrString)
|
logs.Log.Warnf("[check.error] %s maybe ip had banned, break (%d/%d), error: %s", pool.BaseURL, pool.failedCount, pool.BreakThreshold, bl.ErrString)
|
||||||
@ -390,14 +394,14 @@ func (pool *BrutePool) Invoke(v interface{}) {
|
|||||||
func (pool *BrutePool) NoScopeInvoke(v interface{}) {
|
func (pool *BrutePool) NoScopeInvoke(v interface{}) {
|
||||||
defer pool.wg.Done()
|
defer pool.wg.Done()
|
||||||
unit := v.(*Unit)
|
unit := v.(*Unit)
|
||||||
req, err := ihttp.BuildRequest(pool.ClientType, unit.path, "", "", "GET")
|
req, err := ihttp.BuildRequest(pool.ctx, pool.ClientType, unit.path, "", "", "GET")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Log.Error(err.Error())
|
logs.Log.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.SetHeaders(pool.Headers)
|
req.SetHeaders(pool.Headers)
|
||||||
req.SetHeader("User-Agent", pkg.RandomUA())
|
req.SetHeader("User-Agent", pkg.RandomUA())
|
||||||
resp, reqerr := pool.client.Do(pool.ctx, req)
|
resp, reqerr := pool.client.Do(req)
|
||||||
if pool.ClientType == ihttp.FAST {
|
if pool.ClientType == ihttp.FAST {
|
||||||
defer fasthttp.ReleaseResponse(resp.FastResponse)
|
defer fasthttp.ReleaseResponse(resp.FastResponse)
|
||||||
defer fasthttp.ReleaseRequest(req.FastRequest)
|
defer fasthttp.ReleaseRequest(req.FastRequest)
|
||||||
@ -509,7 +513,7 @@ func (pool *BrutePool) Handler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pool *BrutePool) doAppendRule(bl *pkg.Baseline) {
|
func (pool *BrutePool) doAppendRule(bl *pkg.Baseline) {
|
||||||
if pool.AppendRule == nil || bl.Source == parsers.RuleSource {
|
if pool.AppendRule == nil || bl.Source == parsers.AppendRuleSource {
|
||||||
pool.wg.Done()
|
pool.wg.Done()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -520,7 +524,7 @@ func (pool *BrutePool) doAppendRule(bl *pkg.Baseline) {
|
|||||||
pool.addAddition(&Unit{
|
pool.addAddition(&Unit{
|
||||||
path: pkg.Dir(bl.Url.Path) + u,
|
path: pkg.Dir(bl.Url.Path) + u,
|
||||||
host: bl.Host,
|
host: bl.Host,
|
||||||
source: parsers.RuleSource,
|
source: parsers.AppendRuleSource,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -535,7 +539,8 @@ func (pool *BrutePool) doAppendWords(bl *pkg.Baseline) {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer pool.wg.Done()
|
defer pool.wg.Done()
|
||||||
for _, u := range pool.AppendWords {
|
|
||||||
|
for u := range NewBruteWords(pool.Config, pool.AppendWords).Output {
|
||||||
pool.addAddition(&Unit{
|
pool.addAddition(&Unit{
|
||||||
path: pkg.SafePath(bl.Path, u),
|
path: pkg.SafePath(bl.Path, u),
|
||||||
host: bl.Host,
|
host: bl.Host,
|
||||||
@ -569,13 +574,7 @@ func (pool *BrutePool) doCommonFile() {
|
|||||||
if pool.Mod == HostSpray {
|
if pool.Mod == HostSpray {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, u := range pkg.Dicts["common"] {
|
for u := range NewBruteWords(pool.Config, append(pkg.Dicts["common"], pkg.Dicts["log"]...)).Output {
|
||||||
pool.addAddition(&Unit{
|
|
||||||
path: pool.dir + u,
|
|
||||||
source: parsers.CommonFileSource,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
for _, u := range pkg.Dicts["log"] {
|
|
||||||
pool.addAddition(&Unit{
|
pool.addAddition(&Unit{
|
||||||
path: pool.dir + u,
|
path: pool.dir + u,
|
||||||
source: parsers.CommonFileSource,
|
source: parsers.CommonFileSource,
|
||||||
@ -721,7 +720,8 @@ func (pool *BrutePool) Close() {
|
|||||||
close(pool.additionCh) // 关闭addition管道
|
close(pool.additionCh) // 关闭addition管道
|
||||||
close(pool.checkCh) // 关闭check管道
|
close(pool.checkCh) // 关闭check管道
|
||||||
pool.Statistor.EndTime = time.Now().Unix()
|
pool.Statistor.EndTime = time.Now().Unix()
|
||||||
pool.Bar.Close()
|
pool.reqPool.Release()
|
||||||
|
pool.scopePool.Release()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pool *BrutePool) safePath(u string) string {
|
func (pool *BrutePool) safePath(u string) string {
|
||||||
@ -814,24 +814,14 @@ func (pool *BrutePool) doBak() {
|
|||||||
if pool.Mod == HostSpray {
|
if pool.Mod == HostSpray {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
worder, err := words.NewWorderWithDsl("{?0}.{?@bak_ext}", [][]string{pkg.BakGenerator(pool.url.Host)}, nil)
|
for w := range NewBruteDSL(pool.Config, "{?0}.{?@bak_ext}", [][]string{pkg.BakGenerator(pool.url.Host)}).Output {
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
worder.Run()
|
|
||||||
for w := range worder.C {
|
|
||||||
pool.addAddition(&Unit{
|
pool.addAddition(&Unit{
|
||||||
path: pool.dir + w,
|
path: pool.dir + w,
|
||||||
source: parsers.BakSource,
|
source: parsers.BakSource,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
worder, err = words.NewWorderWithDsl("{?@bak_name}.{?@bak_ext}", nil, nil)
|
for w := range NewBruteDSL(pool.Config, "{?@bak_name}.{?@bak_ext}", nil).Output {
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
worder.Run()
|
|
||||||
for w := range worder.C {
|
|
||||||
pool.addAddition(&Unit{
|
pool.addAddition(&Unit{
|
||||||
path: pool.dir + w,
|
path: pool.dir + w,
|
||||||
source: parsers.BakSource,
|
source: parsers.BakSource,
|
||||||
|
@ -18,7 +18,7 @@ func NewCheckPool(ctx context.Context, config *Config) (*CheckPool, error) {
|
|||||||
pctx, cancel := context.WithCancel(ctx)
|
pctx, cancel := context.WithCancel(ctx)
|
||||||
config.ClientType = ihttp.STANDARD
|
config.ClientType = ihttp.STANDARD
|
||||||
pool := &CheckPool{
|
pool := &CheckPool{
|
||||||
&BasePool{
|
BasePool: &BasePool{
|
||||||
Config: config,
|
Config: config,
|
||||||
Statistor: pkg.NewStatistor(""),
|
Statistor: pkg.NewStatistor(""),
|
||||||
ctx: pctx,
|
ctx: pctx,
|
||||||
@ -38,13 +38,14 @@ func NewCheckPool(ctx context.Context, config *Config) (*CheckPool, error) {
|
|||||||
pool.Headers = map[string]string{"Connection": "close"}
|
pool.Headers = map[string]string{"Connection": "close"}
|
||||||
p, _ := ants.NewPoolWithFunc(config.Thread, pool.Invoke)
|
p, _ := ants.NewPoolWithFunc(config.Thread, pool.Invoke)
|
||||||
|
|
||||||
pool.BasePool.Pool = p
|
pool.Pool = p
|
||||||
go pool.Handler()
|
go pool.Handler()
|
||||||
return pool, nil
|
return pool, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type CheckPool struct {
|
type CheckPool struct {
|
||||||
*BasePool
|
*BasePool
|
||||||
|
Pool *ants.PoolWithFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pool *CheckPool) Run(ctx context.Context, offset, limit int) {
|
func (pool *CheckPool) Run(ctx context.Context, offset, limit int) {
|
||||||
@ -66,7 +67,7 @@ func (pool *CheckPool) Run(ctx context.Context, offset, limit int) {
|
|||||||
Loop:
|
Loop:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case u, ok := <-pool.Worder.C:
|
case u, ok := <-pool.Worder.Output:
|
||||||
if !ok {
|
if !ok {
|
||||||
done = true
|
done = true
|
||||||
continue
|
continue
|
||||||
@ -82,12 +83,12 @@ Loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pool.wg.Add(1)
|
pool.wg.Add(1)
|
||||||
_ = pool.BasePool.Pool.Invoke(newUnit(u, parsers.CheckSource))
|
_ = pool.Pool.Invoke(newUnit(u, parsers.CheckSource))
|
||||||
case u, ok := <-pool.additionCh:
|
case u, ok := <-pool.additionCh:
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_ = pool.BasePool.Pool.Invoke(u)
|
_ = pool.Pool.Invoke(u)
|
||||||
case <-pool.closeCh:
|
case <-pool.closeCh:
|
||||||
break Loop
|
break Loop
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
@ -99,6 +100,10 @@ Loop:
|
|||||||
|
|
||||||
pool.Close()
|
pool.Close()
|
||||||
}
|
}
|
||||||
|
func (pool *CheckPool) Close() {
|
||||||
|
pool.Bar.Close()
|
||||||
|
pool.Pool.Release()
|
||||||
|
}
|
||||||
|
|
||||||
func (pool *CheckPool) Invoke(v interface{}) {
|
func (pool *CheckPool) Invoke(v interface{}) {
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -107,7 +112,7 @@ func (pool *CheckPool) Invoke(v interface{}) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
unit := v.(*Unit)
|
unit := v.(*Unit)
|
||||||
req, err := ihttp.BuildRequest(pool.ClientType, unit.path, "", "", "GET")
|
req, err := ihttp.BuildRequest(pool.ctx, pool.ClientType, unit.path, "", "", "GET")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Log.Debug(err.Error())
|
logs.Log.Debug(err.Error())
|
||||||
bl := &pkg.Baseline{
|
bl := &pkg.Baseline{
|
||||||
@ -125,7 +130,7 @@ func (pool *CheckPool) Invoke(v interface{}) {
|
|||||||
req.SetHeaders(pool.Headers)
|
req.SetHeaders(pool.Headers)
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
var bl *pkg.Baseline
|
var bl *pkg.Baseline
|
||||||
resp, reqerr := pool.client.Do(pool.ctx, req)
|
resp, reqerr := pool.client.Do(req)
|
||||||
if reqerr != nil {
|
if reqerr != nil {
|
||||||
pool.failedCount++
|
pool.failedCount++
|
||||||
bl = &pkg.Baseline{
|
bl = &pkg.Baseline{
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
package pool
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/chainreactors/spray/pkg"
|
|
||||||
"github.com/chainreactors/words/rule"
|
|
||||||
"github.com/expr-lang/expr/vm"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SprayMod int
|
|
||||||
|
|
||||||
const (
|
|
||||||
PathSpray SprayMod = iota + 1
|
|
||||||
HostSpray
|
|
||||||
ParamSpray
|
|
||||||
CustomSpray
|
|
||||||
)
|
|
||||||
|
|
||||||
var ModMap = map[string]SprayMod{
|
|
||||||
"path": PathSpray,
|
|
||||||
"host": HostSpray,
|
|
||||||
}
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
BaseURL string
|
|
||||||
ProxyAddr string
|
|
||||||
Thread int
|
|
||||||
Wordlist []string
|
|
||||||
Timeout int
|
|
||||||
ProcessCh chan *pkg.Baseline
|
|
||||||
OutputCh chan *pkg.Baseline
|
|
||||||
FuzzyCh chan *pkg.Baseline
|
|
||||||
Outwg *sync.WaitGroup
|
|
||||||
RateLimit int
|
|
||||||
CheckPeriod int
|
|
||||||
ErrPeriod int32
|
|
||||||
BreakThreshold int32
|
|
||||||
Method string
|
|
||||||
Mod SprayMod
|
|
||||||
Headers map[string]string
|
|
||||||
ClientType int
|
|
||||||
MatchExpr *vm.Program
|
|
||||||
FilterExpr *vm.Program
|
|
||||||
RecuExpr *vm.Program
|
|
||||||
AppendRule *rule.Program
|
|
||||||
AppendWords []string
|
|
||||||
Fuzzy bool
|
|
||||||
IgnoreWaf bool
|
|
||||||
Crawl bool
|
|
||||||
Scope []string
|
|
||||||
Active bool
|
|
||||||
Bak bool
|
|
||||||
Common bool
|
|
||||||
RetryLimit int
|
|
||||||
RandomUserAgent bool
|
|
||||||
Random string
|
|
||||||
Index string
|
|
||||||
}
|
|
@ -6,14 +6,12 @@ import (
|
|||||||
"github.com/chainreactors/spray/internal/ihttp"
|
"github.com/chainreactors/spray/internal/ihttp"
|
||||||
"github.com/chainreactors/spray/pkg"
|
"github.com/chainreactors/spray/pkg"
|
||||||
"github.com/chainreactors/words"
|
"github.com/chainreactors/words"
|
||||||
"github.com/panjf2000/ants/v2"
|
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BasePool struct {
|
type BasePool struct {
|
||||||
*Config
|
*Config
|
||||||
Statistor *pkg.Statistor
|
Statistor *pkg.Statistor
|
||||||
Pool *ants.PoolWithFunc
|
|
||||||
Bar *pkg.Bar
|
Bar *pkg.Bar
|
||||||
Worder *words.Worder
|
Worder *words.Worder
|
||||||
Cancel context.CancelFunc
|
Cancel context.CancelFunc
|
||||||
@ -72,10 +70,6 @@ func (pool *BasePool) addAddition(u *Unit) {
|
|||||||
pool.additionCh <- u
|
pool.additionCh <- u
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pool *BasePool) Close() {
|
|
||||||
pool.Bar.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pool *BasePool) putToOutput(bl *pkg.Baseline) {
|
func (pool *BasePool) putToOutput(bl *pkg.Baseline) {
|
||||||
if bl.IsValid || bl.IsFuzzy {
|
if bl.IsValid || bl.IsFuzzy {
|
||||||
bl.Collect()
|
bl.Collect()
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
package pool
|
package pool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/chainreactors/logs"
|
||||||
"github.com/chainreactors/parsers"
|
"github.com/chainreactors/parsers"
|
||||||
"github.com/chainreactors/spray/pkg"
|
"github.com/chainreactors/spray/pkg"
|
||||||
|
"github.com/chainreactors/words"
|
||||||
|
"github.com/chainreactors/words/rule"
|
||||||
|
"github.com/expr-lang/expr/vm"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newUnit(path string, source parsers.SpraySource) *Unit {
|
func newUnit(path string, source parsers.SpraySource) *Unit {
|
||||||
@ -31,3 +37,71 @@ type Baselines struct {
|
|||||||
index *pkg.Baseline
|
index *pkg.Baseline
|
||||||
baselines map[int]*pkg.Baseline
|
baselines map[int]*pkg.Baseline
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SprayMod int
|
||||||
|
|
||||||
|
const (
|
||||||
|
PathSpray SprayMod = iota + 1
|
||||||
|
HostSpray
|
||||||
|
ParamSpray
|
||||||
|
CustomSpray
|
||||||
|
)
|
||||||
|
|
||||||
|
var ModMap = map[string]SprayMod{
|
||||||
|
"path": PathSpray,
|
||||||
|
"host": HostSpray,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
BaseURL string
|
||||||
|
ProxyAddr string
|
||||||
|
Thread int
|
||||||
|
Wordlist []string
|
||||||
|
Timeout time.Duration
|
||||||
|
ProcessCh chan *pkg.Baseline
|
||||||
|
OutputCh chan *pkg.Baseline
|
||||||
|
FuzzyCh chan *pkg.Baseline
|
||||||
|
Outwg *sync.WaitGroup
|
||||||
|
RateLimit int
|
||||||
|
CheckPeriod int
|
||||||
|
ErrPeriod int32
|
||||||
|
BreakThreshold int32
|
||||||
|
Method string
|
||||||
|
Mod SprayMod
|
||||||
|
Headers map[string]string
|
||||||
|
ClientType int
|
||||||
|
MatchExpr *vm.Program
|
||||||
|
FilterExpr *vm.Program
|
||||||
|
RecuExpr *vm.Program
|
||||||
|
AppendRule *rule.Program
|
||||||
|
Fns []words.WordFunc
|
||||||
|
AppendWords []string
|
||||||
|
Fuzzy bool
|
||||||
|
IgnoreWaf bool
|
||||||
|
Crawl bool
|
||||||
|
Scope []string
|
||||||
|
Active bool
|
||||||
|
Bak bool
|
||||||
|
Common bool
|
||||||
|
RetryLimit int
|
||||||
|
RandomUserAgent bool
|
||||||
|
Random string
|
||||||
|
Index string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBruteWords(config *Config, list []string) *words.Worder {
|
||||||
|
word := words.NewWorderWithList(list)
|
||||||
|
word.Fns = config.Fns
|
||||||
|
word.Run()
|
||||||
|
return word
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBruteDSL(config *Config, dsl string, params [][]string) *words.Worder {
|
||||||
|
word, err := words.NewWorderWithDsl(dsl, params, nil)
|
||||||
|
if err != nil {
|
||||||
|
logs.Log.Error(err.Error())
|
||||||
|
}
|
||||||
|
word.Fns = config.Fns
|
||||||
|
word.Run()
|
||||||
|
return word
|
||||||
|
}
|
||||||
|
@ -13,7 +13,9 @@ import (
|
|||||||
"github.com/panjf2000/ants/v2"
|
"github.com/panjf2000/ants/v2"
|
||||||
"github.com/vbauerster/mpb/v8"
|
"github.com/vbauerster/mpb/v8"
|
||||||
"github.com/vbauerster/mpb/v8/decor"
|
"github.com/vbauerster/mpb/v8/decor"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -45,7 +47,7 @@ type Runner struct {
|
|||||||
DumpFile *files.File
|
DumpFile *files.File
|
||||||
StatFile *files.File
|
StatFile *files.File
|
||||||
Progress *mpb.Progress
|
Progress *mpb.Progress
|
||||||
Fns []func(string) []string
|
Fns []words.WordFunc
|
||||||
Count int // tasks total number
|
Count int // tasks total number
|
||||||
Wordlist []string
|
Wordlist []string
|
||||||
AppendWords []string
|
AppendWords []string
|
||||||
@ -60,7 +62,7 @@ type Runner struct {
|
|||||||
func (r *Runner) PrepareConfig() *pool.Config {
|
func (r *Runner) PrepareConfig() *pool.Config {
|
||||||
config := &pool.Config{
|
config := &pool.Config{
|
||||||
Thread: r.Threads,
|
Thread: r.Threads,
|
||||||
Timeout: r.Timeout,
|
Timeout: time.Duration(r.Timeout) * time.Second,
|
||||||
RateLimit: r.RateLimit,
|
RateLimit: r.RateLimit,
|
||||||
Headers: r.Headers,
|
Headers: r.Headers,
|
||||||
Method: r.Method,
|
Method: r.Method,
|
||||||
@ -77,6 +79,7 @@ func (r *Runner) PrepareConfig() *pool.Config {
|
|||||||
RecuExpr: r.RecursiveExpr,
|
RecuExpr: r.RecursiveExpr,
|
||||||
AppendRule: r.AppendRules, // 对有效目录追加规则, 根据rule生成
|
AppendRule: r.AppendRules, // 对有效目录追加规则, 根据rule生成
|
||||||
AppendWords: r.AppendWords, // 对有效目录追加字典
|
AppendWords: r.AppendWords, // 对有效目录追加字典
|
||||||
|
Fns: r.Fns,
|
||||||
//IgnoreWaf: r.IgnoreWaf,
|
//IgnoreWaf: r.IgnoreWaf,
|
||||||
Crawl: r.CrawlPlugin,
|
Crawl: r.CrawlPlugin,
|
||||||
Scope: r.Scope,
|
Scope: r.Scope,
|
||||||
@ -180,7 +183,7 @@ func (r *Runner) Prepare(ctx context.Context) error {
|
|||||||
brutePool.Statistor.Total = t.origin.sum
|
brutePool.Statistor.Total = t.origin.sum
|
||||||
} else {
|
} else {
|
||||||
brutePool.Statistor = pkg.NewStatistor(t.baseUrl)
|
brutePool.Statistor = pkg.NewStatistor(t.baseUrl)
|
||||||
brutePool.Worder = words.NewWorder(r.Wordlist)
|
brutePool.Worder = words.NewWorderWithList(r.Wordlist)
|
||||||
brutePool.Worder.Fns = r.Fns
|
brutePool.Worder.Fns = r.Fns
|
||||||
brutePool.Worder.Rules = r.Rules.Expressions
|
brutePool.Worder.Rules = r.Rules.Expressions
|
||||||
}
|
}
|
||||||
@ -205,7 +208,7 @@ func (r *Runner) Prepare(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
brutePool.Run(ctx, brutePool.Statistor.Offset, limit)
|
brutePool.Run(brutePool.Statistor.Offset, limit)
|
||||||
|
|
||||||
if brutePool.IsFailed && len(brutePool.FailedBaselines) > 0 {
|
if brutePool.IsFailed && len(brutePool.FailedBaselines) > 0 {
|
||||||
// 如果因为错误积累退出, end将指向第一个错误发生时, 防止resume时跳过大量目标
|
// 如果因为错误积累退出, end将指向第一个错误发生时, 防止resume时跳过大量目标
|
||||||
@ -228,6 +231,7 @@ Loop:
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
// 如果超过了deadline, 尚未开始的任务都将被记录到stat中
|
||||||
if len(r.taskCh) > 0 {
|
if len(r.taskCh) > 0 {
|
||||||
for t := range r.taskCh {
|
for t := range r.taskCh {
|
||||||
stat := pkg.NewStatistor(t.baseUrl)
|
stat := pkg.NewStatistor(t.baseUrl)
|
||||||
@ -366,7 +370,6 @@ func (r *Runner) Output(bl *pkg.Baseline) {
|
|||||||
|
|
||||||
if bl.IsValid {
|
if bl.IsValid {
|
||||||
logs.Log.Console(out + "\n")
|
logs.Log.Console(out + "\n")
|
||||||
|
|
||||||
} else if r.Fuzzy && bl.IsFuzzy {
|
} else if r.Fuzzy && bl.IsFuzzy {
|
||||||
logs.Log.Console("[fuzzy] " + out + "\n")
|
logs.Log.Console("[fuzzy] " + out + "\n")
|
||||||
}
|
}
|
||||||
@ -376,6 +379,10 @@ func (r *Runner) Output(bl *pkg.Baseline) {
|
|||||||
r.OutputFile.SafeWrite(bl.ToJson() + "\n")
|
r.OutputFile.SafeWrite(bl.ToJson() + "\n")
|
||||||
} else if r.FileOutput == "csv" {
|
} else if r.FileOutput == "csv" {
|
||||||
r.OutputFile.SafeWrite(bl.ToCSV() + "\n")
|
r.OutputFile.SafeWrite(bl.ToCSV() + "\n")
|
||||||
|
} else if r.FileOutput == "full" {
|
||||||
|
r.OutputFile.SafeWrite(bl.String() + "\n")
|
||||||
|
} else {
|
||||||
|
r.OutputFile.SafeWrite(bl.Format(strings.Split(r.FileOutput, ",")) + "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
r.OutputFile.SafeSync()
|
r.OutputFile.SafeSync()
|
||||||
|
@ -14,13 +14,13 @@ type Origin struct {
|
|||||||
sum int
|
sum int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Origin) InitWorder(fns []func(string) []string) (*words.Worder, error) {
|
func (o *Origin) InitWorder(fns []words.WordFunc) (*words.Worder, error) {
|
||||||
var worder *words.Worder
|
var worder *words.Worder
|
||||||
wl, err := pkg.LoadWordlist(o.Word, o.Dictionaries)
|
wl, err := pkg.LoadWordlist(o.Word, o.Dictionaries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
worder = words.NewWorder(wl)
|
worder = words.NewWorderWithList(wl)
|
||||||
worder.Fns = fns
|
worder.Fns = fns
|
||||||
rules, err := pkg.LoadRuleWithFiles(o.RuleFiles, o.RuleFilter)
|
rules, err := pkg.LoadRuleWithFiles(o.RuleFiles, o.RuleFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -14,3 +14,9 @@ package internal
|
|||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
var ConfigTemplate = `
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
`
|
||||||
|
20
pkg/parse.go
Normal file
20
pkg/parse.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package pkg
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
var (
|
||||||
|
SkipChar = "%SKIP%"
|
||||||
|
EXTChar = "%EXT%"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ParseEXTPlaceholderFunc(exts []string) func(string) []string {
|
||||||
|
return func(s string) []string {
|
||||||
|
ss := make([]string, len(exts))
|
||||||
|
for i, e := range exts {
|
||||||
|
if strings.Contains(s, EXTChar) {
|
||||||
|
ss[i] = strings.Replace(s, EXTChar, e, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ss
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user