Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/js/libs/mysql/mysql_private.go
2858 views
1
package mysql
2
3
import (
4
"context"
5
"database/sql"
6
"fmt"
7
"net"
8
"net/url"
9
"strings"
10
)
11
12
type (
13
// MySQLOptions defines the data source name (DSN) options required to connect to a MySQL database.
14
// along with other options like Timeout etc
15
// @example
16
// ```javascript
17
// const mysql = require('nuclei/mysql');
18
// const options = new mysql.MySQLOptions();
19
// options.Host = 'acme.com';
20
// options.Port = 3306;
21
// ```
22
MySQLOptions struct {
23
Host string // Host is the host name or IP address of the MySQL server.
24
Port int // Port is the port number on which the MySQL server is listening.
25
Protocol string // Protocol is the protocol used to connect to the MySQL server (ex: "tcp").
26
Username string // Username is the user name used to authenticate with the MySQL server.
27
Password string // Password is the password used to authenticate with the MySQL server.
28
DbName string // DbName is the name of the database to connect to on the MySQL server.
29
RawQuery string // QueryStr is the query string to append to the DSN (ex: "?tls=skip-verify").
30
Timeout int // Timeout is the timeout in seconds for the connection to the MySQL server.
31
}
32
)
33
34
// BuildDSN builds a MySQL data source name (DSN) from the given options.
35
// @example
36
// ```javascript
37
// const mysql = require('nuclei/mysql');
38
// const options = new mysql.MySQLOptions();
39
// options.Host = 'acme.com';
40
// options.Port = 3306;
41
// const dsn = mysql.BuildDSN(options);
42
// ```
43
func BuildDSN(opts MySQLOptions) (string, error) {
44
if opts.Host == "" || opts.Port <= 0 {
45
return "", fmt.Errorf("invalid host or port")
46
}
47
if opts.Protocol == "" {
48
opts.Protocol = "tcp"
49
}
50
// We're going to use a custom dialer when creating MySQL connections, so if we've been
51
// given "tcp" as the protocol, then quietly switch it to "nucleitcp", which we have
52
// already registered.
53
if opts.Protocol == "tcp" {
54
opts.Protocol = "nucleitcp"
55
}
56
if opts.DbName == "" {
57
opts.DbName = "/"
58
} else {
59
opts.DbName = "/" + opts.DbName
60
}
61
target := net.JoinHostPort(opts.Host, fmt.Sprintf("%d", opts.Port))
62
var dsn strings.Builder
63
dsn.WriteString(fmt.Sprintf("%v:%v", url.QueryEscape(opts.Username), opts.Password))
64
dsn.WriteString("@")
65
dsn.WriteString(fmt.Sprintf("%v(%v)", opts.Protocol, target))
66
if opts.DbName != "" {
67
dsn.WriteString(opts.DbName)
68
}
69
if opts.RawQuery != "" {
70
dsn.WriteString(opts.RawQuery)
71
}
72
return dsn.String(), nil
73
}
74
75
// @memo
76
func connectWithDSN(executionId string, dsn string) (bool, error) {
77
db, err := sql.Open("mysql", dsn)
78
if err != nil {
79
return false, err
80
}
81
defer func() {
82
_ = db.Close()
83
}()
84
db.SetMaxOpenConns(1)
85
db.SetMaxIdleConns(0)
86
87
ctx := context.WithValue(context.Background(), "executionId", executionId) // nolint: staticcheck
88
err = db.PingContext(ctx)
89
if err != nil {
90
return false, err
91
}
92
return true, nil
93
}
94
95