/*******************************************/ /* _mhttponc.pkg : _on by http :-) */ /* by Marc Barilley */ /* inspired by work done by Sylvain Huet */ /* supports switch beetween _on / HTTPsend */ /*******************************************/ /* */ fun clibychannel_c (c, chn)= c.Http_Chn_Client_uchannel == chn;; fun deleteHTTPclient_c (c)= _fooS "deleteHTTPclient_c"; set c.Http_Chn_Client_bufHTTPout = nil; set c.Http_Chn_Client_bufHTTPin = nil; if c.Http_Chn_Client_INET==nil then nil else { _fooS "INETStopURL c.Http_Chn_Client_INET"; INETStopURL c.Http_Chn_Client_INET; set c.Http_Chn_Client_INET=nil; }; _killchannel c.Http_Chn_Client_uchannel; set c.Http_Chn_Client_uchannel=nil; set http_clients_list = remove_from_list http_clients_list c; 0;; fun errHTTPsys_c (c)= _fooS "errHTTPsys_c"; 0;; fun execHTTP_c (c)= _fooS "execHTTP_c"; if (c==nil) || (c.Http_Chn_Client_bufHTTPin==nil) then { _fooS "client nil !!!"; 0 } else if (strlen c.Http_Chn_Client_bufHTTPin)>=8 then let htoi substr c.Http_Chn_Client_bufHTTPin 0 8 -> l in if (strlen c.Http_Chn_Client_bufHTTPin)>=8+l then let substr c.Http_Chn_Client_bufHTTPin 8 l -> scr in ( set c.Http_Chn_Client_bufHTTPin = substr c.Http_Chn_Client_bufHTTPin 8+l strlen c.Http_Chn_Client_bufHTTPin; _scriptc c.Http_Chn_Client_uchannel scr; _fooS " boucle sur execHTTP_c"; execHTTP_c c ) else 0 else 0;; fun errHTTP_c (c)= _fooS "errHTTP_c"; _scriptc c.Http_Chn_Client_uchannel "_closed"; deleteHTTPclient_c c;; proto fis_signal_c = fun [Http_Chn_Client_Struct] Http_Chn_Client_Struct;; /* send command */ fun cbgetSend_c (inet, c, s, reason)= _fooS "Http reception send "; _fooS strcat " s==" s; _fooS strcat " strlen s==" (itoa strlen s); _fooS strcat " reason==" (itoa reason); if (reason==0) then ( set c.Http_Chn_Client_curget=strcat c.Http_Chn_Client_curget s; 0 ) else if reason==1 then if (!strcmp c.Http_Chn_Client_curget "FIS") then ( set c.Http_Chn_Client_nummsg = c.Http_Chn_Client_nummsg+1; set c.Http_Chn_Client_lastmsg = nil; fis_signal_c c; 0 ) else { set c.Http_Chn_Client_state = HTTP_ABNORMAL_TERMINATION; _fooS " le serveur ne me reconnait pas."; errHTTP_c c } else if c.Http_Chn_Client_lastmsg==nil then { _fooS " il n'y avait pas de message mais une connection quand meme."; set c.Http_Chn_Client_state = HTTP_ABNORMAL_TERMINATION; errHTTP_c c } else ( set c.Http_Chn_Client_bufHTTPout = c.Http_Chn_Client_lastmsg::c.Http_Chn_Client_bufHTTPout; fis_signal_c c; 0 );; fun flush_http_c (c)= _fooS "flush_http_c"; if (c.Http_Chn_Client_ticket==nil) || (c.Http_Chn_Client_fis==0) then { _fooS " cmd not sent"; _fooS strcat " fis ==" itoa c.Http_Chn_Client_fis; _fooS strcat " ticket ==" itoa c.Http_Chn_Client_ticket; set c.Http_Chn_Client_state = HTTP_CONNECTING; nil } else if c.Http_Chn_Client_bufHTTPout != nil then { _fooS " sending cmd"; _fooS strcat " ticket ==" itoa c.Http_Chn_Client_ticket; _fooS strcat " nummsg ==" itoa c.Http_Chn_Client_nummsg; match hd c.Http_Chn_Client_bufHTTPout with (Http_Chn_Client_UserCommand cmd -> { _fooS strcat " user command==" cmd; _fooS strcat " url ==" strcatn c.Http_Chn_Client_urlhttp::"S"::(itoh8 c.Http_Chn_Client_ticket)::(itoh4 c.Http_Chn_Client_nummsg)::nil; set c.Http_Chn_Client_INET = INETGetURLex _channel "POST" strcatn c.Http_Chn_Client_urlhttp::"S"::(itoh8 c.Http_Chn_Client_ticket)::(itoh4 c.Http_Chn_Client_nummsg)::nil cmd 0 @cbgetSend_c c; if c.Http_Chn_Client_INET==nil then { _fooS " echec connection commande"; errHTTP_c c; nil } else { set c.Http_Chn_Client_curget=nil; set c.Http_Chn_Client_lastmsg = hd c.Http_Chn_Client_bufHTTPout; set c.Http_Chn_Client_bufHTTPout = tl c.Http_Chn_Client_bufHTTPout; set c.Http_Chn_Client_fis=0; c } } ) |(Http_Chn_Client_SysCommand cmd -> match cmd with (Http_Chn_Client_SysCommand_CloseClient -> { _scriptc c.Http_Chn_Client_uchannel "_closed"; deleteHTTPclient_c c; nil } ) |(_ -> nil) ) |(_ -> c) } else { _fooS " bufHTTPout == NIL"; nil } ;; fun add_http_c (c, l, msg)= if c==nil then { _fooS "add_http_c"; _fooS " c==NIL !!!!"; nil } else if l==nil then (Http_Chn_Client_UserCommand msg)::nil else let l->[a n] in a::add_http_c c n msg ;; fun fis_signal_c (c)= _fooS "fis_signal_c"; set c.Http_Chn_Client_fis = 1; flush_http_c c ;; /* "life socket" */ var firstTime_http_cblifeINET_c = 1;; proto cblifeINET_c = fun [INET Http_Chn_Client_Struct S I] I;; fun reconnectHTTP_c (c)= _fooS " RECONNEXION"; _fooS strcat " ticket == " (itoa c.Http_Chn_Client_ticket); set c.Http_Chn_Client_lifeINET = INETGetURL _channel strcatn c.Http_Chn_Client_urlhttp::"R"::(itoh8 c.Http_Chn_Client_ticket)::nil 0 @cblifeINET_c c; if c.Http_Chn_Client_lifeINET==nil then { set c.Http_Chn_Client_state = if c.Http_Chn_Client_bufHTTPout != nil then HTTP_ABNORMAL_TERMINATION else HTTP_SERVER_CLOSED; _fooS " echec re - connection"; errHTTP_c c; } else { set c.Http_Chn_Client_state = HTTP_CONNECTED; _fooS " re - connection reussie"; 0 };; fun cblifeINET_c (inet, c, s, reason)= _fooS "life socket callback"; _fooS strcat " reason==" itoa reason; if c.Http_Chn_Client_uchannel==nil /* client déjà mort */ then { _fooS " le client est deja mort : c.Http_Chn_Client_uchannel==nil"; INETStopURL c.Http_Chn_Client_lifeINET; nil } else { if reason==0 /* réception d'un message */ then ( _fooS strcat " s==" s; set c.Http_Chn_Client_bufHTTPin = strcat c.Http_Chn_Client_bufHTTPin s; nil ) else if reason==1 /* la transmission est finie */ then if c.Http_Chn_Client_state & HTTP_FIRST_CONNECTION then { _fooS "c.Http_Chn_Client_bufHTTPin =="; _fooS c.Http_Chn_Client_bufHTTPin; if (strfind "__http_syscmd_init_connexion_ticket" c.Http_Chn_Client_bufHTTPin 0) != nil then { set c.Http_Chn_Client_state = c.Http_Chn_Client_state &~ HTTP_FIRST_CONNECTION; execHTTP_c c; _fooS "Voila, c'est mon _connected a moi tout seul"; _scriptc c.Http_Chn_Client_uchannel "_connected"; reconnectHTTP_c c } else { set c.Http_Chn_Client_state = HTTP_NO_SERVER; _fooS " first connection failed"; errHTTP_c c; } } else if (c.Http_Chn_Client_ticket==nil) && ((strlen c.Http_Chn_Client_bufHTTPin) == 0) then { set c.Http_Chn_Client_state = HTTP_NO_SERVER; _fooS " pas de serveur"; errHTTP_c c; } else { execHTTP_c c; reconnectHTTP_c c } else /* il y a eu une erreur */ { set c.Http_Chn_Client_state = if c.Http_Chn_Client_bufHTTPout != nil then HTTP_ABNORMAL_TERMINATION else HTTP_SERVER_CLOSED; _fooS " echec connection"; errHTTP_c c; }; }; reason;; /* */ fun http_openchannel (url, script, env)= _fooS "http_openchannel"; let cutbypoints strtolist url -> [addr port] in let listtostr addr -> addr in let atoi listtostr port -> port in let mkHttp_Chn_Client_Struct [ url /* Http_Chn_Client_rurl */ addr /* Http_Chn_Client_rchannelIP */ port /* Http_Chn_Client_rchannelport */ script /* Http_Chn_Client_script */ nil /* Http_Chn_Client_uchannel */ nil /* Http_Chn_Client_ticket */ "" /* Http_Chn_Client_bufHTTPin */ 1 /* Http_Chn_Client_fis */ nil /* Http_Chn_Client_bufHTTPout */ nil /* Http_Chn_Client_lastmsg */ strcatn /* Http_Chn_Client_urlhttp */ "http://"::addr:: (if !strcmpi _getress "Firewall" "strong" then nil else strcat ":" (itoa port)):: "/"::(itoh4 port)::"?":: nil 0 /* Http_Chn_Client_nummsg */ "" /* Http_Chn_Client_curget */ nil /* Http_Chn_Client_INET */ nil /* Http_Chn_Client_lifeINET */ HTTP_FIRST_CONNECTION ] -> c in { _fooS strcat " addr ==" addr; _fooS strcat " port ==" itoa port; _fooS strcat " c.Http_Chn_Client_urlhttp== " c.Http_Chn_Client_urlhttp; set c.Http_Chn_Client_lifeINET = INETGetURL _channel (strcat c.Http_Chn_Client_urlhttp "C") 0 @cblifeINET_c c; if c.Http_Chn_Client_lifeINET==nil then { _fooS " echec openchannel"; set c.Http_Chn_Client_state = HTTP_ABNORMAL_TERMINATION; errHTTP_c c; nil } else { set c.Http_Chn_Client_state = HTTP_FIRST_CONNECTION | HTTP_CONNECTING; set http_clients_list = c::http_clients_list; set c.Http_Chn_Client_uchannel = _openchannel nil nil env; _scriptc c.Http_Chn_Client_uchannel strcatn "_load \"locked/lib/_mhttponprec.pkg\"\n":: "initHttpUnpluggedChannel\n":: script:: nil; Http_Chn_Client c } };;