Java tutorial
// (c) Alexandre Fenyo 2012, 2013, 2014, 2015, 2016 - alex@fenyo.net - http://fenyo.net - GPLv3 licensed package net.fenyo.mail4hotspot.web; import java.io.IOException; import java.net.URLEncoder; import java.net.UnknownHostException; import java.util.Map; import net.fenyo.mail4hotspot.domain.*; import net.fenyo.mail4hotspot.domain.Account.Provider; import net.fenyo.mail4hotspot.service.AdvancedServices; import net.fenyo.mail4hotspot.service.Browser; import net.fenyo.mail4hotspot.service.GeneralServices; import net.fenyo.mail4hotspot.tools.GeneralException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import org.springframework.dao.*; import org.springframework.transaction.*; import javax.persistence.*; import javax.servlet.http.HttpServletRequest; // excellente doc sur les controller : "16.3 Implementing Controllers" de spring-framework-reference.pdf @Controller("webController") public class WebController { protected final Log log = LogFactory.getLog(getClass()); // @qualifier: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-autowired-annotation @Autowired private GeneralServices generalServices; @Autowired private AdvancedServices advancedServices; /* requests for users */ @RequestMapping("/intro") public ModelAndView intro() { log.info("TRACE: intro;done;"); ModelAndView mav = new ModelAndView(); mav.setViewName("say-hello"); return mav; } @RequestMapping("/admin") public ModelAndView admin() { log.info("TRACE: admin;done;"); ModelAndView mav = new ModelAndView(); mav.addObject("userList", generalServices.getUserList()); mav.setViewName("say-admin"); return mav; } @RequestMapping(value = "/getvaluepack", method = RequestMethod.GET) public ModelAndView getValuePack() { log.info("TRACE: getvaluepack;get;"); ModelAndView mav = new ModelAndView(); mav.setViewName("form-getvaluepack"); return mav; } // si on voulait directement envoyer le contenu du fichier quand le login/password est OK : http://stackoverflow.com/questions/6604509/spring-mvc-image-controller-to-display-image-bytes-in-jsp @RequestMapping(value = "/getvaluepack", method = RequestMethod.POST) public ModelAndView getValuePackPost(@RequestParam(value = "username", required = false) final String username, @RequestParam(value = "password", required = false) final String password, final ModelMap model) { log.info("TRACE: getvaluepack;post;" + username + ";" + password + ";"); ModelAndView mav = new ModelAndView(); try { final User user = generalServices.getUser(username); if (user.getPassword().equals(password) == false) { log.info("TRACE: getvaluepack;invalid password;" + username + ";" + password + ";"); mav.setViewName("getvaluepack-badauth"); } else { log.info("TRACE: getvaluepack;done;" + username + ";" + password + ";"); mav.setViewName("getvaluepack-goodauth"); } } catch (final Exception ex) { log.info("TRACE: getvaluepack;bad username;" + username + ";" + password + ";"); mav.setViewName("getvaluepack-badauth"); } return mav; } @RequestMapping(value = "/getuuid", method = RequestMethod.GET) public ModelAndView getUuid() { log.info("TRACE: getuuid;get;"); ModelAndView mav = new ModelAndView(); mav.setViewName("form-getuuid"); return mav; } @RequestMapping(value = "/getuuid", method = RequestMethod.POST) public ModelAndView getUuidPost(@RequestParam(value = "username", required = false) final String username, @RequestParam(value = "password", required = false) final String password, final ModelMap model) { log.info("TRACE: getuuid;post;" + username + ";" + password + ";"); ModelAndView mav = new ModelAndView(); try { final User user = generalServices.getUser(username); if (user.getPassword().equals(password) == false) { log.info("TRACE: getuuid;invalid password;" + username + ";" + password + ";"); mav.setViewName("getuuid-badauth"); } else { log.info("TRACE: getuuid;done;" + username + ";" + password + ";"); mav.addObject("user", user); mav.setViewName("getuuid-goodauth"); } } catch (final Exception ex) { log.info("TRACE: getuuid;bad username;" + username + ";" + password + ";"); mav.setViewName("getuuid-badauth"); } return mav; } @RequestMapping(value = "/create-account", method = RequestMethod.GET) public ModelAndView createAccount() { log.info("TRACE: createaccount;get;"); ModelAndView mav = new ModelAndView(); mav.setViewName("form-createaccount"); return mav; } @RequestMapping(value = "/create-account", method = RequestMethod.POST) public ModelAndView createAccountPost( @RequestParam(value = "user_username", required = false) final String user_username, @RequestParam(value = "username", required = false) final String username, @RequestParam(value = "email", required = false) final String email, @RequestParam(value = "password", required = false) final String password, @RequestParam(value = "provider", required = false) final String provider_string, final ModelMap model) throws GeneralException { log.info("TRACE: createaccount;post;" + user_username + ";" + provider_string + ";" + username + ";" + email + ";" + password + ";"); Account.Provider provider = null; if (provider_string.equals("GMAIL")) provider = Provider.GMAIL; if (provider_string.equals("HOTMAIL")) provider = Provider.HOTMAIL; if (provider_string.equals("OPERAMAIL")) provider = Provider.OPERAMAIL; if (provider_string.equals("YAHOO")) provider = Provider.YAHOO; if (provider_string.equals("TESTIMAPLOCALHOST")) provider = Provider.TESTIMAPLOCALHOST; if (provider_string.equals("TESTIMAPRSI")) provider = Provider.TESTIMAPRSI; if (provider_string.equals("TESTPOPLOCALHOST")) provider = Provider.TESTPOPLOCALHOST; if (provider_string.equals("TESTPOPRSI")) provider = Provider.TESTPOPRSI; generalServices.createAccount(user_username, username, email, password, provider); log.info("TRACE: createaccount;done;" + user_username + ";" + provider_string + ";" + username + ";" + email + ";" + password + ";"); ModelAndView mav = new ModelAndView("redirect:admin", model); return mav; } @RequestMapping(value = "/create-user", method = RequestMethod.GET) public ModelAndView createUser() { log.info("TRACE: createuser;get;"); ModelAndView mav = new ModelAndView(); mav.setViewName("form-createuser"); return mav; } @RequestMapping(value = "/create-user", method = RequestMethod.POST) public ModelAndView createUserPost(@RequestParam(value = "username", required = false) final String username, @RequestParam(value = "password", required = false) final String password, final ModelMap model) throws GeneralException { log.info("TRACE: createuser;post;" + username + ";" + password + ";"); generalServices.createUser(username, password); log.info("TRACE: createuser;done;" + username + ";" + password + ";"); ModelAndView mav = new ModelAndView("redirect:admin", model); //mav.setViewName("forward:admin"); // est trait en interne, l'URL ct browser ne change pas => pour que l'URL change, il faut utiliser redirect return mav; } @RequestMapping(value = "/drop-account", method = RequestMethod.GET) public ModelAndView dropAccount() { log.info("TRACE: drop-account;get;"); ModelAndView mav = new ModelAndView(); mav.setViewName("form-dropaccount"); return mav; } @RequestMapping(value = "/drop-account", method = RequestMethod.POST) public ModelAndView dropAccountPost(@RequestParam(value = "username", required = false) final String username, @RequestParam(value = "id", required = false) final long id, final ModelMap model) throws GeneralException { log.info("TRACE: drop-account;post;" + username + ";" + id + ";"); generalServices.dropAccount(username, id); log.info("TRACE: drop-account;done;" + username + ";" + id + ";"); ModelAndView mav = new ModelAndView("redirect:admin", model); return mav; } @RequestMapping(value = "/drop-user", method = RequestMethod.GET) public ModelAndView dropUser() { log.info("TRACE: drop-user;get;"); ModelAndView mav = new ModelAndView(); mav.setViewName("form-dropuser"); return mav; } @RequestMapping(value = "/drop-user", method = RequestMethod.POST) public ModelAndView dropUserPost(@RequestParam(value = "username", required = false) final String username, final ModelMap model) throws GeneralException { log.info("TRACE: drop-user;post;" + username + ";"); generalServices.dropUser(username); log.info("TRACE: drop-user;done;" + username + ";"); ModelAndView mav = new ModelAndView("redirect:admin", model); return mav; } @RequestMapping(value = "/create-default", method = RequestMethod.GET) public ModelAndView createDefault(final ModelMap model) { log.info("TRACE: create-default;get;"); generalServices.createDefault(); log.info("TRACE: create-default;done;"); ModelAndView mav = new ModelAndView("redirect:admin", model); return mav; } @RequestMapping(value = "/create-initial-users", method = RequestMethod.GET) public ModelAndView createInitialUsers(final ModelMap model) { log.info("TRACE: create-initial-users;get;"); generalServices.createInitialUsers(); log.info("TRACE: create-initial-users;done;"); ModelAndView mav = new ModelAndView("redirect:admin", model); return mav; } @RequestMapping(value = "/create-initial-ips", method = RequestMethod.GET) public ModelAndView createInitialIps(final ModelMap model) throws UnknownHostException { log.info("TRACE: create-initial-ips;get;"); generalServices.createInitialIps(); log.info("TRACE: create-initial-ips;done;"); ModelAndView mav = new ModelAndView("redirect:admin", model); return mav; } // @RequestMapping(value = "/process-mails", method = RequestMethod.GET) // public ModelAndView processMails(final ModelMap model) { // advancedServices.processMails(); // ModelAndView mav = new ModelAndView("redirect:admin", model); // return mav; // } @RequestMapping(value = "/process-mails2", method = RequestMethod.GET) public ModelAndView processMails2(final ModelMap model) { advancedServices.processMailsWithHeaderOnly("fenyoa"); ModelAndView mav = new ModelAndView("redirect:admin", model); return mav; } @RequestMapping(value = "/process-mails3", method = RequestMethod.GET) public ModelAndView processMails3(final ModelMap model) { advancedServices.processMails("fenyoa"); ModelAndView mav = new ModelAndView("redirect:admin", model); return mav; } @RequestMapping(value = "/testlog", method = RequestMethod.GET) public ModelAndView processTestlog(final ModelMap model) { advancedServices.testLog(); ModelAndView mav = new ModelAndView("redirect:admin", model); return mav; } /* requests for mobiles */ // for manual testing only @RequestMapping(value = "/mobile-create-user", method = RequestMethod.GET) public ModelAndView mobileCreateUser() { log.info("TRACE: mobile-create-user;get;"); ModelAndView mav = new ModelAndView(); mav.setViewName("mobile-form-createuser"); return mav; } @RequestMapping(value = "/mobile-create-user", method = RequestMethod.POST) public ModelAndView mobileCreateUserPost( @RequestParam(value = "username", required = false) final String username, @RequestParam(value = "password", required = false) final String password, @RequestParam(value = "info", required = false) final String info, final ModelMap model) { log.info("TRACE: mobile-create-user;post;" + username + ";" + password + ";" + info + ";"); ModelAndView mav = new ModelAndView(); mav.setViewName("mobile-action-createuser"); String trace_uuid = ""; try { final String uuid = generalServices.createUser(username, password); log.info("TRACE: mobile-create-user;exec;" + username + ";" + password + ";" + info + ";" + trace_uuid + ";"); trace_uuid = uuid; mav.addObject("statusCode", 0); mav.addObject("statusString", "OK"); mav.addObject("uuid", uuid); final Account account = generalServices.getFirstAccount(username); generalServices.sendInternalMailByAccount(account, "Welcome at VPN-over-DNS !", "Dear new customer,\n\nIn order to use this service, do not forget to configure you mail account by clicking on 'Configure mail' in the Configuration tab.\n\n-- The VPN-over-DNS support team."); generalServices.sendInternalMailByAccount(account, "Important message from VPN-over-DNS", "Dear customer,\n\nThe full documentation of this application is available at:\n www.vpnoverdns.com\n\nIn this web site, you will find every informations needed to know how to best configure and use VPN-over-DNS.\n\n-- The VPN-over-DNS support team."); log.info("TRACE: mobile-create-user;done;" + username + ";" + password + ";" + info + ";" + trace_uuid + ";"); } catch (final DataIntegrityViolationException ex) { // compte existe dj log.info("TRACE: mobile-create-user;user already exists;" + username + ";" + password + ";" + info + ";" + trace_uuid + ";"); log.warn(ex); mav.addObject("statusCode", 1); mav.addObject("statusString", "user already exists"); mav.addObject("uuid", ""); } catch (final TransactionSystemException ex) { // bdd down log.info("TRACE: mobile-create-user;bdd down;" + username + ";" + password + ";" + info + ";" + trace_uuid + ";"); log.warn(ex); mav.addObject("statusCode", 2); mav.addObject("statusString", "bdd down"); mav.addObject("uuid", ""); } catch (final Exception ex) { // autre cause d'erreur log.info("TRACE: mobile-create-user;exception;" + username + ";" + password + ";" + info + ";" + trace_uuid + ";"); log.warn(ex); mav.addObject("statusCode", 3); mav.addObject("statusString", ex.toString()); mav.addObject("uuid", ""); } return mav; } // for manual testing only @RequestMapping(value = "/mobile-get-user", method = RequestMethod.GET) public ModelAndView mobileGetUser() { log.info("TRACE: mobile-get-user;get;"); ModelAndView mav = new ModelAndView(); mav.setViewName("mobile-form-getuser"); return mav; } @RequestMapping(value = "/mobile-get-user", method = RequestMethod.POST) public ModelAndView mobileGetUserPost(@RequestParam(value = "username", required = false) final String username, @RequestParam(value = "password", required = false) final String password, @RequestParam(value = "info", required = false) final String info, final ModelMap model) { log.info("TRACE: mobile-get-user;post;" + username + ";" + password + ";" + info + ";"); ModelAndView mav = new ModelAndView(); mav.setViewName("mobile-action-getuser"); mav.addObject("provider", ""); mav.addObject("email", ""); mav.addObject("login", ""); mav.addObject("uuid", ""); try { final User user = generalServices.getUser(username); if (user.getPassword().equals(password) == false) { log.info("TRACE: mobile-get-user;invalid password;" + username + ";" + password + ";" + info + ";"); mav.addObject("statusCode", 1); mav.addObject("statusString", "invalid password"); mav.addObject("uuid", ""); final Account account = generalServices.getFirstAccount(username); generalServices.sendInternalMailByAccount(account, "Warning message from VPN-over-DNS", "Dear customer,\n\nThis is to inform you that there was an attempt to log on your VPN-over-DNS account with an invalid password.\n\n-- The VPN-over-DNS support team."); } else { log.info("TRACE: mobile-get-user;password checked;" + username + ";" + password + ";" + info + ";"); final Account account = generalServices.getFirstAccount(username); if (account != null && account.getProvider() != Provider.NOT_INITIALIZED) { mav.addObject("provider", account.getProvider()); mav.addObject("email", URLEncoder.encode(account.getEmail(), "UTF-8")); mav.addObject("login", URLEncoder.encode(account.getUsername(), "UTF-8")); } mav.addObject("statusCode", 0); mav.addObject("statusString", "OK"); mav.addObject("uuid", user.getUuid()); // fenyoa is used to check the service every minute, so no new mail every minute for him if (!user.getUsername().equals("fenyoa")) generalServices.sendInternalMailByAccount(account, "Welcome back at VPN-over-DNS !", "Dear customer,\n\nThis is to confirm that you have successfully logged on your VPN-over-DNS account.\n\n-- The VPN-over-DNS support team."); } } catch (final NoResultException ex) { log.info("TRACE: mobile-get-user;no such user;" + username + ";" + password + ";" + info + ";"); log.warn(ex); mav.addObject("statusCode", 2); mav.addObject("statusString", "no such user"); mav.addObject("uuid", ""); } catch (final Exception ex) { log.info("TRACE: mobile-get-user;exception;" + username + ";" + password + ";" + info + ";"); log.warn(ex); mav.addObject("statusCode", 3); mav.addObject("statusString", ex.toString()); mav.addObject("uuid", ""); } return mav; } // for manual testing only @RequestMapping(value = "/mobile-set-user", method = RequestMethod.GET) public ModelAndView mobileSetUser() { log.info("TRACE: mobile-set-user;get;"); ModelAndView mav = new ModelAndView(); mav.setViewName("mobile-form-setuser"); return mav; } // statusCode returned values: // 253: bad provider // 254: no such user // 255: other error // 0: OK // 1: invalid password @RequestMapping(value = "/mobile-set-user", method = RequestMethod.POST) public ModelAndView mobileSetUserPost(@RequestParam(value = "username", required = false) final String username, @RequestParam(value = "password", required = false) final String password, @RequestParam(value = "provider", required = false) final String provider_string, @RequestParam(value = "provider_email", required = false) final String provider_email, @RequestParam(value = "provider_login", required = false) final String provider_login, @RequestParam(value = "provider_password", required = false) final String provider_password, @RequestParam(value = "info", required = false) final String info, final ModelMap model) { log.info("TRACE: mobile-set-user;post;" + username + ";" + password + ";" + info + ";" + provider_string + ";" + provider_email + ";" + provider_login + ";" + provider_password + ";"); ModelAndView mav = new ModelAndView(); mav.setViewName("mobile-action-createuser"); try { Account.Provider provider = null; if (provider_string.equals("GMAIL")) provider = Provider.GMAIL; if (provider_string.equals("HOTMAIL")) provider = Provider.HOTMAIL; if (provider_string.equals("OPERAMAIL")) provider = Provider.OPERAMAIL; if (provider_string.equals("YAHOO")) provider = Provider.YAHOO; if (provider_string.equals("TESTIMAPLOCALHOST")) provider = Provider.TESTIMAPLOCALHOST; if (provider_string.equals("TESTIMAPRSI")) provider = Provider.TESTIMAPRSI; if (provider_string.equals("TESTPOPLOCALHOST")) provider = Provider.TESTPOPLOCALHOST; if (provider_string.equals("TESTPOPRSI")) provider = Provider.TESTPOPRSI; if (provider == null) { log.info("TRACE: mobile-set-user;bad provider;" + username + ";" + password + ";" + info + ";" + provider_string + ";" + provider_email + ";" + provider_login + ";" + provider_password + ";"); mav.addObject("statusCode", 253); mav.addObject("statusString", "bad provider"); } else { final int statusCode = generalServices.setUser(username, password, provider, provider_email, provider_login, provider_password); mav.addObject("statusCode", statusCode); switch (statusCode) { case 0: log.info("TRACE: mobile-set-user;done;" + username + ";" + password + ";" + info + ";" + provider_string + ";" + provider_email + ";" + provider_login + ";" + provider_password + ";"); mav.addObject("statusString", "OK"); break; case 1: log.info("TRACE: mobile-set-user;invalid password;" + username + ";" + password + ";" + info + ";" + provider_string + ";" + provider_email + ";" + provider_login + ";" + provider_password + ";"); mav.addObject("statusString", "invalid password"); break; default: log.info("TRACE: mobile-set-user;invalid status code;" + username + ";" + password + ";" + info + ";" + provider_string + ";" + provider_email + ";" + provider_login + ";" + provider_password + ";"); mav.addObject("statusString", "should not be there"); break; } } } catch (final NoResultException ex) { log.info("TRACE: mobile-set-user;no such user;" + username + ";" + password + ";" + info + ";" + provider_string + ";" + provider_email + ";" + provider_login + ";" + provider_password + ";"); log.warn(ex); mav.addObject("statusCode", 254); mav.addObject("statusString", "no such user"); } catch (final Exception ex) { log.info("TRACE: mobile-set-user;exception;" + username + ";" + password + ";" + info + ";" + provider_string + ";" + provider_email + ";" + provider_login + ";" + provider_password + ";"); log.warn(ex); mav.addObject("statusCode", 255); mav.addObject("statusString", ex.toString()); } return mav; } // for manual testing only @RequestMapping(value = "/mobile-drop-user", method = RequestMethod.GET) public ModelAndView mobileDropUser() { log.info("TRACE: mobile-drop-user;get;"); ModelAndView mav = new ModelAndView(); mav.setViewName("mobile-form-dropuser"); return mav; } // this form is only allowed from authorized hosts since it is not listed in the following Apache security configuration: // <ProxyMatch ^ajp://docker:8009/mail4hotspot/app/mobile-(create|get|set)-user.*$> // Order Deny,Allow // Allow from all // </ProxyMatch> @RequestMapping(value = "/mobile-drop-user", method = RequestMethod.POST) public ModelAndView mobileDropUserPost( @RequestParam(value = "username", required = false) final String username, @RequestParam(value = "password", required = false) final String password, final ModelMap model) { log.info("TRACE: mobile-drop-user;form;" + username + ";" + password + ";"); ModelAndView mav = new ModelAndView(); mav.setViewName("mobile-action-createuser"); try { final User user = generalServices.getUser(username); if (user.getPassword().equals(password) == false) { log.info("TRACE: mobile-drop-user;invalid password;" + username + ";" + password + ";"); mav.addObject("statusCode", 1); mav.addObject("statusString", "invalid password"); } else { generalServices.dropUser(username); mav.addObject("statusCode", 0); mav.addObject("statusString", "OK"); log.info("TRACE: mobile-drop-user;done;" + username + ";" + password + ";"); } } catch (final NoResultException ex) { log.info("TRACE: mobile-drop-user;no such user;" + username + ";" + password + ";"); log.warn(ex); mav.addObject("statusCode", 2); mav.addObject("statusString", "no such user"); } catch (final Exception ex) { log.info("TRACE: mobile-drop-user;exception;" + username + ";" + password + ";"); log.warn(ex); mav.addObject("statusCode", 3); mav.addObject("statusString", ex.toString()); } return mav; } @RequestMapping(value = "/navigation") public ModelAndView nav(@RequestParam(value = "url", required = false) String target_url, HttpServletRequest request) throws IOException { log.info("TRACE: navigation;get;" + target_url + ";"); @SuppressWarnings("unchecked") final Map<String, String[]> parameters = request.getParameterMap(); boolean first_param = true; if (target_url == null || target_url.isEmpty()) target_url = "http://www.bing.com/"; else if (!parameters.keySet().isEmpty()) { for (final String key : parameters.keySet()) if (!key.equals("url")) for (final String val : parameters.get(key)) { if (first_param == false) target_url += "&"; if (first_param == true) { target_url += "?"; first_param = false; } target_url += URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(val, "UTF-8"); } } log.info("TRACE: navigation;target url;" + target_url + ";"); ModelAndView mav = new ModelAndView(); mav.setViewName("navigation"); String simple_html; try { simple_html = Browser.getSimpleHtml(target_url, request.getCookies()); } catch (final IOException ex) { log.info("TRACE: navigation;exception;" + target_url + ";"); simple_html = "<BODY><center><a href='#en'>english</a> - <a href='#fr'>franais</a></center><p/><hr/>" + "<a name='en'/><table><tr><td bgcolor='#A00000'><font color='white'>An error occured while downloading the page your requested from this server</font></td></tr></table>" + "<P/><font size='-1'><b>Cause</b>: the internal browser shipped with <i>VPN-over-DNS</i> is optimized to be very efficient on low-bandwith networks. For this purpose, it may disable some features needed by this targeted web site: JavaScript, Cascading Style Sheets, Cookies or SSL/TLS (https) transport protocol support." + "<P/>" + "<b>Solution</b>: you can browse this site with your prefered full-featured browser installed on this device, simply by using one of those two <b>proxy</b> configurations:<br/>" + "<UL>" + " <LI><b>fast browsing proxy</b>" + " <UL>" + " <LI>remote host : <b>localhost</b></LI>" + " <LI>remote port : <b>8080</b></LI>" + " <LI>supported features: JavaScript, CSS & Cookies</LI>" + " </UL>" + " </LI><BR/>" + " <LI><b>full-featured browsing proxy</b>" + " <UL>" + " <LI>remote host : <b>localhost</b></LI>" + " <LI>remote port : <b>8081</b></LI>" + " <LI>supported features: pictures, SSL/TLS (https), JavaScript, CSS & Cookies</LI>" + " </UL>" + " </LI>" + "</UL>" + "<b>Note</b>: you need to let <i>VPN-over-DNS</i> running in the background while using your browser with one of those two proxy configurations, since the implementation of those proxies is made through <i>VPN-over-DNS</i>." + "<p/>Support available on www.vpnoverdns.com" + "<HR/>" + "<BODY><a name='fr'/><table><tr><td bgcolor='#A00000'><font color='white'>Une erreur s'est produite lors du tlchargement de la page</font></td></tr></table>" + "<P/><font size='-1'><b>Raison</b>: le navigateur intgr <i>VPN-over-DNS</i> est optimis pour tre particulirement efficace sur les rseaux bas dbit. Pour cela, il n'implmente pas certaines fonctions ventuellement ncessaires au site que vous avez slectionn : JavaScript, Cascading Style Sheets, Cookies ou encore le protocole de transport SSL/TLS (https)." + "<P/>" + "<b>Solution</b>: vous pouvez naviguer sur ce site web avec n'importe quel navigateur install sur ce priphrique et proposant ces fonctionnalits avances, simplement en configurant votre <b>proxy</b> suivant l'une ou l'autre de ces deux alternatives :<br/>" + "<UL>" + " <LI><b>navigation rapide</b>" + " <UL>" + " <LI>hte distant : <b>localhost</b></LI>" + " <LI>port distant : <b>8080</b></LI>" + " <LI>fonctionnalits disponibles : JavaScript, CSS & Cookies</LI>" + " </UL>" + " </LI><BR/>" + " <LI><b>navigation avec fonctions tendues</b>" + " <UL>" + " <LI>hte distant : <b>localhost</b></LI>" + " <LI>port distant : <b>8081</b></LI>" + " <LI>fonctionnalits disponibles : images, SSL/TLS (https), JavaScript, CSS & Cookies</LI>" + " </UL>" + " </LI>" + "</UL>" + "<b> noter</b> : vous devez laisser <i>VPN-over-DNS</i> fonctionner en tche de fond lors de l'utilisation de votre navigateur via l'un ou l'autre de ces proxies, ils sont en effet implments travers <i>VPN-over-DNS</i>." + "<p/>Support disponible sur www.vpnoverdns.com" + "</BODY>"; } mav.addObject("htmlContent", simple_html); log.info("TRACE: navigation;done;" + target_url + ";" + simple_html.length() + ";"); return mav; } }