Passed
Push — master ( b9ce7a...fa5039 )
by Stefano
02:17
created

cmd.scanConfigFromCmd   F

Complexity

Conditions 14

Size

Total Lines 73
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 44
nop 1
dl 0
loc 73
rs 3.6
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like cmd.scanConfigFromCmd often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package cmd
2
3
import (
4
	"net/http"
5
	"net/url"
6
	"strings"
7
	"time"
8
9
	"github.com/pkg/errors"
10
	"github.com/spf13/cobra"
11
	"github.com/stefanoj3/dirstalk/pkg/scan"
12
)
13
14
func scanConfigFromCmd(cmd *cobra.Command) (*scan.Config, error) {
15
	c := &scan.Config{}
16
17
	var err error
18
19
	c.DictionaryPath = cmd.Flag(flagDictionary).Value.String()
20
21
	c.HTTPMethods, err = cmd.Flags().GetStringSlice(flagHTTPMethods)
22
	if err != nil {
23
		return nil, errors.Wrap(err, "failed to read http methods flag")
24
	}
25
26
	c.HTTPStatusesToIgnore, err = cmd.Flags().GetIntSlice(flagHTTPStatusesToIgnore)
27
	if err != nil {
28
		return nil, errors.Wrap(err, "failed to read http methods flag")
29
	}
30
31
	c.Threads, err = cmd.Flags().GetInt(flagThreads)
32
	if err != nil {
33
		return nil, errors.Wrap(err, "failed to read threads flag")
34
	}
35
36
	c.TimeoutInMilliseconds, err = cmd.Flags().GetInt(flagHTTPTimeout)
37
	if err != nil {
38
		return nil, errors.Wrap(err, "failed to read http-timeout flag")
39
	}
40
41
	c.CacheRequests, err = cmd.Flags().GetBool(flagHTTPCacheRequests)
42
	if err != nil {
43
		return nil, errors.Wrap(err, "failed to read http-cache-requests flag")
44
	}
45
46
	c.ScanDepth, err = cmd.Flags().GetInt(flagScanDepth)
47
	if err != nil {
48
		return nil, errors.Wrap(err, "failed to read http-timeout flag")
49
	}
50
51
	socks5Host := cmd.Flag(flagSocks5Host).Value.String()
52
	if len(socks5Host) > 0 {
53
		c.Socks5Url, err = url.Parse("socks5://" + socks5Host)
54
		if err != nil {
55
			return nil, errors.Wrap(err, "invalid value for "+flagSocks5Host)
56
		}
57
	}
58
59
	c.UserAgent = cmd.Flag(flagUserAgent).Value.String()
60
61
	c.UseCookieJar, err = cmd.Flags().GetBool(flagCookieJar)
62
	if err != nil {
63
		return nil, errors.Wrap(err, "cookie jar flag is invalid")
64
	}
65
66
	rawCookies, err := cmd.Flags().GetStringArray(flagCookie)
67
	if err != nil {
68
		return nil, errors.Wrap(err, "failed to read cookies flag")
69
	}
70
71
	c.Cookies, err = rawCookiesToCookies(rawCookies)
72
	if err != nil {
73
		return nil, errors.Wrap(err, "failed to convert rawCookies to objects")
74
	}
75
76
	rawHeaders, err := cmd.Flags().GetStringArray(flagHeader)
77
	if err != nil {
78
		return nil, errors.Wrap(err, "failed to read cookies flag")
79
	}
80
81
	c.Headers, err = rawHeadersToHeaders(rawHeaders)
82
	if err != nil {
83
		return nil, errors.Wrap(err, "failed to convert rawHeaders")
84
	}
85
86
	return c, nil
87
}
88
89
func rawHeadersToHeaders(rawHeaders []string) (map[string]string, error) {
90
	headers := make(map[string]string, len(rawHeaders)*2)
91
92
	for _, rawHeader := range rawHeaders {
93
		parts := strings.Split(rawHeader, ":")
94
		if len(parts) != 2 {
95
			return nil, errors.Errorf("header is in invalid format: %s", rawHeader)
96
		}
97
98
		headers[parts[0]] = parts[1]
99
	}
100
101
	return headers, nil
102
}
103
104
func rawCookiesToCookies(rawCookies []string) ([]*http.Cookie, error) {
105
	cookies := make([]*http.Cookie, 0, len(rawCookies))
106
107
	for _, rawCookie := range rawCookies {
108
		parts := strings.Split(rawCookie, "=")
109
		if len(parts) != 2 {
110
			return nil, errors.Errorf("cookie format is invalid: %s", rawCookie)
111
		}
112
113
		cookies = append(
114
			cookies,
115
			&http.Cookie{
116
				Name:    parts[0],
117
				Value:   parts[1],
118
				Expires: time.Now().AddDate(0, 0, 2),
119
			},
120
		)
121
	}
122
123
	return cookies, nil
124
}
125