ปรับ Codeigniter ให้รองรับ IPv6

codeigniter

IP v4 ได้แจกจนหมดเกลี้ยงไปแล้วเมื่อเดือนกุมภาพันธ์ 2554 แต่ Codeigniter ยังไม่ได้ออกมารองรับ IPv6 รุ่นใหม่เลย
ดังนั้นเมื่อผู้ใช้ web server รุ่นใหม่อย่าง IIS, apache2.4 ที่รองรับ IPv6 เวลาเรียก $this->input->ip_address ก็จะได้ ip 0.0.0.0 ทั้งๆที่แม้จะรันอยู่บน localhost ก็ตาม

สาเหตุเนื่องมาจากการตัดสินใจส่ง ip address กลับไปยัง method นี้นั้นจะผ่านการตรวจ valid_ip() ก่อน และใน method valid_ip() นี้เองที่ยังไม่มีการอัพเดทให้รองรับการตรวจสอบ IPv6 มันจึงส่งค่า 0.0.0.0 กลับไป
โค้ดต่อไปนี้เขียนโดยนาย DjLeChuck ซึ่งทำให้สามารถตรวจ IPv6 ได้อย่างถูกต้องไร้ปัญหา

นำโค้ดต่อไปนี้ ใส่ไว้ใน class MY_Input extends CI_Input {...ในนี้...}
แล้วบันทึกเป็นชื่อไฟล์ MY_Input.php ใน application/core/


    /**
     * Validate IP Address
     *
     * Updated version suggested by Geert De Deckere
     * Add IPV6 validation
     * @author DjLeChuck
     * @link http://codeigniter.com/forums/viewthread/182457/
     *
     * @access    public
     * @param    string
     * @return    string
     */
    function valid_ip($ip) {
        // Check if it's IPV4 or IPV6
        if (substr_count($ip, ':') > 0):
            // IPV6
            // RegExp from http://forums.dartware.com/viewtopic.php?t=452
            // MUST be in 1 line !
            define('IPV6_REGEX', "/^\s*((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4}){0,4}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))(%.+)?\s*$/");

            if (!preg_match(IPV6_REGEX, $ip)):
                return FALSE;
            endif;
        else:
            // IPV4
            $ip_segments = explode('.', $ip);

            // Always 4 segments needed
            if (count($ip_segments) != 4) {
                return FALSE;
            }
            // IP can not start with 0
            if ($ip_segments[0][0] == '0') {
                return FALSE;
            }
            // Check each segment
            foreach ($ip_segments as $segment) {
                // IP segments must be digits and can not be
                // longer than 3 digits or greater then 255
                if ($segment == '' OR preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3) {
                    return FALSE;
                }
            }
        endif;

        return TRUE;
    }

คราวนี้เมื่อลองเรียกดู ip address ด้วย $this->input->ip_address() บน localhost ก็จะได้ ::1 แทน 127.0.0.1 เหมือนอย่างเคย

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

คุณอาจใช้แท็กHTMLและแอททริบิวต์เหล่านี้: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>