แสดงบทความที่มีป้ายกำกับ hack แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ hack แสดงบทความทั้งหมด

วันพุธที่ 24 มิถุนายน พ.ศ. 2558

Download & Read Manga via Golang

เวลาอ่านกาตูน Online ผมอ่านอยู่ไม่กี่เว็บผมเลยเขียน program สำหรับ ดูด กาตูนเหล่านั้นมาลงไว้ที่เครื่องแล้วค่อยอ่านทีหลัง https://github.com/neverlock/Mangafox
แต่ดูดมาก็เป็นภาระ ต้องมาหาโปรแกรมเปิดอ่าน ปรกติแล้วผมใช้ Ehon ผมว่าตัวนี้เป็นตัวอ่าน manga บน MAC ที่ดูดีที่สุดละ แต่บางทีก็ขี้เกียจเปิดมันเพราะต้อง Import Dir รูปเข้าไปให้มันก่อน



จากความรำคาญเลยเขียน golang web service สำหรับอ่านกาตูนอีกตัว โดย hack net/http ใน function ที่ทำงาน serv static file เอามาแสดงผลให้แสดง tag img เพื่อ แสดงรูปซะเลย

ใน function main เขียนแค่ บรรทัดเดียว



package main

import (
        "log"
        "github.com/neverlock/manga_net/http"
)


func main() {
        log.Println("Service at :8080")
        log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("./"))))
}

สั่ง go get github.com/neverlock/manga_net/http
จากนั้นสั่ง go build
แล้วเอา binary ที่ได้ไปวางไว้ใน Dir ที่ load manga มาไว้แล้วสั่ง run แล้วเปิดดูที่ web browser ได้เลย

การแสดงผลจะเหมือนกับการ serv static file แต่ถ้าใน Dir มีรูปมันจะแสดงรูปแทนที่จะเป็น link 



วันอังคารที่ 2 มิถุนายน พ.ศ. 2558

golang SOCKS5 server

ไหนๆวันนี้ก็เขียนเรื่อง go SOCKS client ไปแล้วเขียนเรืองทำ SOCKS server ด้วย go ไปเลยดีกว่าเพราะเห็น Bright มากด like ให้ด้วยเห็นวันก่อนถามเรื่องทำ SOCKS server นิ

package main

import "github.com/armon/go-socks5"

func main(){
conf := &socks5.Config{}
server, err := socks5.New(conf)
if err != nil {
  panic(err)
}

// Create SOCKS5 proxy on localhost port 8000
if err := server.ListenAndServe("tcp", "127.0.0.1:8000"); err != nil {
  panic(err)
        }
}

lib ตัวนี้เป็น SOCKS5 อย่างเดียวเวลา connect ให้ตั้ง type เป็น SOCKS5 ด้วยนะเวลาจะทดสอบ


ตามรูปตัวอย่างบรรทัดด้านบนเป็นการลองส่ง  request จาก client ที่ set SOCKS 4 มาจะเห็นว่า connect ไม่ได้ ถ้า set ถูกจะเห็นตามบรรทัดล่างๆคือ มีการส่งข้อมูลไปกลับระหว่าตัว client กับ target 
แค่นี้ยังไม่พอเรามา hack เพิ่มอีกนิดหน่อยดีกว่า จริงๆผมอยาก print log มากกว่านี้แต่ ไปอ่านdoc มันแล้วไม่มี function พวกนี้เลย เรามาเขียน ความสามารถที่เราอยากได้เพิ่มให้กับ lib มันเลยดีกว่า
โดยเข้าไปแก้ file ที่อยู่ใน path src/github.com/armon/go-socks5/request.go
หรือถ้าต้องการ monitor อะไรเพิ่มเติมก็ไปเขียน hook เพิ่มเอาได้เลย


func (s *Server) handleConnect(conn conn, bufConn io.Reader, dest, realDest *AddrSpec) error {
        // Check if this is allowed
        client := conn.RemoteAddr().(*net.TCPAddr)
        if !s.config.Rules.AllowConnect(realDest.IP, realDest.Port, client.IP, client.Port) {
                if err := sendReply(conn, ruleFailure, nil); err != nil {
                        return fmt.Errorf("Failed to send reply: %v", err)
                }
                return fmt.Errorf("Connect to %v blocked by rules", dest)
        }

        // Attempt to connect
        addr := net.TCPAddr{IP: realDest.IP, Port: realDest.Port}
        target, err := net.DialTCP("tcp", nil, &addr)
        if err != nil {
                msg := err.Error()
                resp := hostUnreachable
                if strings.Contains(msg, "refused") {
                        resp = connectionRefused
                } else if strings.Contains(msg, "network is unreachable") {
                        resp = networkUnreachable
                }
                if err := sendReply(conn, resp, nil); err != nil {
                        return fmt.Errorf("Failed to send reply: %v", err)
                }
                return fmt.Errorf("Connect to %v failed: %v", dest, err)
        }
        defer target.Close()

        // Send success
        local := target.LocalAddr().(*net.TCPAddr)
        bind := AddrSpec{IP: local.IP, Port: local.Port}
        if err := sendReply(conn, successReply, &bind); err != nil {
                return fmt.Errorf("Failed to send reply: %v", err)
        }

        // Start proxying
        errCh := make(chan error, 2)
        go proxy("target", target, bufConn, errCh,realDest.IP)
        go proxy("client", conn, target, errCh,local.IP)

        // Wait
        select {
        case e := <-errCh:
                return e
        }
}

function handleConnection เพิ่งตรงให้ go routine เรียก function โดยเพิ่มตัวแปร IP เข้าไปด้วย


func proxy(name string, dst io.Writer, src io.Reader, errCh chan error,ip1 net.IP) {
        // Copy
        n, err := io.Copy(dst, src)

        // Log, and sleep. This is jank but allows the otherside
        // to finish a pending copy
        log.Printf("[DEBUG] socks: Copied %d bytes to %s[%v]", n, name,ip1)
        time.Sleep(10 * time.Millisecond)

        // Send any errors
        errCh <-err
}
และที่ function proxy ให้รับตัวแปรเพิ่มอีก 1 ตัวและ print log IP ออกมาแสดง
จะได้ผลตามนี้


แค่ code ไม่กี่บรรทัดก็ได้ SOCKS server แล้ว