- 投稿日:2021-01-28T16:17:55+09:00
MySQL に ssl 認証で接続
次のファイルがあるフォルダーで実行します。
client-cert.pem client-key.pem server-ca.pemコマンド
ssl_connect.shhost="example.com" user="scott" pass="secret" # mysql --ssl-ca=server-ca.pem --ssl-cert=client-cert.pem \ --ssl-key=client-key.pem \ --host=${host} --user=${user} --password=${pass}Python3
show_tables.py#! /usr/bin/python # # show_tables.py # # Jan/28/2021 import pymysql.cursors # host_aa='example.com' user_aa='scott' pass_aa='secret' db_aa='dbfirst' # connection = pymysql.connect(host=host_aa, user=user_aa, password=pass_aa, db=db_aa, charset='utf8', cursorclass=pymysql.cursors.DictCursor, ssl={'key': './client-key.pem', 'cert': './client-cert.pem', 'ca': './server-ca.pem','check_hostname': False}) cursor = connection.cursor() cursor.execute("show tables") result = cursor.fetchall() # print(result) for rr in result: print(rr) cursor.close() connection.close()Node.js
show_tables.js#! /usr/bin/node // --------------------------------------------------------------- // show_tables.js // // Jan/28/2021 // // --------------------------------------------------------------- 'use strict' var fs = require("fs") // --------------------------------------------------------------- console.error ("*** 開始 ***") var mysql = require('mysql') var connection = mysql.createConnection ({ host: 'example.com', user: 'scott', password: 'secret', database : 'dbfirst', ssl : { ca : fs.readFileSync('./server-ca.pem'), key : fs.readFileSync('./client-key.pem'), cert : fs.readFileSync('./client-cert.pem'), } }) connection.query("show tables", function (err, rows) { if (err) throw err console.log (rows.length) rows.forEach(function(row) { console.log(row) }) connection.end() console.error ("*** 終了 ***") }) // ---------------------------------------------------------------Go
show_tables.go// ---------------------------------------------------------------- // // show_tables.go // // Jan/29/2021 // // ---------------------------------------------------------------- package main import ( "crypto/tls" "database/sql" "fmt" "log" "os" "github.com/go-sql-driver/mysql" ) func main() { fmt.Fprintf (os.Stderr,"*** 開始 ***\n") cert, err := tls.LoadX509KeyPair("./client-cert.pem", "./client-key.pem") if err != nil { log.Fatal(err) } clientCert := []tls.Certificate{cert} mysql.RegisterTLSConfig("custom", &tls.Config{ Certificates: clientCert, InsecureSkipVerify: true, }) db, err := sql.Open("mysql", "scott:secret@tcp(example.com:3306)/dbfirst?tls=custom") if err != nil { log.Fatal(err) } err = db.Ping() if err != nil { log.Fatal(err) } sql_str := "show tables" rows, err := db.Query(sql_str) if err != nil { fmt.Println(err) } defer rows.Close() for rows.Next() { var name string if err := rows.Scan(&name); err != nil { fmt.Println(err) } fmt.Printf ("%s\n",name) } if err := rows.Err(); err != nil { fmt.Println(err) } fmt.Fprintf (os.Stderr,"*** 終了 ***\n") } // ----------------------------------------------------------------参考ページ
MySQLでクライアント証明書を使う
- 投稿日:2021-01-28T10:55:29+09:00
【自己学習用】はじめてのGo3
type
Goではtypeを用いて既存の型を拡張した独自の型を定義できる。
呼び出す際に,型が適合していないとコンパイルエラー。type ID int type Priority int func ProcessTask(id ID, priority Priority) { } var id ID = 3 var priority Priority = 5 ProcessTask(priority, id) // コンパイルエラー構造体(struct)
GOの構造体はメソッドを持つことができ,RubyやJavaでのクラスに近い。
構造体もtypeを用いて宣言し,構造体名のあとにそのフィールドを記述する。
各フィールドの可視性は名前で決まり,大文字で始まる場合はパブリック,小文字はプライベート。type Task struct { ID int // public Detail string // public done bool // private } func main() { var task Task = Task{ ID: 1, Detail: "buy the milk", done: true, } fmt.Println(task.ID) // 1 fmt.Println(task.Detail) // "buy the milk" fmt.Println(task.done) // true task := Task{} //構造体の生成時に値を明示的に指定しなかった場合は,ゼロ値で初期化 }コンストラクタ
Goにはコンストラクタがない。
代わりにNewで始まる関数を定義し,その内部で構造体を生成するのが通例。func NewTask(id int, detail string) *Task { task := &Task{ ID: id, Detail: detail, done: false, } return task } func main() { task := NewTask(1, "buy the milk") // &{ID:1 Detail:buy the milk done:false} fmt.Printf("%+v", task) }メソッド
型にはメソッドを定義できます。メソッドは,そのメソッドを実行した対象の型をレシーバとして受>け取り,メソッドの内部で使用できます。
つまりいわゆる拡張メソッドのこと。
func (メソッドを定義する型名の変数名, メソッドを定義する型名) メソッド名 戻り値 {
}package main import ( "fmt" ) type Task struct { ID int Detail string done bool } func NewTask(id int, detail string) *Task { task := &Task{ ID: id, Detail: detail, done: false, } return task } func (task Task) String() string { str := fmt.Sprintf("%d) %s", task.ID, task.Detail) return str } func main() { task := NewTask(1, "buy the milk") fmt.Printf("%s", task.String()) // 1) buy the milk }インタフェース
インタフェースの名前は,実装すべき関数名が単純な場合は,その関数名にerを加えた名前を付ける慣習がある。
Goは,型がインタフェースに定義されたメソッドを実装していれば,インタフェースを満たしているとみなす。
↑のTaskにはString()メソッドを実装しているため,Stringerを引数に取る次のような関数に渡すことができる。type Stringer interface { String() string } ~省略~ func main() { task := NewTask(1, "buy the milk") fmt.Printf("%s", task.String()) // 1) buy the milk Print(task) // TaskにはStringメソッドを定義しているためエラーにならない } func Print(stringer Stringer) { fmt.Println(stringer.String()) }次のような何も指定していないインタフェースを定義すると、どんな型も受け取ることができる関数を定義できる。
定義しなくてもinterface{}と記述すると同じ意味になる。func Do(e Any) { // do something } Do("a") // どのような型も渡すことができる func Do(e interface{}) { // do something } Do("a") // どのような型も渡すことができる型の埋め込み
Goでは,継承はサポートされていない代わりに、ほかの型を「埋め込む」(Embed)という方式で,構造体やインタフェースの振る舞いを拡張できる。
package main import ( "fmt" ) type User struct { FirstName string LastName string } func (u *User) FullName() string { fullname := fmt.Sprintf("%s %s", u.FirstName, u.LastName) return fullname } func NewUser(firstName, lastName string) *User { return &User{ FirstName: firstName, LastName: lastName, } } type Task struct { ID int Detail string done bool *User // Userを埋め込む } func NewTask(id int, detail, firstName, lastName string) *Task { task := &Task{ ID: id, Detail: detail, done: false, User: NewUser(firstName, lastName), } return task } func main() { task := NewTask(1, "buy the milk", "Jxck", "Daniel") // TaskにUserのフィールドが埋め込まれている fmt.Println(task.FirstName) fmt.Println(task.LastName) // TaskにUserのメソッドが埋め込まれている fmt.Println(task.FullName()) // Taskから埋め込まれたUser自体にもアクセス可能 fmt.Println(task.User) fmt.Println(task.User.FirstName) //Userからもメンバにアクセス可能 /* type Task struct { ID int Detail string FirstName string done bool *User // Userを埋め込む } もしTaskにUser配下のメンバと同名のメンバがいたらどうなるか? →エラーとはならず共存する fmt.Println(task.FirstName) fmt.Println(task.User.FirstName) */ }
- 投稿日:2021-01-28T09:31:13+09:00
Redis の WebAPI (Gin)
こちらで定めた仕様を満たすサーバーサイドのプログラムです。
Redis の WebAPI を作成次のプログラムを改造しました。
Gin の使い方redis_api.go// --------------------------------------------------------------- // // redis_api.go // // Jan/28/2021 // --------------------------------------------------------------- package main import "github.com/gin-gonic/gin" import "net/http" import ( "os" "fmt" "net" "strings" "encoding/json" ) // --------------------------------------------------------------- func main() { router := gin.Default() router.GET("/user/:name", func(c *gin.Context) { name := c.Param("name") c.String(http.StatusOK, "Hello %s", name) }) router.POST("/redis_read", func(c *gin.Context) { key := c.PostForm("key") message := read_proc(key) c.String(http.StatusOK, message) }) router.POST("/redis_insert", func(c *gin.Context) { key := c.PostForm("key") value := c.PostForm("value") message := insert_proc(key,value) c.String(http.StatusOK, message) }) router.POST("/redis_list", func(c *gin.Context) { message := list_proc() c.String(http.StatusOK, message) }) router.Run(":8080") } // --------------------------------------------------------------- // [4]: func read_proc(key string) string { fmt.Fprintf (os.Stderr,"*** read_proc ***\n") hostname := "localhost" port := "6379" conn, err := net.Dial ("tcp", hostname + ":" + port) if err != nil { fmt.Println(err) return "err" } json_str := mcached_socket_read_proc (conn,key) conn.Close () return json_str } // --------------------------------------------------------------- // [4-6]: func mcached_socket_read_proc (conn net.Conn,key_in string) string { json_str := "" str_received := socket_read_proc (conn,key_in) lines := strings.Split(str_received,"\n") if (! strings.Contains(lines[0],"END")) { json_str = lines[1] } return json_str } // --------------------------------------------------------------- // [4-6-8]: func socket_read_proc (conn net.Conn,key_in string) string { str_received := "" _, err := conn.Write([]byte("get " + key_in + "\r\n")) if err != nil { fmt.Println(err) return str_received } buf := make([]byte, 1024) nn, err := conn.Read(buf[:]) if err != nil { fmt.Println(err) return str_received } str_received = string(buf[0:nn]) return str_received } // --------------------------------------------------------------- // [6]: func insert_proc(key string, value string) string { fmt.Fprintf (os.Stderr,"*** insert_proc ***\n") hostname := "localhost" port := "6379" conn, err := net.Dial ("tcp", hostname + ":" + port) if err != nil { fmt.Println(err) return "err" } redis_socket_write_proc (conn,key,value) conn.Close () return "ok" } // ---------------------------------------------------------------- func redis_socket_write_proc (conn net.Conn,key_in string,json_str string) { fmt.Println (key_in) fmt.Println (json_str) comm_aa := "set " + key_in + " '" + json_str + "'\r\n" conn.Write([]byte(comm_aa)) buf := make ([]byte,1024) conn.Read (buf[:]) fmt.Println (string(buf[0:10])) } // ---------------------------------------------------------------- // [8]: func list_proc() string { fmt.Fprintf (os.Stderr,"*** list_proc ***\n") hostname := "localhost" port := "6379" conn, err := net.Dial ("tcp", hostname + ":" + port) if err != nil { fmt.Println(err) return "err" } keys := key_get_proc(conn) conn.Close () output, _ := json.Marshal(keys) return string(output) } // --------------------------------------------------------------- // [8-4]: func key_get_proc (conn net.Conn) []string { var keys []string string_received := string_get_proc (conn) if 0 < len (string_received) { datax := strings.Split (string_received,"\n") for _, pp := range datax { if (0 < len (pp)) && (pp[:1] == "t") { pp = strings.TrimRight(pp, "\r") keys = append(keys, pp) } } } return keys } // ---------------------------------------------------------------- // [8-4-4]: func string_get_proc (conn net.Conn) string{ str_received := "" comm_aa := "keys *" + "\r\n" _, err := conn.Write([]byte(comm_aa)) if err != nil { fmt.Println(err) return str_received } buf := make([]byte, 1024) nn, err := conn.Read(buf[:]) if err != nil { fmt.Println(err) return str_received } str_received = string(buf[0:nn]) return str_received } // ---------------------------------------------------------------サーバーの実行
go run redis_api.goテストスクリプト
read
curl -X POST http://localhost:8080/redis_read -d key=t1851insert
curl -X POST http://localhost:8080/redis_insert -d key=t1855 \ -d value='{"name": "宇都宮","population": 8751206,"date_mod": "2021-1-16"}'list
curl -X POST http://localhost:8080/redis_list