Ответы пользователя по тегу iOS
  • Как грамотно обработать iOS CNA при подключении к WiFI с Captive Portal?

    OCTAGRAM
    @OCTAGRAM
    Следите за руками:

    21:23:25 GET "captive.apple.com" /hotspot-detect.html HTTP/1.0 302 0 - "CaptiveNetworkSupport-346 wispr" - - - "http://captive.apple.com/hotspot-1.html"
    21:23:25 GET "captive.apple.com" /hotspot-1.html HTTP/1.0 403 86 - "CaptiveNetworkSupport-346 wispr" - - - -
    21:23:26 GET "captive.apple.com" /hotspot-detect.html HTTP/1.1 200 467 - "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Mobile/14C92" - - - -
    21:23:26 GET "captive.apple.com" /hotspot-detect.html HTTP/1.0 200 68 - "CaptiveNetworkSupport-346 wispr" - - - -
    21:23:28 GET "captive.apple.com" /hotspot-2.html HTTP/1.1 302 0 - "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0 Mobile/14C92 Safari/602.1" - - - "http://мой-URL"


    Первые два ответа — это чтобы показать wispr такую бяку, чтоб он захотел вмешаться. wispr и на Mac OS X, и на iOS заканчивается на " wispr". Сразу 403 или 200 без Success как-то не очень работают, а 302 — вполне, но раз 302, то и по другому адресу надо что-то ответить. Потом запускается CNS (нет Safari), и ему отдаётся страничка, на которой есть Success и скрипт, который через полсекунды создаст обычную (без _blank) ссылку с абсолютным URL (который с двоечкой) и нажмёт по ней click()'ом. При отдаче страницы на stateful сервере помечается этот комп. Либо переход по ссылке, либо Success и код 200 на странице, либо просто это делается каждый раз после первого открытия, пока не разобрался, что-то из этого заставляет сделать ещё один запрос wispr, и на этот раз помеченному компу отдаётся самый обычный Success, а когда через полсекунды пойдёт переход по ссылке, CNS уже будет в состоянии «Готово» и направит переход в настоящий Safari, а сам закроется. При обнаружении открытия ссылки настоящим Safari пометка с компа сбрасывается.

    Бывает, зацикливается в CNA, но после увеличения задержки на секунду вроде нормализовалось.

    with AWS.Status;
    with AWS.Response;
    
    package Worker_Echoes.Apple.Captive is
    
       function Service (Request : AWS.Status.Data)
         return AWS.Response.Data;
    
    end Worker_Echoes.Apple.Captive;


    with Ada.Strings.Fixed;
    
    with AWS.URL;
    with AWS.Messages;
    
    with Worker_Echoes.Protected_Strings;
    with Worker_Echoes.Config;
    
    package body Worker_Echoes.Apple.Captive is
    
       use AWS;
       use all type AWS.Messages.Status_Code;
    
       Last_CNA_CNS_Peername : Protected_Strings.Protected_String;
    
       -------------
       -- Service --
       -------------
    
       function Service (Request : Status.Data) return Response.Data is
          URL_Object : constant URL.Object := Status.URI (Request);
          URL_String : constant String := URL.URL (URL_Object);
          User_Agent : constant String := Status.User_Agent (Request);
       begin
          if User_Agent'Length >= 6 and then User_Agent (User_Agent'Last - 5 .. User_Agent'Last) = " wispr" then
             if Last_CNA_CNS_Peername.Get = Status.Peername (Request) then
                return Response.Build
                  (Status_Code => S200,
                   Content_Type => "text/html; charset=utf-8",
                   Message_Body => "<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>");
             elsif URL_String = "http://captive.apple.com/hotspot-1.html" then
                return Response.Build
                  (Status_Code => S200,
                   Content_Type => "text/html; charset=utf-8",
                   Message_Body => "<HTML><HEAD></HEAD><BODY></BODY></HTML>");
             else
                return Response.URL ("http://captive.apple.com/hotspot-1.html");
             end if;
          elsif Ada.Strings.Fixed.Index (User_Agent, "Safari") = 0 then
             Last_CNA_CNS_Peername.Set (Status.Peername (Request));
    
             -- 1. Not sure if intact "<BODY>Success</BODY>" matters, but probably yes.
             -- 2. There was no delay previously, thus A had to be created before BODY is processed.
             --    Now it's possible to click A with id, but touching working code was avoided.
             return Response.Build
               (Status_Code => S200,
                Content_Type => "text/html; charset=utf-8",
                Message_Body => "<HTML><HEAD><SCRIPT>" &
                                   "window.setTimeout (function () {" &
                                      "var A = document.createElement (""a"");" &
                                      "A.setAttribute (""href"", ""http://captive.apple.com/hotspot-2.html"");" &
                                      "var Body = document.getElementsByTagName (""body"");" &
                                      "if (Body.length > 0) {" &
                                         "Body = Body [0];" &
                                      "} else {" &
                                         "Body = document.createElement (""body"");" &
                                         "document.getElementsByTagName (""html"") [0].appendChild (Body);" &
                                      "}" &
                                      "Body.appendChild (A);" &
                                      "A.click ();" &
                                   "}, 1000);" &
                                "</SCRIPT>" &
                                "<STYLE>body { display: none; }</STYLE>" &
                                "<TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>");
          else
             Protected_Strings.Reset (Last_CNA_CNS_Peername, Status.Peername (Request)); -- reset if matches
             return Response.URL (Config.Get_Target_URL);
          end if;
       end Service;
    
    end Worker_Echoes.Apple.Captive;
    Ответ написан
    1 комментарий
  • Как открыть safari из captiveportal popup?

    OCTAGRAM
    @OCTAGRAM
    Следите за руками:

    21:23:25 GET "captive.apple.com" /hotspot-detect.html HTTP/1.0 302 0 - "CaptiveNetworkSupport-346 wispr" - - - "http://captive.apple.com/hotspot-1.html"
    21:23:25 GET "captive.apple.com" /hotspot-1.html HTTP/1.0 403 86 - "CaptiveNetworkSupport-346 wispr" - - - -
    21:23:26 GET "captive.apple.com" /hotspot-detect.html HTTP/1.1 200 467 - "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Mobile/14C92" - - - -
    21:23:26 GET "captive.apple.com" /hotspot-detect.html HTTP/1.0 200 68 - "CaptiveNetworkSupport-346 wispr" - - - -
    21:23:28 GET "captive.apple.com" /hotspot-2.html HTTP/1.1 302 0 - "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0 Mobile/14C92 Safari/602.1" - - - "http://мой-URL"


    Первые два ответа — это чтобы показать wispr такую бяку, чтоб он захотел вмешаться. wispr и на Mac OS X, и на iOS заканчивается на " wispr". Сразу 403 или 200 без Success как-то не очень работают, а 302 — вполне, но раз 302, то и по другому адресу надо что-то ответить. Потом запускается CNS (нет Safari), и ему отдаётся страничка, на которой есть Success и скрипт, который через полсекунды создаст обычную (без _blank) ссылку с абсолютным URL (который с двоечкой) и нажмёт по ней click()'ом. При отдаче страницы на stateful сервере помечается этот комп. Либо переход по ссылке, либо Success и код 200 на странице, либо просто это делается каждый раз после первого открытия, пока не разобрался, что-то из этого заставляет сделать ещё один запрос wispr, и на этот раз помеченному компу отдаётся самый обычный Success, а когда через полсекунды пойдёт переход по ссылке, CNS уже будет в состоянии «Готово» и направит переход в настоящий Safari, а сам закроется. При обнаружении открытия ссылки настоящим Safari пометка с компа сбрасывается.

    Бывает, зацикливается в CNA, но после увеличения задержки на секунду вроде нормализовалось.

    with AWS.Status;
    with AWS.Response;
    
    package Worker_Echoes.Apple.Captive is
    
       function Service (Request : AWS.Status.Data)
         return AWS.Response.Data;
    
    end Worker_Echoes.Apple.Captive;


    with Ada.Strings.Fixed;
    
    with AWS.URL;
    with AWS.Messages;
    
    with Worker_Echoes.Protected_Strings;
    with Worker_Echoes.Config;
    
    package body Worker_Echoes.Apple.Captive is
    
       use AWS;
       use all type AWS.Messages.Status_Code;
    
       Last_CNA_CNS_Peername : Protected_Strings.Protected_String;
    
       -------------
       -- Service --
       -------------
    
       function Service (Request : Status.Data) return Response.Data is
          URL_Object : constant URL.Object := Status.URI (Request);
          URL_String : constant String := URL.URL (URL_Object);
          User_Agent : constant String := Status.User_Agent (Request);
       begin
          if User_Agent'Length >= 6 and then User_Agent (User_Agent'Last - 5 .. User_Agent'Last) = " wispr" then
             if Last_CNA_CNS_Peername.Get = Status.Peername (Request) then
                return Response.Build
                  (Status_Code => S200,
                   Content_Type => "text/html; charset=utf-8",
                   Message_Body => "<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>");
             elsif URL_String = "http://captive.apple.com/hotspot-1.html" then
                return Response.Build
                  (Status_Code => S200,
                   Content_Type => "text/html; charset=utf-8",
                   Message_Body => "<HTML><HEAD></HEAD><BODY></BODY></HTML>");
             else
                return Response.URL ("http://captive.apple.com/hotspot-1.html");
             end if;
          elsif Ada.Strings.Fixed.Index (User_Agent, "Safari") = 0 then
             Last_CNA_CNS_Peername.Set (Status.Peername (Request));
    
             -- 1. Not sure if intact "<BODY>Success</BODY>" matters, but probably yes.
             -- 2. There was no delay previously, thus A had to be created before BODY is processed.
             --    Now it's possible to click A with id, but touching working code was avoided.
             return Response.Build
               (Status_Code => S200,
                Content_Type => "text/html; charset=utf-8",
                Message_Body => "<HTML><HEAD><SCRIPT>" &
                                   "window.setTimeout (function () {" &
                                      "var A = document.createElement (""a"");" &
                                      "A.setAttribute (""href"", ""http://captive.apple.com/hotspot-2.html"");" &
                                      "var Body = document.getElementsByTagName (""body"");" &
                                      "if (Body.length > 0) {" &
                                         "Body = Body [0];" &
                                      "} else {" &
                                         "Body = document.createElement (""body"");" &
                                         "document.getElementsByTagName (""html"") [0].appendChild (Body);" &
                                      "}" &
                                      "Body.appendChild (A);" &
                                      "A.click ();" &
                                   "}, 1000);" &
                                "</SCRIPT>" &
                                "<STYLE>body { display: none; }</STYLE>" &
                                "<TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>");
          else
             Protected_Strings.Reset (Last_CNA_CNS_Peername, Status.Peername (Request)); -- reset if matches
             return Response.URL (Config.Get_Target_URL);
          end if;
       end Service;
    
    end Worker_Echoes.Apple.Captive;
    Ответ написан
    2 комментария
  • DLNA клиент для iPad?

    OCTAGRAM
    @OCTAGRAM
    У Apple NAT-PMP и Bonjour, у Microsoft — UPnP. У Apple DAAP, у Microsoft — DLNA. Not Invented Here, just as always.

    Ставьте Firefly Media Server и раздавайте музыку по нормальному DAAP.

    Если DAAP на iPad не заведётся, для Firefly был патч.

    Есть дистрибутив Linux для медиасерверов, Amahi, в нём и DAAP и DLNA сервера
    Ответ написан