Passed
Pull Request — master (#52)
by Stefano
02:05
created

producer.*ReProducer.buildReproducer   B

Complexity

Conditions 8

Size

Total Lines 40
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 23
nop 0
dl 0
loc 40
rs 7.3333
c 0
b 0
f 0
1
package producer
2
3
import (
4
	"path"
5
	"sync"
6
7
	"github.com/stefanoj3/dirstalk/pkg/pathutil"
8
	"github.com/stefanoj3/dirstalk/pkg/scan"
9
)
10
11
const defaultChannelBuffer = 25
12
13
var statusCodesToSkip = map[int]bool{
14
	404: false,
15
}
16
17
func NewReProducer(
0 ignored issues
show
introduced by
exported function NewReProducer should have comment or be unexported
Loading history...
18
	producer scan.Producer,
19
) *ReProducer {
20
	return &ReProducer{
21
		producer: producer,
22
	}
23
}
24
25
type ReProducer struct {
0 ignored issues
show
introduced by
exported type ReProducer should have comment or be unexported
Loading history...
26
	producer scan.Producer
27
}
28
29
// Reproduce will check if it is possible to go deeper on the result provided, if so will
30
func (r *ReProducer) Reproduce() func(r scan.Result) <-chan scan.Target {
31
	return r.buildReproducer()
32
}
33
34
func (r *ReProducer) buildReproducer() func(result scan.Result) <-chan scan.Target {
35
	resultRegistry := sync.Map{}
36
37
	return func(result scan.Result) <-chan scan.Target {
38
		resultChannel := make(chan scan.Target, defaultChannelBuffer)
39
40
		go func() {
41
			defer close(resultChannel)
42
43
			if _, ok := statusCodesToSkip[result.Response.StatusCode]; ok {
44
				return
45
			}
46
47
			if result.Target.Depth <= 0 {
48
				return
49
			}
50
51
			// no point in appending to a filename
52
			if pathutil.HasExtension(result.Target.Path) {
53
				return
54
			}
55
56
			_, inRegistry := resultRegistry.Load(result.Target.Path)
57
			if inRegistry {
58
				return
59
			}
60
			resultRegistry.Store(result.Target.Path, false)
61
62
			for target := range r.producer.Produce() {
63
				newTarget := result.Target
64
				newTarget.Depth--
65
				newTarget.Path = path.Join(newTarget.Path, target.Path)
66
				newTarget.Method = target.Method
67
68
				resultChannel <- newTarget
69
			}
70
71
		}()
72
73
		return resultChannel
74
	}
75
}
76