Добавлено: Пятница, 13 Марта, 2009 16:07 Размещено в: Новости проекта
Убедительная просьба, если Вам надо прокачать большое количество адресов, просьба заключать их в один запрос (не более 4000 Ip в одном запросе). В скором времени будет выложен пример скрипта на perl для прокачки лога Apache.
Теперь мы подключили XML-сервис обработки запросов на определение местонахождения российских IP-адресов. Сервис обслуживается специальным сервером. Сервер получает запрос в формате XML через POST HTTP запрос, отдает ответ также в формате XML.
Сервер расположен по адресу 194.85.91.253, порт 8090, работает по протоколу HTTP. Метод GET сервером не поддерживается. Минимальный заголовок HTTP запроса выглядит следующим образом:
POST /geo/geo.html HTTP/1.1
Content-length: CL
,где CL - длина тела запроса
Формат тела запроса выглядит следующим образом:
<ipquery [id="123456"]>
<fields>
[<all/>]
[<inetnum/>]
[<inet-descr/>]
[<inet-status/>]
[<city/>]
[<region/>]
[<district/>]
[<lat/>]
[<lng/>]
</fields>
<ip-list>
<ip>62.5.128.0</ip>
<ip>144.206.192.23</ip>
….
<ip>85.44.33.22</ip>
</ip-list>
</ipquery>
,где id=”123456″ - необязательный параметр. Это идентификатор запроса, в кавычках - любые числа и буквы, ответ сервера будет содержать указанный вами id; тег <fields> содержит поля, которые вы хотите получить:
<inetnum/> - блок адресов, к которому относится искомый ip-адрес
<inet-descr/> - описание блока по базе RIPE (www.ripe.net)
<inet-status/> - статус блока по базе RIPE
<city/> - город, к которому относится искомый ip
<region/> - регион, к которому относится искомый ip
<district/> - федеральный округ РФ, к которому относится искомый ip
<lat/> - географическая широта города
<lng/> - географическая долгота города
<all/> - все вышеперечисленные поля
В теге <ip-list> содержится список ip, которые надо прокачать. Это может быть один ip, или несколько. Максимальное количество 4000 ip в одном запросе. Каждый ip обрамляется тегами <ip> и </ip>.
Формат ответа сервера:
<ip-answer id=”123456″>
<ip value=”62.5.128.0″>
<inetnum>62.5.128.0 - 62.5.128.15</inetnum>
<inet-descr>Subnetwork for VA159-RIPE</inet-descr>
<inet-status>ASSIGNED PA</inet-status>
<city>Москва</city>
<region>Москва</region>
<district>Центральный</district>
<lat>55.755787</lat>
<lng>37.617634</lng>
</ip>
….
</ip-answer>
По каждому адресу, мы получаем список полей, которые мы указали в <fields> в запросе. В вышеуказанном примере ответа в запросе был указан <all/>.
Для обращения к серверу с вашего сайта, можно использовать стандартную библиотеку HTTP (имеется практически во всех языках программирования). Подключаемся к 194.85.91.253:8090, отправляем POST запрос на /geo/geo.html, в котором содержится <ipquery>…</ipquery>. В скором времени будут выложены примеры на различных языках.
Для обращения к серверу через форму нужно вставить такой HTML код:
<form name = “index” action = “http://194.85.91.253:8090/geo/geo.html” method = “post”>
<textarea name=”address”></textarea>
<input type=”submit” value=”OK”>
</form>
Названия формы и поля <textarea> не важны. В поле textarea вставляется запрос в формате XML, указанный выше. Например:
|
7 Апреля, 2010 в 13:54
Класс для PHP
Метод getLocation в качестве вводных параметров получает массив с IP адресами, и возвращает объект SimpleXML (UTF-8)
asXML();
$query = “POST /geo/geo.html HTTP/1.1\r\nContent-Length: “.strlen ($xml).”\r\n\r\n$xml\r\n\r\n”;
if (!$socket = fsockopen($this->ipHost, $this->ipPort)) {
$result=”No Connection”;
} else {
$response = ”;
fwrite($socket, $query);
while (!feof($socket)) $response.= fgets($socket, 2048);
fclose($socket);
// Конвертируем ответ в XML-строку в кодировке UTF-8
$result=str_replace(’Windows-1251′, ‘UTF-8′, iconv(’Windows-1251′, ‘UTF-8′,str_replace(”\n”, ”, mb_substr($response.’ ‘, mb_strpos($response,’<?’ ,0,’Windows-1251′), -1, ‘Windows-1251′)) ));
}
return simplexml_load_string($result);
}
public function getLocation($ip) {
$ipList=simplexml_load_string(”);
for ($i=0;$i{’ip-list’}->addChild(’ip’,$ip[$i]);
}
return $this->connectGeoIPserver($ipList);
}
}
$geoip=new GeoIP();
$xml=$geoip->getLocation(array(’212.69.101.20′,’92.255.241.1′,’93.186.231.222′));
echo $xml->asXML();
?>
7 Апреля, 2010 в 13:59
Класс для PHP >5.x
Метод getLocation в качестве вводных параметров получает массив с IP адресами, и возвращает объект SimpleXML (UTF-8)
geoip.txt
21 Апреля, 2010 в 14:27
Добрый день. Спасибо за сервис.
).
Возникла сложность, на новом хостинге закрыт порт 8090, открыты только 80 и 443 (открыть нужный достаточно проблематично и затратно
Есть ли возможность повесить данный сервис на один из этих портов?
22 Апреля, 2010 в 13:40
Возникла сложность, на новом хостинге закрыт порт 8090, открыты только 80 и 443 (открыть нужный достаточно проблематично и затратно
Есть ли возможность повесить данный сервис на один из этих портов?
Добрый день!
К сожалению такой возможности нет. Не совсем ясна Ваша проблема. Вы же не поднимаете сервер у себя на хостинге, Вы обращаетесь к нам. По идее можно опрашивать любой порт.
Мы не можем поменять порт сервиса, т.к. на 80 порту живет сайт, а 443 - зарезервирован для HTTPS
22 Апреля, 2010 в 14:17
Проблема в том, что на хостинге закрыты все исходящие порты, кроме 80 и 443го. Такие у них правила.
8090 можно открыть, но если заплатить за выделенный IP адрес, его стоимость это 50% от стоимости самого хостинга…
Думаю у друзей на сервере сделать шлюз с 80 на 8090, но стабильность такого варианта будет низка…
23 Апреля, 2010 в 14:39
8090 можно открыть, но если заплатить за выделенный IP адрес, его стоимость это 50% от стоимости самого хостинга…
Думаю у друзей на сервере сделать шлюз с 80 на 8090, но стабильность такого варианта будет низка…
Дык Вам не нужен исходящий порт, Вы же делаете запрос к порту, а не поднимаете его у себя.
23 Апреля, 2010 в 15:59
Не правильно выразился, возможно. Фаервол режет все порты исходящие/входящие, кроме двух.
Вот цитата из хелпа хостинга:
Problem:
Why am I unable to use the fsockopen function?
Solution:
The fsockopen function will work for outbound connection to any URL on port 80 (HTTP) or 443 (HTTPS). If fsockopen is attempting to use another port, it will not work until we have added that port to the firewall.
By default, your account is on a shared IP address. We have a firewall for our shared IP customers which prohibits opening additional ports. If you need to connect using a port number other than 80 or 443, this will require you purchase a Dedicated IP for your Hostmonster account.
24 Мая, 2010 в 13:19
RE:Значения переменных $xml_query и $xml_response укажите.
А какое значение указать для $xml_response ???
24 Мая, 2010 в 13:55
Подскажите, есть где-то пример использования данных с сайта при помощи asp?
24 Мая, 2010 в 16:05
Пока к сожалению нет.
9 Июня, 2010 в 15:04
Доброй день. Хочу сообщить, что блоки
1.Населенный пункт Южно-Сахалинск
Блок IP-адресов:
188.168.64.0 - 188.168.65.255
2.Населенный пункт Чита
Блок IP-адресов
188.168.60.0 - 188.168.60.255
188.168.61.0 - 188.168.61.255
распознаются сервисом как Москва, Москва,
Хотя на сайте http://ipgeobase.ru/cgi-bin/AdvSearch.cgi в поиске выдается верный результат. Для контроля работы сервиса как раз данные с сайта и использовались.
9 Июня, 2010 в 15:20
86.110.176.0 - 86.110.179.0
то же самое - Москва
18 Июня, 2010 в 15:47
Иван, спасибо за замечание. Ошибка исправлена.
22 Июня, 2010 в 15:34
Вдохновившись сервисом http://jsonip.appspot.com создал похожую обвязку для xml-сервиса ipgeobase’а: http://jsonipgeobase.appspot.com
Принимаемые параметры (все необязательные):
callback - имя callback-функции для jsonp, если не передавать, то в ответ будет json
fields - любые поля из [inetnum, inet-descr, inet-status, city, region, district, lat, lng], т.е. какие поля отправлять в запросе к ipgeobase, если не указаны, то в запросе будет “all”
Выходные параметры:
status - “ok” если был получен корректный ответ от ipgeobase, “error” - в противном случае
ip - ip-адрес клиента
inetnum, inet-descr, inet-status, city, region, district, lat, lng - из ответа ipgeobase
Пример использования:
http://jsonipgeobase.appspot.com/?callback=geoip&fields=city&fields=lng&fields=lat
В ответ получим jsonp вида:
geoip({”status”: “ok”, “ip”: “94.24.168.68″, “lng”: “61.402580″, “lat”: “55.159889″, “city”: “\u0427\u0435\u043b\u044f\u0431\u0438\u043d\u0441\u043a”});
24 Июня, 2010 в 10:47
Пример для asp.net
public class IpGeo
{
public string inetnum { get; set; }
public string inet_descr { get; set; }
public string inet_status { get; set; }
public string city { get; set; }
public string region { get; set; }
public string district { get; set; }
public string lat { get; set; }
public string lng { get; set; }
}
protected void Page_Load(object sender, EventArgs e) {
List ipgeo = readHtmlPage(”http://194.85.91.253:8090/geo/geo.html”);
}
private List readHtmlPage(string url)
{
string VisitorIP = Request.ServerVariables["REMOTE_ADDR"];
String strPost = “” + VisitorIP + “”;
StreamWriter myWriter = null;
HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
objRequest.Method = “POST”;
objRequest.ContentLength = strPost.Length;
try
{
myWriter = new StreamWriter(objRequest.GetRequestStream());
myWriter.Write(strPost);
}
catch (Exception e)
{
}
finally
{
myWriter.Close();
}
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
Encoding encode = System.Text.Encoding.GetEncoding(”Windows-1251″);
List ipGeo = new List();
using (StreamReader sr =
new StreamReader(objResponse.GetResponseStream(), encode))
{
string result = sr.ReadToEnd();
TextReader tr = new StringReader(result);
XElement xmlTree = XElement.Load(tr);
sr.Close();
try
{
ipGeo.AddRange(
(from mi in xmlTree.Elements(”ip”)
where mi.Attribute(”value”).Value == VisitorIP
select new IpGeo
{
inetnum = mi.Element(”inetnum”).Value,
inet_descr = mi.Element(”inet-descr”).Value,
inet_status = mi.Element(”inet-status”).Value,
lat = mi.Element(”lat”).Value,
lng = mi.Element(”lng”).Value,
city = mi.Element(”city”).Value,
region = mi.Element(”region”).Value,
district = mi.Element(”district”).Value
}));
}
catch
{
}
tr.Close();
foreach (IpGeo ipgeo in ipGeo)
{
Response.Write(”IP: ” + VisitorIP + “”);
Response.Write(”Округ: ” + ipgeo.district + “”);
Response.Write(”Регион: ” + ipgeo.region + “”);
Response.Write(”Город: ” + ipgeo.city + “”);
Response.Write(”Широта: ” + ipgeo.lat + “”);
Response.Write(”Долгота: ” + ipgeo.lng + “”);
}
}
return ipGeo;
}
1 Июля, 2010 в 12:05
а почему ругается?
Call to undefined function curl_init() on line 13
14 Июля, 2010 в 16:47
function get_city ($ip)
юзайте на здоровье!
{
$curl = curl_init();
curl_setopt_array ($curl, array (
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => “http://194.85.91.253:8090/geo/geo.html”,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS =>”address=”.urlencode(”".$ip.”")
)
);
$rez = curl_exec ($curl);
if (preg_match (”|\(.*)\|”, $rez, $city))
{
return $city[1];
}
return “неизвестный город”;
}
$city = get_city ($_SERVER['REMOTE_ADDR']);
Вот такой вариан с использованием курла
4 Августа, 2010 в 13:24
Есть в Вашей базе сервиса ipv6 локации?
5 Августа, 2010 в 11:18
Еще раз подыму вопрос про реализацию запросов к вашему сервису не со стороны сервера (PHP скрипта) а со стороны клиента (javascript+AJAX).
Ктонибудь уже успешно реализовал данную задачу? Если нет, то думаю стоит об этом подумать ибо часто бывает что на хостинге в целях безопасности закрыт доступ к внешним IP да и еще к томуже на нестандартные порты TCP.
PS Может админам сервиса стоит создать офиц.клуб обсуждения сервиса на Яндексе (clubs.ya.ru)?
Очень много толковых людей пользуются тамошними клубами.
5 Августа, 2010 в 17:31
Пока нет, но в будущем обязательно появятся.
5 Августа, 2010 в 17:43
Ктонибудь уже успешно реализовал данную задачу? Если нет, то думаю стоит об этом подумать ибо часто бывает что на хостинге в целях безопасности закрыт доступ к внешним IP да и еще к томуже на нестандартные порты TCP.
PS Может админам сервиса стоит создать офиц.клуб обсуждения сервиса на Яндексе (clubs.ya.ru)?
Очень много толковых людей пользуются тамошними клубами.
Пока мы не планируем реализацию клиентского приложения. Если вы напишите подобную программу и поделитесь с нами, мы выложим ее на сайте с указанием автора.
6 Августа, 2010 в 13:52
KDV, см. коммент 44993 (http://blog.ipgeobase.ru/?p=37#comment-44993)