ปรับ 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 เหมือนอย่างเคย

ใส่ความเห็น

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>